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