OpenWalnut 1.3.1
|
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 00045 /** 00046 * This is the base class and interface for property groups. This class itself is abstract and derived from WPropertyBase. So if you create a 00047 * 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 00048 * itself. This allows the deriving class to prohibit modifications and to provide a custom interface, or even model-controller like 00049 * implementations. 00050 * 00051 * Another advantage is, that the GUI implementations which support WPropertyGroupBase can display your custom properties directly. 00052 */ 00053 class WPropertyGroupBase: public WPropertyBase 00054 { 00055 public: 00056 /** 00057 * For shortening: a type defining a shared vector of WSubject pointers. 00058 */ 00059 typedef std::vector< boost::shared_ptr< WPropertyBase > > PropertyContainerType; 00060 00061 /** 00062 * The alias for a shared container. 00063 */ 00064 typedef WSharedSequenceContainer< PropertyContainerType > PropertySharedContainerType; 00065 00066 /** 00067 * The const iterator type of the container. 00068 */ 00069 typedef PropertyContainerType::const_iterator PropertyConstIterator; 00070 00071 /** 00072 * The iterator type of the container. 00073 */ 00074 typedef PropertyContainerType::iterator PropertyIterator; 00075 00076 /** 00077 * Convenience typedef for a boost::shared_ptr< WPropertyGroupBase >. 00078 */ 00079 typedef boost::shared_ptr< WPropertyGroupBase > SPtr; 00080 00081 /** 00082 * Convenience typedef for a boost::shared_ptr< const WPropertyGroupBase >. 00083 */ 00084 typedef boost::shared_ptr< const WPropertyGroupBase > ConstSPtr; 00085 00086 /////////////////////////////////////////////////////////////////////////////////////////////////// 00087 // Construction 00088 /////////////////////////////////////////////////////////////////////////////////////////////////// 00089 00090 /** 00091 * Constructor. Creates an empty list of properties. 00092 * 00093 * \param name the name of the property group. The GUI is using this name for naming the tabs/group boxes 00094 * \param description the description of the group. 00095 */ 00096 WPropertyGroupBase( std::string name, std::string description ); 00097 00098 /** 00099 * Copy constructor. Creates a deep copy of this property. As boost::signals2 and condition variables are non-copyable, new instances get 00100 * created. The subscriptions to a signal are LOST as well as all listeners to a condition. 00101 * The conditions you can grab using getValueChangeConditon and getCondition are not the same as in the original! This is because 00102 * the class corresponds to the observer/observable pattern. You won't expect a clone to fire a condition if a original flag is changed 00103 * (which after cloning is completely decoupled from the clone). 00104 * 00105 * \note the properties inside this list are also copied deep 00106 * 00107 * \param from the instance to copy. 00108 */ 00109 explicit WPropertyGroupBase( const WPropertyGroupBase& from ); 00110 00111 /** 00112 * Destructor. 00113 */ 00114 virtual ~WPropertyGroupBase(); 00115 00116 /////////////////////////////////////////////////////////////////////////////////////////////////// 00117 // The WPropertyGroupBase interface 00118 /////////////////////////////////////////////////////////////////////////////////////////////////// 00119 00120 /** 00121 * Helper function that finds a property by its name. Use this method to find out whether the property exists or not, since 00122 * findProperty throws an exception. 00123 * 00124 * \param name name of searched property. 00125 * 00126 * \return Answer to the question whether the property exists. 00127 */ 00128 virtual bool existsProperty( std::string name ); 00129 00130 /** 00131 * Function searches the property. If it does not exists, it throws an exception. 00132 * 00133 * \param name the name of the property 00134 * 00135 * \return a WProperty object 00136 */ 00137 virtual boost::shared_ptr< WPropertyBase > getProperty( std::string name ); 00138 00139 /** 00140 * Returns a read ticket for read-access to the list of properties. 00141 * 00142 * \return the read ticket. 00143 */ 00144 virtual PropertySharedContainerType::ReadTicket getProperties() const; 00145 00146 /** 00147 * Returns an read ticket for the properties. This, and only this, has to be used for external iteration of properties. 00148 * 00149 * \see WSharedObjectTicketRead 00150 * \return the read ticket. 00151 */ 00152 virtual PropertySharedContainerType::ReadTicket getReadTicket() const; 00153 00154 /** 00155 * Searches the property with a given name. It does not throw any exception. It simply returns NULL if it can't be found. 00156 * 00157 * \param name the name of the property to search 00158 * 00159 * \return the property or NULL if not found. 00160 */ 00161 virtual boost::shared_ptr< WPropertyBase > findProperty( std::string name ) const; 00162 00163 protected: 00164 /** 00165 * Helping function to find a property inside a specific group. It does not recursively find properties nested inside other property groups. 00166 * 00167 * \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 00168 * findProperty as it is contained in this or a nested properties instance. 00169 * \param name the name of the property inside THIS group. 00170 * 00171 * \return the property if found, else NULL. 00172 */ 00173 virtual boost::shared_ptr< WPropertyBase > findProperty( const WPropertyGroupBase* const props, std::string name ) const; 00174 00175 /** 00176 * The set of proerties. This uses the operators ==,<,> WProperty to determine equalness. 00177 */ 00178 PropertySharedContainerType m_properties; 00179 00180 /** 00181 * Compares the names of two properties and returns true if they are equal. 00182 * 00183 * \param prop1 the first prop. 00184 * \param prop2 the second prop. 00185 * 00186 * \return Are the names of the two properties equal? 00187 */ 00188 bool propNamePredicate( boost::shared_ptr< WPropertyBase > prop1, boost::shared_ptr< WPropertyBase > prop2 ) const; 00189 00190 /** 00191 * Insert the specified property into the list. This method is protected. It is a convenience method for deriving classes to add properties 00192 * without the need to update several conditions and similar. 00193 * 00194 * \param prop the property to add 00195 */ 00196 void addArbitraryProperty( WPropertyBase::SPtr prop ); 00197 00198 /** 00199 * Comfortable template to create a property instance and add it to the group. This is a utility for deriving classes which need to handle 00200 * certain property types and other types during compile time. 00201 * 00202 * At the first glance, this might not look very useful. But this 00203 * is practical to change the add-behaviour for certain property types by specializing this class. For example, the template \ref 00204 * WPropertyStruct uses this to modify the behaviour for the non-property type \ref WPropertyStructHelper::NOTYPE, which is used as 00205 * template list default (to emulate variadic template parameters lists). 00206 * 00207 * \tparam PropertyType the property type to create. It is assumed that this is a shared_ptr< WPropertyXYZ >. 00208 */ 00209 template< typename PropertyType > 00210 struct PropertyCreatorAndGroupAdder 00211 { 00212 /** 00213 * The type of the initial value. 00214 */ 00215 typedef typename PropertyType::element_type::ValueType ValueType; 00216 00217 /** 00218 * Actually does the work and adds a new property with the given name, description and other parameters to the specified group. 00219 * 00220 * \param group the group to add the new property to 00221 * \param name the name of the new property 00222 * \param description the description of the new property 00223 * \param initial initial value 00224 */ 00225 static void createAndAdd( WPropertyGroupBase* group, std::string name, std::string description, const ValueType& initial = ValueType() ) 00226 { 00227 group->addArbitraryProperty( 00228 PropertyType( 00229 new typename PropertyType::element_type( name, description, initial ) 00230 ) 00231 ); 00232 } 00233 }; 00234 00235 private: 00236 }; 00237 00238 #endif // WPROPERTYGROUPBASE_H 00239