00001 /*************************************************************************** 00002 * * 00003 * (c) Art Tevs, MPI Informatik Saarbruecken * 00004 * mailto: <tevs@mpi-sb.mpg.de> * 00005 * * 00006 * This program is free software; you can redistribute it and/or modify * 00007 * it under the terms of the GNU General Public License as published by * 00008 * the Free Software Foundation; either version 2 of the License, or * 00009 * (at your option) any later version. * 00010 * * 00011 ***************************************************************************/ 00012 00013 00014 #ifndef _NR_PROPERTY_H_ 00015 #define _NR_PROPERTY_H_ 00016 00017 //---------------------------------------------------------------------------------- 00018 // Includes 00019 //---------------------------------------------------------------------------------- 00020 #include "Prerequisities.h" 00021 #include <boost/any.hpp> 00022 00023 00024 namespace nrEngine{ 00025 00026 class PropertyManager; 00027 00028 //! Properties are name value pair with a value of any type 00029 /** 00030 * Properties represents name-value pairs with a name as a string and a 00031 * value of any type. For the type of value we use boost::any which is 00032 * capable to represent any type of data. 00033 * 00034 * \ingroup gp 00035 **/ 00036 class _NRExport Property{ 00037 public: 00038 00039 /** 00040 * Create an empty property object. No name is specified 00041 * and no value 00042 **/ 00043 Property(); 00044 00045 /** 00046 * Create a new property object. 00047 * 00048 * @param name Name of the property. Name should be unique 00049 * within one property map 00050 **/ 00051 Property(const std::string& name); 00052 00053 /** 00054 * Construct a property object with a certain name, but also define 00055 * a value directly 00056 **/ 00057 Property (const std::string& name, const boost::any& value); 00058 00059 /** 00060 * Construct the property from another one 00061 **/ 00062 Property(const Property&); 00063 00064 /** 00065 * Get the name of the property 00066 **/ 00067 NR_FORCEINLINE const std::string& getName() const { return mName; } 00068 00069 /** 00070 * Get the fullname of the property. Fullname contains 00071 * whole group path and the name (i.e. "group.name" ). 00072 * Only PropertyManager can change full name, because he does 00073 * only know to which group this property belongs. If property 00074 * is not handled by manager, so fullname is equal name 00075 **/ 00076 NR_FORCEINLINE const std::string& getFullName() const { return mFullName; } 00077 00078 /** 00079 * Get value of the property 00080 **/ 00081 NR_FORCEINLINE const boost::any& getValue() const { return mValue; } 00082 NR_FORCEINLINE boost::any& getValue() { return mValue; } 00083 00084 00085 /** 00086 * Check if the stored value has this type 00087 **/ 00088 //NR_FORCEINLINE bool is 00089 00090 /** 00091 * Assign new value to the property 00092 **/ 00093 Property& operator=(const boost::any& ); 00094 00095 /** 00096 * Compare two properties. Two properties are the same 00097 * if their names and type of the values are the same. 00098 * 00099 * NOTE: We can not compare the values itself because boost::any 00100 * library can not be casted here to any type. If you wish to have 00101 * more usefull comparing function, that refer to compare<T>() 00102 **/ 00103 bool operator==(const Property& ); 00104 00105 bool operator!=(const Property& p) { return !(operator==(p)); } 00106 00107 00108 /** 00109 * Specific compare of the values with a certain type. 00110 * This will compare the properties like operator==() 00111 * do and also compare the values by converting them 00112 * to the certain type and looking if they are the same. 00113 **/ 00114 template<class T> bool compare(const Property& p) 00115 { 00116 if (*this != p) return false; 00117 return boost::any_cast<T>(mValue) == boost::any_cast<T>(p.getValue()); 00118 } 00119 00120 /** 00121 * Get the value by casting to a certain type 00122 **/ 00123 template<class T> T get(){ 00124 return boost::any_cast<T>(mValue); 00125 } 00126 00127 /** 00128 * Set user data. We use extra user data information if casting 00129 * will fail for the value types. 00130 **/ 00131 NR_FORCEINLINE void setUserData(void* data) { mUserData = data; } 00132 00133 /** 00134 * Get user data from the property 00135 **/ 00136 NR_FORCEINLINE void* getUserData() { return mUserData; } 00137 00138 /** 00139 * Does our property contains any user data. Just check if the user 00140 * data pointer equals to NULL. If yes, so we do not get any user data. 00141 **/ 00142 NR_FORCEINLINE bool hasUserData() { return mUserData != NULL; } 00143 00144 private: 00145 00146 //! Name of the property 00147 std::string mName; 00148 00149 //! Full name of property (group.name) 00150 std::string mFullName; 00151 00152 //! Value holding by the property 00153 boost::any mValue; 00154 00155 //! Userdata to be stored 00156 void* mUserData; 00157 00158 //! Manager is allowed to change internal structure 00159 friend class PropertyManager; 00160 00161 //! Copy only the data from given property 00162 NR_FORCEINLINE void copyDataOnly(const Property& p) 00163 { 00164 mValue = p.mValue; 00165 mUserData = p.mUserData; 00166 } 00167 }; 00168 00169 //! Property list to hold property objects 00170 /** 00171 * PropertyList is a derived class from std::list holding 00172 * objects of type Property. We expand the functionality by 00173 * adding some nicer operators and functions, so the list 00174 * can be constructed in concatenated way. 00175 * \ingroup gp 00176 **/ 00177 class _NRExport PropertyList : public std::list<Property> { 00178 public: 00179 00180 /** 00181 * Add a new element into the property list 00182 **/ 00183 PropertyList& operator, (const Property& p); 00184 00185 /** 00186 * Pop an element from the front and return it back 00187 **/ 00188 PropertyList& operator, (Property& p); 00189 00190 /** 00191 * Check if a certain property exists 00192 **/ 00193 bool exists(const std::string& name) const; 00194 00195 /** 00196 * Get a property value by the given name. 00197 * The behaviour is the same as in std::map. If no 00198 * such property exists, so new one with such a name will be created 00199 **/ 00200 Property& operator[](const std::string& name); 00201 const Property& operator[](const std::string& name) const ; 00202 00203 /** 00204 * Get property from the list 00205 **/ 00206 //Property& get(const std::string& name); 00207 00208 }; 00209 00210 00211 }; // end namespace 00212 00213 #endif