OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #ifndef WPROPERTYGROUPBASE_H 00026 #define WPROPERTYGROUPBASE_H 00027 00028 #include <map> 00029 #include <string> 00030 #include <vector> 00031 00032 #include <boost/thread/thread.hpp> 00033 #include <boost/thread/mutex.hpp> 00034 #include <boost/thread/locks.hpp> 00035 #include <boost/thread.hpp> 00036 00037 #include "WConditionSet.h" 00038 #include "WPropertyBase.h" 00039 #include "WPropertyTypes.h" 00040 #include "WPropertyVariable.h" 00041 #include "WSharedSequenceContainer.h" 00042 00043 /** 00044 * This is the base class and interface for property groups. This class itself is abstract and derived from WPropertyBase. So if you create a 00045 * 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 00046 * itself. This allows the deriving class to prohibit modifications and to provide a custom interface, or even model-controller like 00047 * implementations. 00048 * 00049 * Another advantage is, that the GUI implementations which support WPropertyGroupBase can display your custom properties directly. 00050 */ 00051 class WPropertyGroupBase: public WPropertyBase 00052 { 00053 public: 00054 /** 00055 * For shortening: a type defining a shared vector of WSubject pointers. 00056 */ 00057 typedef std::vector< boost::shared_ptr< WPropertyBase > > PropertyContainerType; 00058 00059 /** 00060 * The alias for a shared container. 00061 */ 00062 typedef WSharedSequenceContainer< PropertyContainerType > PropertySharedContainerType; 00063 00064 /** 00065 * The const iterator type of the container. 00066 */ 00067 typedef PropertyContainerType::const_iterator PropertyConstIterator; 00068 00069 /** 00070 * The iterator type of the container. 00071 */ 00072 typedef PropertyContainerType::iterator PropertyIterator; 00073 00074 /** 00075 * Convenience typedef for a boost::shared_ptr< WPropertyGroupBase >. 00076 */ 00077 typedef boost::shared_ptr< WPropertyGroupBase > SPtr; 00078 00079 /** 00080 * Convenience typedef for a boost::shared_ptr< const WPropertyGroupBase >. 00081 */ 00082 typedef boost::shared_ptr< const WPropertyGroupBase > ConstSPtr; 00083 00084 /** 00085 * The separator used to separate groups and subgroups 00086 */ 00087 static const std::string separator; 00088 00089 /////////////////////////////////////////////////////////////////////////////////////////////////// 00090 // Construction 00091 /////////////////////////////////////////////////////////////////////////////////////////////////// 00092 00093 /** 00094 * Constructor. Creates an empty list of properties. 00095 * 00096 * \param name the name of the property group. The GUI is using this name for naming the tabs/group boxes 00097 * \param description the description of the group. 00098 */ 00099 WPropertyGroupBase( std::string name, std::string description ); 00100 00101 /** 00102 * Copy constructor. Creates a deep copy of this property. As boost::signals2 and condition variables are non-copyable, new instances get 00103 * created. The subscriptions to a signal are LOST as well as all listeners to a condition. 00104 * The conditions you can grab using getValueChangeConditon and getCondition are not the same as in the original! This is because 00105 * the class corresponds to the observer/observable pattern. You won't expect a clone to fire a condition if a original flag is changed 00106 * (which after cloning is completely decoupled from the clone). 00107 * 00108 * \note the properties inside this list are also copied deep 00109 * 00110 * \param from the instance to copy. 00111 */ 00112 explicit WPropertyGroupBase( const WPropertyGroupBase& from ); 00113 00114 /** 00115 * Destructor. 00116 */ 00117 virtual ~WPropertyGroupBase(); 00118 00119 /////////////////////////////////////////////////////////////////////////////////////////////////// 00120 // The WPropertyGroupBase interface 00121 /////////////////////////////////////////////////////////////////////////////////////////////////// 00122 00123 /** 00124 * Helper function that finds a property by its name. Use this method to find out whether the property exists or not, since 00125 * findProperty throws an exception. 00126 * 00127 * \param name name of searched property. 00128 * 00129 * \return Answer to the question whether the property exists. 00130 */ 00131 virtual bool existsProperty( std::string name ); 00132 00133 /** 00134 * Function searches the property. If it does not exists, it throws an exception. 00135 * 00136 * \param name the name of the property 00137 * 00138 * \return a WProperty object 00139 */ 00140 virtual boost::shared_ptr< WPropertyBase > getProperty( std::string name ); 00141 00142 /** 00143 * Returns a read ticket for read-access to the list of properties. 00144 * 00145 * \return the read ticket. 00146 */ 00147 virtual PropertySharedContainerType::ReadTicket getProperties() const; 00148 00149 /** 00150 * Returns an read ticket for the properties. This, and only this, has to be used for external iteration of properties. 00151 * 00152 * \see WSharedObjectTicketRead 00153 * \return the read ticket. 00154 */ 00155 virtual PropertySharedContainerType::ReadTicket getReadTicket() const; 00156 00157 /** 00158 * 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 00159 * in nested groups too. The naming rules for finding a property in subgroups of this group is like specifying a path, using the \ref 00160 * separator char: "somegroup" + separator + "anothergroup" + separator + "propnametosearch". 00161 * 00162 * \param name the name of the property to search 00163 * 00164 * \return the property or NULL if not found. 00165 */ 00166 virtual boost::shared_ptr< WPropertyBase > findProperty( std::string name ) const; 00167 00168 /** 00169 * The visitor type used to visit properties as strings. The first parameter is the name, including the path of the property, relative to 00170 * this group. The second parameter is the value as string. 00171 */ 00172 typedef boost::function< void ( std::string, std::string )> PropertyStringVisitor; 00173 00174 /** 00175 * Visit all leafs in the property three that aren't empty groups. This is especially interesting when using it with lambda functionality. 00176 * The visitor function gets two parameters: 1st: the name of the property, including the path beginning at this group; 2nd: the value as 00177 * string. 00178 * 00179 * \param visitor the function to use for each property. 00180 * \param pathPrefix add this prefix to the property name in the visitor. It might be interesting if manually implementing group visitors 00181 * that always require a complete path, so you can add an upper-level path here. 00182 */ 00183 virtual void visitAsString( PropertyStringVisitor visitor, std::string pathPrefix = "" ) const; 00184 00185 protected: 00186 /** 00187 * Helping function to find a property inside a specific group. It does not recursively find properties nested inside other property groups. 00188 * 00189 * \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 00190 * findProperty as it is contained in this or a nested properties instance. 00191 * \param name the name of the property inside THIS group. 00192 * 00193 * \return the property if found, else NULL. 00194 */ 00195 virtual boost::shared_ptr< WPropertyBase > findProperty( const WPropertyGroupBase* const props, std::string name ) const; 00196 00197 /** 00198 * The set of proerties. This uses the operators ==,<,> WProperty to determine equalness. 00199 */ 00200 PropertySharedContainerType m_properties; 00201 00202 /** 00203 * Compares the names of two properties and returns true if they are equal. 00204 * 00205 * \param prop1 the first prop. 00206 * \param prop2 the second prop. 00207 * 00208 * \return Are the names of the two properties equal? 00209 */ 00210 bool propNamePredicate( boost::shared_ptr< WPropertyBase > prop1, boost::shared_ptr< WPropertyBase > prop2 ) const; 00211 00212 /** 00213 * Insert the specified property into the list. This method is protected. It is a convenience method for deriving classes to add properties 00214 * without the need to update several conditions and similar. 00215 * 00216 * \param prop the property to add 00217 */ 00218 void addArbitraryProperty( WPropertyBase::SPtr prop ); 00219 00220 /** 00221 * Comfortable template to create a property instance and add it to the group. This is a utility for deriving classes which need to handle 00222 * certain property types and other types during compile time. 00223 * 00224 * At the first glance, this might not look very useful. But this 00225 * is practical to change the add-behaviour for certain property types by specializing this class. For example, the template \ref 00226 * WPropertyStruct uses this to modify the behaviour for the non-property type \ref WPropertyStructHelper::NOTYPE, which is used as 00227 * template list default (to emulate variadic template parameters lists). 00228 * 00229 * \tparam PropertyType the property type to create. It is assumed that this is a shared_ptr< WPropertyXYZ >. 00230 */ 00231 template< typename PropertyType > 00232 struct PropertyCreatorAndGroupAdder 00233 { 00234 /** 00235 * The type of the initial value. 00236 */ 00237 typedef typename PropertyType::element_type::ValueType ValueType; 00238 00239 /** 00240 * Actually does the work and adds a new property with the given name, description and other parameters to the specified group. 00241 * 00242 * \param group the group to add the new property to 00243 * \param name the name of the new property 00244 * \param description the description of the new property 00245 * \param initial initial value 00246 */ 00247 static void createAndAdd( WPropertyGroupBase* group, std::string name, std::string description, const ValueType& initial = ValueType() ) 00248 { 00249 group->addArbitraryProperty( 00250 PropertyType( 00251 new typename PropertyType::element_type( name, description, initial ) 00252 ) 00253 ); 00254 } 00255 }; 00256 00257 private: 00258 }; 00259 00260 #endif // WPROPERTYGROUPBASE_H 00261