Property.h

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

Generated on Wed Sep 12 23:19:42 2007 for nrEngine by  doxygen 1.5.1