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