1
//---------------------------------------------------------------------------
3
// Project: OpenWalnut ( http://www.openwalnut.org )
5
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6
// For more information see http://www.openwalnut.org/copying
8
// This file is part of OpenWalnut.
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.
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.
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/>.
23
//---------------------------------------------------------------------------
28
#include <boost/shared_ptr.hpp>
30
#include "WCondition.h"
33
* Class to have a simple notification/condition system for simple flags. This is somewhat similar to the observer design pattern.
34
* The type of the flag is specified by the template parameter. Per default, it is of type bool.
36
template < typename T >
41
* The type for later access.
46
* Convenience typedef for a boost::shared_ptr.
48
typedef boost::shared_ptr< WFlag< T > > SPtr;
51
* Convenience typedef for a boost::shared_ptr. Const.
53
typedef boost::shared_ptr< const WFlag< T > > ConstSPtr;
56
* Constructor. Uses a given condition to realize the wait/notify functionality. By using this constructor, the specified
57
* condition gets deleted whenever this WFlag is deleted.
59
* \param condition the condition to use.
60
* \note condition can also be a WConditionOneShot.
61
* \param initial the initial value of this flag.
63
WFlag( WCondition* condition, T initial );
66
* Constructor. Uses a given condition to realize the wait/notify functionality. By using this constructor, the specified
67
* condition gets NOT explicitely deleted when this WFlag gets deleted.
69
* \param condition the condition to use.
70
* \note condition can also be a WConditionOneShot.
71
* \param initial the initial value of this flag.
73
WFlag( boost::shared_ptr< WCondition > condition, T initial );
76
* Copy constructor. Creates a deep copy of this property. As boost::signals2 and condition variables are non-copyable, new instances get
77
* created. The subscriptions to a signal are LOST as well as all listeners to a condition.
78
* The conditions you can grab using getValueChangeConditon and getCondition are not the same as in the original! This is because
79
* the class corresponds to the observer/observable pattern. You won't expect a clone to fire a condition if a original flag is changed
80
* (which after cloning is completely decoupled from the clone).
82
* \param from the instance to copy.
84
explicit WFlag( const WFlag& from );
87
* Destructor. It deletes the instance of WCondition specified on construction.
92
* Operator returns value of the flag.
94
* \param resetChangeState when true, the changed() flag gets reset to false.
98
virtual const T get( bool resetChangeState = false );
101
* Operator returns value of the flag.
105
virtual const T get() const;
108
* Operator returns value of the flag.
112
virtual const T operator()() const;
115
* Operator returns value of the flag. It does not reset the change flag.
119
virtual operator T() const;
122
* Wait for the flag to change its value. For WConditionOneShot is also recognizes if the flag has changed before.
124
virtual void wait() const;
127
* Sets the new value for this flag. Also notifies waiting threads. After setting a value, changed() will be true.
129
* \param value the new value
130
* \param suppressNotification true to avoid a firing condition. This is useful for resetting values.
132
* \return true if the value has been set successfully.
134
* \note set( get() ) == true
136
virtual bool set( T value, bool suppressNotification = false );
139
* Sets the new value for this flag. Also notifies waiting threads.
141
* \param value the new value
143
virtual void operator()( T value );
146
* Returns the condition that is used by this flag.
148
* \return the condition
150
boost::shared_ptr< WCondition > getCondition();
153
* Returns the condition denoting a value change. In contrast to getCondition, this condition fires regardless of notification is suppressed
154
* during set() or not.
156
* \return the condition denoting a value change.
158
boost::shared_ptr< WCondition > getValueChangeCondition();
161
* Determines whether the specified value is acceptable. In WFlags, this always returns true. To modify the behaviour,
162
* implement this function in an appropriate way.
164
* \param newValue the new value.
166
* \return true if it is a valid/acceptable value.
168
virtual bool accept( T newValue );
171
* Tests whether a flag is currently valid. It is equal to accept( get() );
173
* \return true if current value is valid.
175
virtual bool isValid();
178
* True whenever the value inside this flag has changed since the last reset. It stays true until get( true ) is called or the reset value is
181
* \param reset if true, the change flag gets reset.
183
* \return true when the value has changed and not yet been reseted.
185
virtual bool changed( bool reset = false );
190
* The condition to be used for waiting/notifying. Please note, that it gets deleted during destruction.
192
boost::shared_ptr< WCondition > m_condition;
195
* This condition is fired whenever the value changes. In contrast to m_condition, this also fires if set() is called with
196
* suppressNotification=true.
198
boost::shared_ptr< WCondition > m_valueChangeCondition;
206
* Denotes whether the value has changed since the last reset.
214
* Alias for easy usage of WFLag< bool >.
216
typedef WFlag< bool > WBoolFlag;
218
template < typename T >
219
WFlag< T >::WFlag( WCondition* condition, T initial ):
220
m_condition( boost::shared_ptr< WCondition >( condition ) ),
221
m_valueChangeCondition( boost::shared_ptr< WCondition >( new WCondition() ) ),
227
template < typename T >
228
WFlag< T >::WFlag( boost::shared_ptr< WCondition > condition, T initial ):
229
m_condition( condition ),
230
m_valueChangeCondition( boost::shared_ptr< WCondition >( new WCondition() ) ),
236
template < typename T >
237
WFlag< T >::WFlag( const WFlag& from ):
238
m_condition( boost::shared_ptr< WCondition >( new WCondition() ) ),
239
m_valueChangeCondition( boost::shared_ptr< WCondition >( new WCondition() ) ),
240
m_flag( from.m_flag ),
241
m_changed( from.m_changed )
245
template < typename T >
250
template < typename T >
251
const T WFlag< T >::operator()() const
256
template < typename T >
257
const T WFlag< T >::get( bool resetChangeState )
259
if( resetChangeState )
266
template < typename T >
267
const T WFlag< T >::get() const
272
template < typename T >
273
WFlag< T >::operator T() const
278
template < typename T >
279
void WFlag< T >::wait() const
284
template < typename T >
285
void WFlag< T >::operator()( T value )
290
template < typename T >
291
bool WFlag< T >::set( T value, bool suppressNotification )
293
// if the value is the same as the current one -> do not notify but let the caller know "all ok"
294
if( m_flag == value )
299
// let the caller know whether the value was acceptable.
300
if( !accept( value ) )
308
// is the notification suppressed ?
309
if( !suppressNotification )
311
m_condition->notify();
313
m_valueChangeCondition->notify();
318
template < typename T >
319
boost::shared_ptr< WCondition > WFlag< T >::getCondition()
324
template < typename T >
325
boost::shared_ptr< WCondition > WFlag< T >::getValueChangeCondition()
327
return m_valueChangeCondition;
330
template < typename T >
331
bool WFlag< T >::accept( T /* newValue */ )
333
// please implement this method in your class to modify the behaviour.
337
template < typename T >
338
bool WFlag< T >::isValid()
340
return accept( get() );
343
template < typename T >
344
bool WFlag< T >::changed( bool reset )
346
bool tmp = m_changed;