~ubuntu-branches/ubuntu/precise/openwalnut/precise

« back to all changes in this revision

Viewing changes to src/core/common/WFlag.h

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Eichelbaum
  • Date: 2011-06-21 10:26:54 UTC
  • Revision ID: james.westby@ubuntu.com-20110621102654-rq0zf436q949biih
Tags: upstream-1.2.5
ImportĀ upstreamĀ versionĀ 1.2.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <boost/shared_ptr.hpp>
 
29
 
 
30
#include "WCondition.h"
 
31
 
 
32
/**
 
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.
 
35
 */
 
36
template < typename T >
 
37
class WFlag
 
38
{
 
39
public:
 
40
    /**
 
41
     * The type for later access.
 
42
     */
 
43
    typedef T ValueType;
 
44
 
 
45
    /**
 
46
     * Convenience typedef for a boost::shared_ptr.
 
47
     */
 
48
    typedef boost::shared_ptr< WFlag< T > > SPtr;
 
49
 
 
50
    /**
 
51
     * Convenience typedef for a boost::shared_ptr. Const.
 
52
     */
 
53
    typedef boost::shared_ptr< const WFlag< T > > ConstSPtr;
 
54
 
 
55
    /**
 
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.
 
58
     *
 
59
     * \param condition the condition to use.
 
60
     * \note condition can also be a WConditionOneShot.
 
61
     * \param initial the initial value of this flag.
 
62
     */
 
63
    WFlag( WCondition* condition, T initial );
 
64
 
 
65
    /**
 
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.
 
68
     *
 
69
     * \param condition the condition to use.
 
70
     * \note condition can also be a WConditionOneShot.
 
71
     * \param initial the initial value of this flag.
 
72
     */
 
73
    WFlag( boost::shared_ptr< WCondition > condition, T initial );
 
74
 
 
75
    /**
 
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).
 
81
     *
 
82
     * \param from the instance to copy.
 
83
     */
 
84
    explicit WFlag( const WFlag& from );
 
85
 
 
86
    /**
 
87
     * Destructor. It deletes the instance of WCondition specified on construction.
 
88
     */
 
89
    virtual ~WFlag();
 
90
 
 
91
    /**
 
92
     * Operator returns value of the flag.
 
93
     *
 
94
     * \param resetChangeState when true, the changed() flag gets reset to false.
 
95
     *
 
96
     * \return the value.
 
97
     */
 
98
    virtual const T get( bool resetChangeState = false );
 
99
 
 
100
    /**
 
101
     * Operator returns value of the flag.
 
102
     *
 
103
     * \return the value.
 
104
     */
 
105
    virtual const T get() const;
 
106
 
 
107
    /**
 
108
     * Operator returns value of the flag.
 
109
     *
 
110
     * \return the value.
 
111
     */
 
112
    virtual const T operator()() const;
 
113
 
 
114
    /**
 
115
     * Operator returns value of the flag. It does not reset the change flag.
 
116
     *
 
117
     * \return the value.
 
118
     */
 
119
    virtual operator T() const;
 
120
 
 
121
    /**
 
122
     * Wait for the flag to change its value. For WConditionOneShot is also recognizes if the flag has changed before.
 
123
     */
 
124
    virtual void wait() const;
 
125
 
 
126
    /**
 
127
     * Sets the new value for this flag. Also notifies waiting threads. After setting a value, changed() will be true.
 
128
     *
 
129
     * \param value the new value
 
130
     * \param suppressNotification true to avoid a firing condition. This is useful for resetting values.
 
131
     *
 
132
     * \return true if the value has been set successfully.
 
133
     *
 
134
     * \note set( get() ) == true
 
135
     */
 
136
    virtual bool set( T value, bool suppressNotification = false );
 
137
 
 
138
    /**
 
139
     * Sets the new value for this flag. Also notifies waiting threads.
 
140
     *
 
141
     * \param value the new value
 
142
     */
 
143
    virtual void operator()( T value );
 
144
 
 
145
    /**
 
146
     * Returns the condition that is used by this flag.
 
147
     *
 
148
     * \return the condition
 
149
     */
 
150
    boost::shared_ptr< WCondition > getCondition();
 
151
 
 
152
    /**
 
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.
 
155
     *
 
156
     * \return the condition denoting a value change.
 
157
     */
 
158
    boost::shared_ptr< WCondition > getValueChangeCondition();
 
159
 
 
160
    /**
 
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.
 
163
     *
 
164
     * \param newValue the new value.
 
165
     *
 
166
     * \return true if it is a valid/acceptable value.
 
167
     */
 
168
    virtual bool accept( T newValue );
 
169
 
 
170
    /**
 
171
     * Tests whether a flag is currently valid. It is equal to accept( get() );
 
172
     *
 
173
     * \return true if current value is valid.
 
174
     */
 
175
    virtual bool isValid();
 
176
 
 
177
    /**
 
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
 
179
     * true.
 
180
     *
 
181
     * \param reset if true, the change flag gets reset.
 
182
     *
 
183
     * \return true when the value has changed and not yet been reseted.
 
184
     */
 
185
    virtual bool changed( bool reset = false );
 
186
 
 
187
protected:
 
188
 
 
189
    /**
 
190
     * The condition to be used for waiting/notifying. Please note, that it gets deleted during destruction.
 
191
     */
 
192
    boost::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
    boost::shared_ptr< WCondition > m_valueChangeCondition;
 
199
 
 
200
    /**
 
201
     * The flag value.
 
202
     */
 
203
    T m_flag;
 
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, T initial ):
 
220
    m_condition( boost::shared_ptr< WCondition >( condition ) ),
 
221
    m_valueChangeCondition( boost::shared_ptr< WCondition >( new WCondition() ) ),
 
222
    m_flag( initial ),
 
223
    m_changed( true )
 
224
{
 
225
}
 
226
 
 
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() ) ),
 
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( 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 )
 
242
{
 
243
}
 
244
 
 
245
template < typename T >
 
246
WFlag< T >::~WFlag()
 
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 >
 
273
WFlag< T >::operator T() const
 
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()( T value )
 
286
{
 
287
    set( value );
 
288
}
 
289
 
 
290
template < typename T >
 
291
bool WFlag< T >::set( 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
boost::shared_ptr< WCondition > WFlag< T >::getCondition()
 
320
{
 
321
    return m_condition;
 
322
}
 
323
 
 
324
template < typename T >
 
325
boost::shared_ptr< WCondition > WFlag< T >::getValueChangeCondition()
 
326
{
 
327
    return m_valueChangeCondition;
 
328
}
 
329
 
 
330
template < typename T >
 
331
bool WFlag< T >::accept( T /* newValue */ )
 
332
{
 
333
    // please implement this method in your class to modify the behaviour.
 
334
    return true;
 
335
}
 
336
 
 
337
template < typename T >
 
338
bool WFlag< T >::isValid()
 
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