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