OpenWalnut  1.5.0dev
WFlag.h
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 #ifndef WFLAG_H
26 #define WFLAG_H
27 
28 #include <memory>
29 
30 
31 #include "WCondition.h"
32 
33 /**
34  * Class to have a simple notification/condition system for simple flags. This is somewhat similar to the observer design pattern.
35  * The type of the flag is specified by the template parameter. Per default, it is of type bool.
36  */
37 template < typename T >
38 class WFlag
39 {
40 public:
41  /**
42  * The type for later access.
43  */
44  typedef T ValueType;
45 
46  /**
47  * Convenience typedef for a std::shared_ptr.
48  */
49  typedef std::shared_ptr< WFlag< T > > SPtr;
50 
51  /**
52  * Convenience typedef for a std::shared_ptr. Const.
53  */
54  typedef std::shared_ptr< const WFlag< T > > ConstSPtr;
55 
56  /**
57  * Constructor. Uses a given condition to realize the wait/notify functionality. By using this constructor, the specified
58  * condition gets deleted whenever this WFlag is deleted.
59  *
60  * \param condition the condition to use.
61  * \note condition can also be a WConditionOneShot.
62  * \param initial the initial value of this flag.
63  */
64  WFlag( WCondition* condition, const T& initial );
65 
66  /**
67  * Constructor. Uses a given condition to realize the wait/notify functionality. By using this constructor, the specified
68  * condition gets NOT explicitely deleted when this WFlag gets deleted.
69  *
70  * \param condition the condition to use.
71  * \note condition can also be a WConditionOneShot.
72  * \param initial the initial value of this flag.
73  */
74  WFlag( std::shared_ptr< WCondition > condition, const T& initial );
75 
76  /**
77  * Copy constructor. Creates a deep copy of this property. As boost::signals2 and condition variables are non-copyable, new instances get
78  * created. The subscriptions to a signal are LOST as well as all listeners to a condition.
79  * The conditions you can grab using getValueChangeConditon and getCondition are not the same as in the original! This is because
80  * the class corresponds to the observer/observable pattern. You won't expect a clone to fire a condition if a original flag is changed
81  * (which after cloning is completely decoupled from the clone).
82  *
83  * \param from the instance to copy.
84  */
85  explicit WFlag( const WFlag& from );
86 
87  /**
88  * Destructor. It deletes the instance of WCondition specified on construction.
89  */
90  virtual ~WFlag();
91 
92  /**
93  * Operator returns value of the flag.
94  *
95  * \param resetChangeState when true, the changed() flag gets reset to false.
96  *
97  * \return the value.
98  */
99  virtual const T& get( bool resetChangeState = false );
100 
101  /**
102  * Operator returns value of the flag.
103  *
104  * \return the value.
105  */
106  virtual const T& get() const;
107 
108  /**
109  * Operator returns value of the flag.
110  *
111  * \return the value.
112  */
113  virtual const T& operator()() const;
114 
115  /**
116  * Operator returns value of the flag. It does not reset the change flag.
117  *
118  * \return the value.
119  */
120  virtual operator T() const;
121 
122  /**
123  * Wait for the flag to change its value. For WConditionOneShot is also recognizes if the flag has changed before.
124  */
125  virtual void wait() const;
126 
127  /**
128  * Sets the new value for this flag. Also notifies waiting threads. After setting a value, changed() will be true.
129  *
130  * \param value the new value
131  * \param suppressNotification true to avoid a firing condition. This is useful for resetting values.
132  *
133  * \return true if the value has been set successfully.
134  *
135  * \note set( get() ) == true
136  */
137  virtual bool set( const T& value, bool suppressNotification = false );
138 
139  /**
140  * Sets the new value for this flag. Also notifies waiting threads.
141  *
142  * \param value the new value
143  */
144  virtual void operator()( const T& value );
145 
146  /**
147  * Returns the condition that is used by this flag.
148  *
149  * \return the condition
150  */
151  std::shared_ptr< WCondition > getCondition();
152 
153  /**
154  * Returns the condition denoting a value change. In contrast to getCondition, this condition fires regardless of notification is suppressed
155  * during set() or not.
156  *
157  * \return the condition denoting a value change.
158  */
159  std::shared_ptr< WCondition > getValueChangeCondition();
160 
161  /**
162  * Determines whether the specified value is acceptable. In WFlags, this always returns true. To modify the behaviour,
163  * implement this function in an appropriate way.
164  *
165  * \param newValue the new value.
166  *
167  * \return true if it is a valid/acceptable value.
168  */
169  virtual bool accept( const T& newValue );
170 
171  /**
172  * Tests whether a flag is currently valid. It is equal to accept( get() );
173  *
174  * \return true if current value is valid.
175  */
176  virtual bool isValid();
177 
178  /**
179  * 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
180  * true.
181  *
182  * \param reset if true, the change flag gets reset.
183  *
184  * \return true when the value has changed and not yet been reseted.
185  */
186  virtual bool changed( bool reset = false );
187 
188 protected:
189  /**
190  * The condition to be used for waiting/notifying. Please note, that it gets deleted during destruction.
191  */
192  std::shared_ptr< WCondition > m_condition;
193 
194  /**
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.
197  */
198  std::shared_ptr< WCondition > m_valueChangeCondition;
199 
200  /**
201  * The flag value.
202  */
204 
205  /**
206  * Denotes whether the value has changed since the last reset.
207  */
208  bool m_changed;
209 
210 private:
211 };
212 
213 /**
214  * Alias for easy usage of WFLag< bool >.
215  */
216 typedef WFlag< bool > WBoolFlag;
217 
218 template < typename T >
219 WFlag< T >::WFlag( WCondition* condition, const T& initial ):
220  m_condition( std::shared_ptr< WCondition >( condition ) ),
221  m_valueChangeCondition( std::shared_ptr< WCondition >( new WCondition() ) ),
222  m_flag( initial ),
223  m_changed( true )
224 {
225 }
226 
227 template < typename T >
228 WFlag< T >::WFlag( std::shared_ptr< WCondition > condition, const T& initial ):
229  m_condition( condition ),
230  m_valueChangeCondition( std::shared_ptr< WCondition >( new WCondition() ) ),
231  m_flag( initial ),
232  m_changed( true )
233 {
234 }
235 
236 template < typename T >
237 WFlag< T >::WFlag( const WFlag& from ):
238  m_condition( std::shared_ptr< WCondition >( new WCondition() ) ),
239  m_valueChangeCondition( std::shared_ptr< WCondition >( new WCondition() ) ),
240  m_flag( from.m_flag ),
241  m_changed( from.m_changed )
242 {
243 }
244 
245 template < typename T >
247 {
248 }
249 
250 template < typename T >
251 const T& WFlag< T >::operator()() const
252 {
253  return get();
254 }
255 
256 template < typename T >
257 const T& WFlag< T >::get( bool resetChangeState )
258 {
259  if( resetChangeState )
260  {
261  m_changed = false;
262  }
263  return m_flag;
264 }
265 
266 template < typename T >
267 const T& WFlag< T >::get() const
268 {
269  return m_flag;
270 }
271 
272 template < typename T >
274 {
275  return get();
276 }
277 
278 template < typename T >
279 void WFlag< T >::wait() const
280 {
281  m_condition->wait();
282 }
283 
284 template < typename T >
285 void WFlag< T >::operator()( const T& value )
286 {
287  set( value );
288 }
289 
290 template < typename T >
291 bool WFlag< T >::set( const T& value, bool suppressNotification )
292 {
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 )
295  {
296  return true;
297  }
298 
299  // let the caller know whether the value was acceptable.
300  if( !accept( value ) )
301  {
302  return false;
303  }
304 
305  m_flag = value;
306  m_changed = true;
307 
308  // is the notification suppressed ?
309  if( !suppressNotification )
310  {
311  m_condition->notify();
312  }
313  m_valueChangeCondition->notify();
314 
315  return true;
316 }
317 
318 template < typename T >
319 std::shared_ptr< WCondition > WFlag< T >::getCondition()
320 {
321  return m_condition;
322 }
323 
324 template < typename T >
325 std::shared_ptr< WCondition > WFlag< T >::getValueChangeCondition()
326 {
327  return m_valueChangeCondition;
328 }
329 
330 template < typename T >
331 bool WFlag< T >::accept( const T& /* newValue */ )
332 {
333  // please implement this method in your class to modify the behaviour.
334  return true;
335 }
336 
337 template < typename T >
339 {
340  return accept( get() );
341 }
342 
343 template < typename T >
344 bool WFlag< T >::changed( bool reset )
345 {
346  bool tmp = m_changed;
347  if( reset )
348  {
349  m_changed = false;
350  }
351  return tmp;
352 }
353 
354 #endif // WFLAG_H
355 
Class to encapsulate boost::condition_variable_any.
Definition: WCondition.h:42
Class to have a simple notification/condition system for simple flags.
Definition: WFlag.h:39
virtual const T & get() const
Operator returns value of the flag.
Definition: WFlag.h:267
virtual void wait() const
Wait for the flag to change its value.
Definition: WFlag.h:279
WFlag(std::shared_ptr< WCondition > condition, const T &initial)
Constructor.
Definition: WFlag.h:228
virtual bool accept(const T &newValue)
Determines whether the specified value is acceptable.
Definition: WFlag.h:331
T ValueType
The type for later access.
Definition: WFlag.h:44
std::shared_ptr< const WFlag< T > > ConstSPtr
Convenience typedef for a std::shared_ptr.
Definition: WFlag.h:54
std::shared_ptr< WCondition > getCondition()
Returns the condition that is used by this flag.
Definition: WFlag.h:319
T m_flag
The flag value.
Definition: WFlag.h:203
virtual bool changed(bool reset=false)
True whenever the value inside this flag has changed since the last reset.
Definition: WFlag.h:344
virtual const T & get(bool resetChangeState=false)
Operator returns value of the flag.
Definition: WFlag.h:257
std::shared_ptr< WFlag< T > > SPtr
Convenience typedef for a std::shared_ptr.
Definition: WFlag.h:49
std::shared_ptr< WCondition > getValueChangeCondition()
Returns the condition denoting a value change.
Definition: WFlag.h:325
virtual void operator()(const T &value)
Sets the new value for this flag.
Definition: WFlag.h:285
std::shared_ptr< WCondition > m_condition
The condition to be used for waiting/notifying.
Definition: WFlag.h:192
std::shared_ptr< WCondition > m_valueChangeCondition
This condition is fired whenever the value changes.
Definition: WFlag.h:198
virtual bool set(const T &value, bool suppressNotification=false)
Sets the new value for this flag.
Definition: WFlag.h:291
WFlag(const WFlag &from)
Copy constructor.
Definition: WFlag.h:237
virtual const T & operator()() const
Operator returns value of the flag.
Definition: WFlag.h:251
WFlag(WCondition *condition, const T &initial)
Constructor.
Definition: WFlag.h:219
virtual bool isValid()
Tests whether a flag is currently valid.
Definition: WFlag.h:338
virtual ~WFlag()
Destructor.
Definition: WFlag.h:246
bool m_changed
Denotes whether the value has changed since the last reset.
Definition: WFlag.h:208