OpenWalnut  1.4.0
WPropertyBase.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 WPROPERTYBASE_H
26 #define WPROPERTYBASE_H
27 
28 #include <string>
29 
30 #include <boost/function.hpp>
31 #include <boost/signals2/signal.hpp>
32 
33 #include <boost/shared_ptr.hpp>
34 #include <boost/enable_shared_from_this.hpp>
35 
36 #include "WProperties_Fwd.h"
37 #include "WCondition.h"
38 #include "WConditionSet.h"
39 
40 
41 /**
42  * Abstract base class for all properties. Simply provides name and type information.
43  */
44 class WPropertyBase: public boost::enable_shared_from_this< WPropertyBase >
45 {
46 public:
47  /**
48  * Convenience typedef for a boost::shared_ptr< WPropertyBase >
49  */
50  typedef boost::shared_ptr< WPropertyBase > SPtr;
51 
52  /**
53  * Convenience typedef for a boost::shared_ptr< const WPropertyBase >
54  */
55  typedef boost::shared_ptr< const WPropertyBase > ConstSPtr;
56 
57  /**
58  * Create an empty named property.
59  *
60  * \param name the name of the property
61  * \param description the description of the property
62  */
63  WPropertyBase( std::string name, std::string description );
64 
65  /**
66  * Copy constructor. Creates a deep copy of this property. As boost::signals2 and condition variables are non-copyable, new instances get
67  * created. The subscriptions to a signal are LOST as well as all listeners to a condition.
68  *
69  * \param from the instance to copy.
70  */
71  explicit WPropertyBase( const WPropertyBase& from );
72 
73  /**
74  * Destructor.
75  */
76  virtual ~WPropertyBase();
77 
78  /**
79  * This method clones a property and returns the clone. It does a deep copy and, in contrast to a copy constructor, creates property with the
80  * correct type without explicitly requiring the user to specify it. It creates a NEW change condition and change signal. This means, alls
81  * subscribed signal handlers are NOT copied.
82  *
83  * \note this simply ensures the copy constructor of the runtime type is issued.
84  *
85  * \return the deep clone of this property.
86  */
87  virtual boost::shared_ptr< WPropertyBase > clone() = 0;
88 
89  /**
90  * Gets the name of the class.
91  *
92  * \return the name.
93  */
94  std::string getName() const;
95 
96  /**
97  * Gets the description of the property.
98  *
99  * \return the description
100  */
101  std::string getDescription() const;
102 
103  /**
104  * Determines whether the property is hidden or not.
105  *
106  * \return true if hidden
107  */
108  bool isHidden() const;
109 
110  /**
111  * Sets the property hidden. This flag is especially used by the GUI.
112  *
113  * \param hidden true if it should be hidden.
114  */
115  void setHidden( bool hidden = true );
116 
117  /**
118  * Gets the real WPropertyVariable type of this instance.
119  *
120  * \return the real type.
121  */
122  virtual PROPERTY_TYPE getType() const;
123 
124  /**
125  * Gets the purpose of a property. See PROPERTY_PURPOSE for more details. For short: it helps the GUI and others to understand what a module
126  * (or whomever created this property) intents with this property. Typically this value is PV_PURPOSE_PARAMETER, meaning that it is used to
127  * tune the behaviour of a module.
128  *
129  * \note always assume this to be a hint. It does not actually prevent someone from writing or interpreting a parameter property as an
130  * information property.
131  *
132  * \see PROPERTY_PURPOSE
133  * \return the purpose.
134  */
135  virtual PROPERTY_PURPOSE getPurpose() const;
136 
137  /**
138  * Sets the purpose of the property. See \ref getPurpose for more details. You generally should avoid setting this value after
139  * initialization.
140  *
141  * \param purpose the purpose to set.
142  */
143  virtual void setPurpose( PROPERTY_PURPOSE purpose );
144 
145  /**
146  * This methods allows properties to be set by a string value. This is especially useful when a property is only available as string and the
147  * real type of the property is unknown. This is a shortcut for casting the property and then setting the lexically casted value.
148  *
149  * \param value the new value to set.
150  *
151  * \return true if value could be set.
152  */
153  virtual bool setAsString( std::string value ) = 0;
154 
155  /**
156  * Returns the current value as a string. This is useful for debugging or project files. It is not implemented as << operator, since the <<
157  * should also print min/max constraints and so on. This simply is the value.
158  *
159  * \return the value as a string.
160  */
161  virtual std::string getAsString() = 0;
162 
163  /**
164  * This method returns a condition which gets fired whenever the property changes somehow. It is fired when:
165  * \li \ref setHidden is called and the hidden state changes
166  * \li \ref setAsString is called and the value changes
167  * \li WPropertyVariable::set is called and the value changes (regardless of suppression during set)
168  * \li WPropertyVariable::setMin/setMax is called and the value changes
169  * \li WPropertyVariable::addConstraint is called
170  * \li WPropertyVariable::removeConstraints is called
171  * \li WProperties::addProperty is called
172  * \li WProperties::removeProperty is called
173  * \li WProperties::addPropertyGroup is called
174  * This is especially useful if you simply want to know that something has happened.
175  *
176  * \return a condition notified whenever something changes.
177  */
178  virtual boost::shared_ptr< WCondition > getUpdateCondition() const;
179 
180  /**
181  * Sets the value from the specified property to this one. This is especially useful to copy a value without explicitly casting/knowing the
182  * dynamic type of the property.
183  *
184  * \param value the new value.
185  * \param recommendedOnly if true, property types which support recommended values apply the given value as recommendation.
186  *
187  * \return true if the value has been accepted.
188  */
189  virtual bool set( boost::shared_ptr< WPropertyBase > value, bool recommendedOnly = false ) = 0;
190 
191  /////////////////////////////////////////////////////////////////////////////////////////////
192  // Helpers for easy conversion to the possible types
193  /////////////////////////////////////////////////////////////////////////////////////////////
194 
195  /**
196  * Helper converts this instance to its native type.
197  *
198  * \return the property as integer property
199  */
200  WPropInt toPropInt();
201 
202  /**
203  * Helper converts this instance to its native type.
204  *
205  * \return the property as double property
206  */
207  WPropDouble toPropDouble();
208 
209  /**
210  * Helper converts this instance to its native type.
211  *
212  * \return the property as bool property
213  */
214  WPropBool toPropBool();
215 
216  /**
217  * Helper converts this instance to its native type.
218  *
219  * \return the property as string property
220  */
221  WPropString toPropString();
222 
223  /**
224  * Helper converts this instance to its native type.
225  *
226  * \return the property as path property
227  */
228  WPropFilename toPropFilename();
229 
230  /**
231  * Helper converts this instance to its native type.
232  *
233  * \return the property as selection property
234  */
235  WPropSelection toPropSelection();
236 
237  /**
238  * Helper converts this instance to its native type.
239  *
240  * \return the property as color property
241  */
242  WPropColor toPropColor();
243 
244  /**
245  * Helper converts this instance to its native type.
246  *
247  * \return the property as position property
248  */
249  WPropPosition toPropPosition();
250 
251  /**
252  * Helper converts this instance to its native type.
253  *
254  * \return the property as trigger property
255  */
256  WPropTrigger toPropTrigger();
257 
258  /**
259  * Helper converts this instance to its native type.
260  *
261  * \return the property as matrix4x4 property
262  */
263  WPropMatrix4X4 toPropMatrix4X4();
264 
265  /**
266  * Helper converts this instance to its native type.
267  *
268  * \return the property as transfer function property
269  */
270  WPropTransferFunction toPropTransferFunction();
271 
272  /**
273  * Helper converts this instance to its native type.
274  *
275  * \return the property as group
276  */
277  WPropGroup toPropGroup();
278 
279  /**
280  * Helper converts this instance to its native type.
281  *
282  * \return the property as interval property
283  */
284  WPropInterval toPropInterval();
285 
286  /**
287  * Convert the property to a WPropertyGroupBase. This can be done with property structs and groups-
288  *
289  * \return the property as base group.
290  */
291  boost::shared_ptr< WPropertyGroupBase > toPropGroupBase();
292 
293  /**
294  * Helper converts this instance to an arbitrary type.
295  *
296  * \return the property of given type of NULL if not valid type
297  */
298  template< typename T >
299  boost::shared_ptr< WPropertyVariable< T > > toPropertyVariable();
300 
301  /**
302  * Signal signature emitted during set operations
303  */
304  typedef boost::function<void ( boost::shared_ptr< WPropertyBase > )> PropertyChangeNotifierType;
305 
306 protected:
307  /**
308  * Name of the property.
309  */
310  std::string m_name;
311 
312  /**
313  * Description of the property.
314  */
315  std::string m_description;
316 
317  /**
318  * Flag denoting whether the property is hidden or not.
319  */
320  bool m_hidden;
321 
322  /**
323  * Type of the PropertyVariable instance
324  */
325  PROPERTY_TYPE m_type;
326 
327  /**
328  * The purpose of this property. PropertyBase always initializes it with PV_PURPOSE_PARAMETER.
329  */
330  PROPERTY_PURPOSE m_purpose;
331 
332  /**
333  * Calculates the type of the property. This has to be done by the implementing class.
334  */
335  virtual void updateType();
336 
337  /**
338  * Signal used for firing change signals
339  */
340  typedef boost::signals2::signal<void ( boost::shared_ptr< WPropertyBase > )> PropertyChangeSignalType;
341 
342  /**
343  * Signal getting fired whenever the property changes.
344  */
346 
347  /**
348  * Condition notified whenever something changes. See getUpdateCondition for more details.
349  * \see getUpdateCondition
350  */
351  boost::shared_ptr< WConditionSet > m_updateCondition;
352 
353 private:
354 };
355 
356 template< typename T >
357 boost::shared_ptr< WPropertyVariable< T > > WPropertyBase::toPropertyVariable()
358 {
359  return boost::dynamic_pointer_cast< WPropertyVariable< T > >( shared_from_this() );
360 }
361 
362 #endif // WPROPERTYBASE_H
363