OpenWalnut
1.4.0
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
src
core
common
WPropertyObserver.cpp
1
//---------------------------------------------------------------------------
2
//
3
// Project: OpenWalnut ( http://www.openwalnut.org )
4
//
5
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6
// For more information see http://www.openwalnut.org/copying
7
//
8
// This file is part of OpenWalnut.
9
//
10
// OpenWalnut is free software: you can redistribute it and/or modify
11
// it under the terms of the GNU Lesser General Public License as published by
12
// the Free Software Foundation, either version 3 of the License, or
13
// (at your option) any later version.
14
//
15
// OpenWalnut is distributed in the hope that it will be useful,
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
// GNU Lesser General Public License for more details.
19
//
20
// You should have received a copy of the GNU Lesser General Public License
21
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22
//
23
//---------------------------------------------------------------------------
24
25
#include <map>
26
#include <set>
27
#include <string>
28
29
#include "WPropertyObserver.h"
30
31
WPropertyObserver::WPropertyObserver
():
32
WCondition
(),
33
m_subscriptions(),
34
m_updated( false ),
35
m_properties(),
36
m_propNames(),
37
m_updateConditionConnection()
38
{
39
// initialize members
40
}
41
42
WPropertyObserver::~WPropertyObserver
()
43
{
44
// cleanup
45
}
46
47
bool
WPropertyObserver::updated
()
const
48
{
49
return
m_updated
;
50
}
51
52
WPropertyObserver::PropertyNameMap
WPropertyObserver::handled
()
53
{
54
LastUpdated::WriteTicket
l =
m_lastUpdated
.
getWriteTicket
();
55
56
// reset everything
57
m_updated
=
false
;
58
59
// return a copy of the list
60
PropertyNameMap
ret( l->get() );
61
l->get().clear();
62
63
return
ret;
64
}
65
66
void
WPropertyObserver::observe
( boost::shared_ptr< WProperties > properties, std::set< std::string > names )
67
{
68
// something to do?
69
if
(
m_properties
== properties )
70
{
71
return
;
72
}
73
74
// remove old subscriptions to the old properties
75
m_updateConditionConnection
.disconnect();
76
cancelSubscriptions
();
77
m_updated
=
false
;
78
LastUpdated::WriteTicket
l =
m_lastUpdated
.
getWriteTicket
();
79
l->get().clear();
80
81
m_propNames
= names;
82
83
// set new properties and subscribe to all signals
84
m_properties
= properties;
85
// we need to get a call if properties get added or removed
86
m_updateConditionConnection
=
m_properties
->getUpdateCondition()->subscribeSignal(
87
boost::bind( &
WPropertyObserver::updateSubscriptions
,
this
)
88
);
89
90
// and subscribe again to the new group's properties
91
// NOTE: it may be possible that the updateSubscriptions method was called already by the above callback. But thats not that evil.
92
updateSubscriptions
();
93
}
94
95
void
WPropertyObserver::cancelSubscriptions
()
96
{
97
// NOTE: locking is handled by WSharedAssociativeContainer
98
99
// unfortunately, scoped_connections can't be used for the container as it requires copy construction which is not allowed by
100
// scoped_connections. So we need to iterate by hand and disconnect
101
102
Subscriptions::WriteTicket
subs =
m_subscriptions
.
getWriteTicket
();
103
for
(
Subscriptions::Iterator
i = subs->get().begin(); i != subs->get().end(); ++i )
104
{
105
( *i ).second.disconnect();
106
}
107
subs->get().clear();
108
}
109
110
void
WPropertyObserver::updateSubscriptions
()
111
{
112
// lock m_subscriptions
113
Subscriptions::WriteTicket
subs =
m_subscriptions
.
getWriteTicket
();
114
115
// iterate the properties
116
WProperties::PropertySharedContainerType::ReadTicket
props =
m_properties
->getReadTicket();
117
for
(
WProperties::PropertyConstIterator
i = props->get().begin(); i != props->get().end(); ++i )
118
{
119
// should the property be handled? (empty container ensures handling of all props)
120
if
( !
m_propNames
.size() || (
m_propNames
.find( ( *i )->getName() ) !=
m_propNames
.end() ) )
121
{
122
// subscribe to each update signal of the properties
123
subs->get().insert( std::make_pair( *i,
124
( *i )->getUpdateCondition()->subscribeSignal( boost::bind( boost::mem_fn( &
WPropertyObserver::propertyUpdated
),
this
, *i ) )
125
) );
126
}
127
}
128
}
129
130
void
WPropertyObserver::propertyUpdated
( boost::shared_ptr< WPropertyBase > property )
131
{
132
// lock m_lastUpdated
133
LastUpdated::WriteTicket
l =
m_lastUpdated
.
getWriteTicket
();
134
m_updated
=
true
;
135
l->get().insert( std::make_pair( property->getName(), property ) );
136
notify
();
137
}
138
139
boost::shared_ptr< WPropertyObserver >
WPropertyObserver::create
()
140
{
141
return
boost::shared_ptr< WPropertyObserver >(
new
WPropertyObserver
() );
142
}
143
Generated by
1.8.3.1