OpenWalnut  1.4.0
WPropertyGroupBase.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 WPROPERTYGROUPBASE_H
26 #define WPROPERTYGROUPBASE_H
27 
28 #include <map>
29 #include <string>
30 #include <vector>
31 
32 #ifndef Q_MOC_RUN
33 #include <boost/thread/thread.hpp>
34 #endif
35 #ifndef Q_MOC_RUN
36 #include <boost/thread/mutex.hpp>
37 #endif
38 #ifndef Q_MOC_RUN
39 #include <boost/thread/locks.hpp>
40 #endif
41 #ifndef Q_MOC_RUN
42 #include <boost/thread.hpp>
43 #endif
44 
45 #include "WConditionSet.h"
46 #include "WPropertyBase.h"
47 #include "WPropertyTypes.h"
48 #include "WPropertyVariable.h"
49 #include "WSharedSequenceContainer.h"
50 
51 /**
52  * This is the base class and interface for property groups. This class itself is abstract and derived from WPropertyBase. So if you create a
53  * group of properties, this ensures that your group is a property itself. This interface defines no way to add, remove or edit the property list
54  * itself. This allows the deriving class to prohibit modifications and to provide a custom interface, or even model-controller like
55  * implementations.
56  *
57  * Another advantage is, that the GUI implementations which support WPropertyGroupBase can display your custom properties directly.
58  */
60 {
61 public:
62  /**
63  * For shortening: a type defining a shared vector of WSubject pointers.
64  */
65  typedef std::vector< boost::shared_ptr< WPropertyBase > > PropertyContainerType;
66 
67  /**
68  * The alias for a shared container.
69  */
71 
72  /**
73  * The const iterator type of the container.
74  */
75  typedef PropertyContainerType::const_iterator PropertyConstIterator;
76 
77  /**
78  * The iterator type of the container.
79  */
80  typedef PropertyContainerType::iterator PropertyIterator;
81 
82  /**
83  * Convenience typedef for a boost::shared_ptr< WPropertyGroupBase >.
84  */
85  typedef boost::shared_ptr< WPropertyGroupBase > SPtr;
86 
87  /**
88  * Convenience typedef for a boost::shared_ptr< const WPropertyGroupBase >.
89  */
90  typedef boost::shared_ptr< const WPropertyGroupBase > ConstSPtr;
91 
92  /**
93  * The separator used to separate groups and subgroups
94  */
95  static const std::string separator;
96 
97  ///////////////////////////////////////////////////////////////////////////////////////////////////
98  // Construction
99  ///////////////////////////////////////////////////////////////////////////////////////////////////
100 
101  /**
102  * Constructor. Creates an empty list of properties.
103  *
104  * \param name the name of the property group. The GUI is using this name for naming the tabs/group boxes
105  * \param description the description of the group.
106  */
107  WPropertyGroupBase( std::string name, std::string description );
108 
109  /**
110  * Copy constructor. Creates a deep copy of this property. As boost::signals2 and condition variables are non-copyable, new instances get
111  * created. The subscriptions to a signal are LOST as well as all listeners to a condition.
112  * The conditions you can grab using getValueChangeConditon and getCondition are not the same as in the original! This is because
113  * the class corresponds to the observer/observable pattern. You won't expect a clone to fire a condition if a original flag is changed
114  * (which after cloning is completely decoupled from the clone).
115  *
116  * \note the properties inside this list are also copied deep
117  *
118  * \param from the instance to copy.
119  */
120  explicit WPropertyGroupBase( const WPropertyGroupBase& from );
121 
122  /**
123  * Destructor.
124  */
125  virtual ~WPropertyGroupBase();
126 
127  ///////////////////////////////////////////////////////////////////////////////////////////////////
128  // The WPropertyGroupBase interface
129  ///////////////////////////////////////////////////////////////////////////////////////////////////
130 
131  /**
132  * Helper function that finds a property by its name. Use this method to find out whether the property exists or not, since
133  * findProperty throws an exception.
134  *
135  * \param name name of searched property.
136  *
137  * \return Answer to the question whether the property exists.
138  */
139  virtual bool existsProperty( std::string name );
140 
141  /**
142  * Function searches the property. If it does not exists, it throws an exception.
143  *
144  * \param name the name of the property
145  *
146  * \return a WProperty object
147  */
148  virtual boost::shared_ptr< WPropertyBase > getProperty( std::string name );
149 
150  /**
151  * Returns a read ticket for read-access to the list of properties.
152  *
153  * \return the read ticket.
154  */
156 
157  /**
158  * Returns an read ticket for the properties. This, and only this, has to be used for external iteration of properties.
159  *
160  * \see WSharedObjectTicketRead
161  * \return the read ticket.
162  */
164 
165  /**
166  * Searches the property with a given name. It does not throw any exception. It simply returns NULL if it can't be found. It searches
167  * in nested groups too. The naming rules for finding a property in subgroups of this group is like specifying a path, using the \ref
168  * separator char: "somegroup" + separator + "anothergroup" + separator + "propnametosearch".
169  *
170  * \param name the name of the property to search
171  *
172  * \return the property or NULL if not found.
173  */
174  virtual boost::shared_ptr< WPropertyBase > findProperty( std::string name ) const;
175 
176  /**
177  * The visitor type used to visit properties as strings. The first parameter is the name, including the path of the property, relative to
178  * this group. The second parameter is the value as string.
179  */
180  typedef boost::function< void ( std::string, std::string )> PropertyStringVisitor;
181 
182  /**
183  * Visit all leafs in the property three that aren't empty groups. This is especially interesting when using it with lambda functionality.
184  * The visitor function gets two parameters: 1st: the name of the property, including the path beginning at this group; 2nd: the value as
185  * string.
186  *
187  * \param visitor the function to use for each property.
188  * \param pathPrefix add this prefix to the property name in the visitor. It might be interesting if manually implementing group visitors
189  * that always require a complete path, so you can add an upper-level path here.
190  */
191  virtual void visitAsString( PropertyStringVisitor visitor, std::string pathPrefix = "" ) const;
192 
193 protected:
194  /**
195  * Helping function to find a property inside a specific group. It does not recursively find properties nested inside other property groups.
196  *
197  * \param props the group to search in. This is not a shared pointer since it is not needed. It simply can't happen that it is freed during
198  * findProperty as it is contained in this or a nested properties instance.
199  * \param name the name of the property inside THIS group.
200  *
201  * \return the property if found, else NULL.
202  */
203  virtual boost::shared_ptr< WPropertyBase > findProperty( const WPropertyGroupBase* const props, std::string name ) const;
204 
205  /**
206  * The set of proerties. This uses the operators ==,<,> WProperty to determine equalness.
207  */
208  PropertySharedContainerType m_properties;
209 
210  /**
211  * Compares the names of two properties and returns true if they are equal.
212  *
213  * \param prop1 the first prop.
214  * \param prop2 the second prop.
215  *
216  * \return Are the names of the two properties equal?
217  */
218  bool propNamePredicate( boost::shared_ptr< WPropertyBase > prop1, boost::shared_ptr< WPropertyBase > prop2 ) const;
219 
220  /**
221  * Insert the specified property into the list. This method is protected. It is a convenience method for deriving classes to add properties
222  * without the need to update several conditions and similar.
223  *
224  * \param prop the property to add
225  */
227 
228  /**
229  * Comfortable template to create a property instance and add it to the group. This is a utility for deriving classes which need to handle
230  * certain property types and other types during compile time.
231  *
232  * At the first glance, this might not look very useful. But this
233  * is practical to change the add-behaviour for certain property types by specializing this class. For example, the template \ref
234  * WPropertyStruct uses this to modify the behaviour for the non-property type \ref WPropertyStructHelper::NOTYPE, which is used as
235  * template list default (to emulate variadic template parameters lists).
236  *
237  * \tparam PropertyType the property type to create. It is assumed that this is a shared_ptr< WPropertyXYZ >.
238  */
239  template< typename PropertyType >
241  {
242  /**
243  * The type of the initial value.
244  */
245  typedef typename PropertyType::element_type::ValueType ValueType;
246 
247  /**
248  * Actually does the work and adds a new property with the given name, description and other parameters to the specified group.
249  *
250  * \param group the group to add the new property to
251  * \param name the name of the new property
252  * \param description the description of the new property
253  * \param initial initial value
254  */
255  static void createAndAdd( WPropertyGroupBase* group, std::string name, std::string description, const ValueType& initial = ValueType() )
256  {
257  group->addArbitraryProperty(
258  PropertyType(
259  new typename PropertyType::element_type( name, description, initial )
260  )
261  );
262  }
263  };
264 
265 private:
266 };
267 
268 #endif // WPROPERTYGROUPBASE_H
269 
boost::shared_ptr< const WPropertyGroupBase > ConstSPtr
Convenience typedef for a boost::shared_ptr< const WPropertyGroupBase >.
bool propNamePredicate(boost::shared_ptr< WPropertyBase > prop1, boost::shared_ptr< WPropertyBase > prop2) const
Compares the names of two properties and returns true if they are equal.
WSharedSequenceContainer< PropertyContainerType > PropertySharedContainerType
The alias for a shared container.
std::vector< boost::shared_ptr< WPropertyBase > > PropertyContainerType
For shortening: a type defining a shared vector of WSubject pointers.
PropertyContainerType::iterator PropertyIterator
The iterator type of the container.
static void createAndAdd(WPropertyGroupBase *group, std::string name, std::string description, const ValueType &initial=ValueType())
Actually does the work and adds a new property with the given name, description and other parameters ...
boost::shared_ptr< WPropertyGroupBase > SPtr
Convenience typedef for a boost::shared_ptr< WPropertyGroupBase >.
boost::function< void(std::string, std::string)> PropertyStringVisitor
The visitor type used to visit properties as strings.
virtual void visitAsString(PropertyStringVisitor visitor, std::string pathPrefix="") const
Visit all leafs in the property three that aren't empty groups.
PropertySharedContainerType m_properties
The set of proerties.
void addArbitraryProperty(WPropertyBase::SPtr prop)
Insert the specified property into the list.
virtual PropertySharedContainerType::ReadTicket getProperties() const
Returns a read ticket for read-access to the list of properties.
virtual bool existsProperty(std::string name)
Helper function that finds a property by its name.
This is the base class and interface for property groups.
Comfortable template to create a property instance and add it to the group.
Abstract base class for all properties.
Definition: WPropertyBase.h:52
WPropertyGroupBase(std::string name, std::string description)
Constructor.
boost::shared_ptr< WPropertyBase > SPtr
Convenience typedef for a boost::shared_ptr< WPropertyBase >
Definition: WPropertyBase.h:58
static const std::string separator
The separator used to separate groups and subgroups.
virtual boost::shared_ptr< WPropertyBase > findProperty(std::string name) const
Searches the property with a given name.
PropertyType::element_type::ValueType ValueType
The type of the initial value.
virtual boost::shared_ptr< WPropertyBase > getProperty(std::string name)
Function searches the property.
PropertyContainerType::const_iterator PropertyConstIterator
The const iterator type of the container.
virtual PropertySharedContainerType::ReadTicket getReadTicket() const
Returns an read ticket for the properties.
boost::shared_ptr< WSharedObjectTicketRead< PropertyContainerType > > ReadTicket
Type for read tickets.
Definition: WSharedObject.h:64
virtual ~WPropertyGroupBase()
Destructor.