00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef OST_GENETRIC_PROPERTY_HH
00020 #define OST_GENETRIC_PROPERTY_HH
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <sstream>
00032 #include <map>
00033 #include <vector>
00034 #include <boost/variant.hpp>
00035
00036 #include <ost/module_config.hh>
00037 #include <ost/invalid_handle.hh>
00038 #include <ost/message.hh>
00039 #include <ost/geom/vec3.hh>
00040
00041 namespace ost {
00042
00043 struct DLLEXPORT GenericPropError: public Error
00044 {
00045 GenericPropError(const String& m):
00046 Error(m)
00047 {}
00048 };
00049
00050 typedef boost::variant<String, Real, int, bool, geom::Vec3> GenericPropValue;
00051
00053 class TEMPLATE_EXPORT GenericPropContainerImpl
00054 {
00055 typedef std::map<String,GenericPropValue> PropertyMap;
00056
00057 public:
00058 GenericPropContainerImpl(): map_(NULL) {}
00059 ~GenericPropContainerImpl()
00060 {
00061 if (map_) {
00062 delete map_;
00063 }
00064 }
00065 GenericPropContainerImpl(const GenericPropContainerImpl& rhs):
00066 map_(rhs.map_ ? new PropertyMap(*rhs.map_) : NULL)
00067 { }
00068
00069 GenericPropContainerImpl& operator=(const GenericPropContainerImpl& r)
00070 {
00071 this->Assign(r);
00072 return *this;
00073 }
00074
00075 GenericPropValue& GenericProp(const String& key)
00076 {
00077 if (!map_) {
00078 map_=new PropertyMap;
00079 }
00080 return (*map_)[key];
00081 }
00082
00083 const GenericPropValue& GenericProp(const String& key) const
00084 {
00085 if (!map_) {
00086 map_=new PropertyMap;
00087 }
00088 return (*map_)[key];
00089 }
00090
00091 bool HasProp(const String& key) const
00092 {
00093 return map_ && map_->find(key) != map_->end();
00094 }
00095
00096 void ClearProps()
00097 {
00098 if (map_) {
00099 map_->clear();
00100 }
00101 }
00102
00103 void RemoveProp(const String& key)
00104 {
00105 if (map_) {
00106 map_->erase(key);
00107 }
00108 }
00109
00110 void Assign(const GenericPropContainerImpl& impl)
00111 {
00112 if (impl.map_) {
00113 if (!map_) {
00114 map_=new PropertyMap(*impl.map_);
00115 } else {
00116 *map_=*impl.map_;
00117 }
00118 } else {
00119 this->ClearProps();
00120 }
00121 }
00122
00123 PropertyMap GetPropMap() const
00124 {
00125 if (!map_) {
00126 map_=new PropertyMap;
00127 }
00128 return *map_;
00129 }
00130
00131 std::vector<String> GetPropList() const
00132 {
00133 std::vector<String> prop_list;
00134 if (map_) {
00135 PropertyMap::const_iterator i;
00136 for (i=map_->begin(); i!=map_->end(); ++i) {
00137 prop_list.push_back(i->first);
00138 }
00139 }
00140 return prop_list;
00141 }
00142
00143 private:
00144 mutable PropertyMap* map_;
00145 };
00146
00147 template <typename H>
00148 class TEMPLATE_EXPORT ConstGenericPropContainer {
00149 protected:
00150
00151 template<typename T>
00152 T gp_get(const String& key) const {
00153 if(HasProp(key)) {
00154 return boost::get<T>(GetImpl()->GenericProp(key));
00155 } else {
00156 std::ostringstream m("");
00157 m << "unknown property " << key;
00158 throw GenericPropError(m.str());
00159 }
00160 }
00161
00162 template<typename T>
00163 T gp_get(const String& key, const T& def) const {
00164 if(HasProp(key)) {
00165 return boost::get<T>(GetImpl()->GenericProp(key));
00166 }
00167 return def;
00168 }
00169 GenericPropContainerImpl* GetImpl()
00170 {
00171 return static_cast<H*>(this)->GpImpl();
00172 }
00173
00174 const GenericPropContainerImpl* GetImpl() const
00175 {
00176 return static_cast<const H*>(this)->GpImpl();
00177 }
00178
00179 public:
00181 bool HasProp(const String& key) const {
00182 CheckHandleValidity(*static_cast<const H*>(this));
00183 return this->GetImpl()->HasProp(key);
00184 }
00185
00193 String GetPropAsString(const String& key) const
00194 {
00195 CheckHandleValidity(*static_cast<const H*>(this));
00196 if(!HasProp(key)) return "";
00197 std::ostringstream rep("");
00198 rep << this->GetImpl()->GenericProp(key);
00199 return rep.str();
00200 }
00201
00203 String GetStringProp(const String& key) const
00204 {
00205 CheckHandleValidity(*static_cast<const H*>(this));
00206 return this->gp_get<String>(key);
00207 }
00208
00211 Real GetFloatProp(const String& key) const
00212 {
00213 CheckHandleValidity(*static_cast<const H*>(this));
00214 if(HasProp(key)) {
00215 GenericPropValue value=this->GetImpl()->GenericProp(key);
00216 switch (value.which()) {
00217 case 1:
00218 return boost::get<Real>(value);
00219 case 2:
00220 return static_cast<Real>(boost::get<int>(value));
00221 case 3:
00222 return static_cast<Real>(boost::get<bool>(value));
00223 }
00224 std::ostringstream m("");
00225 m << "property '" << key << "' is not numeric";
00226 throw GenericPropError(m.str());
00227 }
00228 std::ostringstream m("");
00229 m << "unknown property " << key;
00230 throw GenericPropError(m.str());
00231 }
00233 int GetIntProp(const String& key) const
00234 {
00235 CheckHandleValidity(*static_cast<const H*>(this));
00236 if (HasProp(key)){
00237 GenericPropValue value=this->GetImpl()->GenericProp(key);
00238 switch (value.which()) {
00239 case 2:
00240 return boost::get<int>(value);
00241 case 3:
00242 return boost::get<bool>(value);
00243 }
00244 std::ostringstream m("");
00245 m << "property '" << key << "' is not integral";
00246 throw GenericPropError(m.str());
00247 }
00248 std::ostringstream m("");
00249 m << "unknown property " << key;
00250 throw GenericPropError(m.str());
00251 }
00252
00254 bool GetBoolProp(const String& key) const
00255 {
00256 CheckHandleValidity(*static_cast<const H*>(this));
00257 return this->gp_get<bool>(key);
00258 }
00259
00261 geom::Vec3 GetVec3Prop(const String& key) const
00262 {
00263 CheckHandleValidity(*static_cast<const H*>(this));
00264 return this->gp_get<geom::Vec3>(key);
00265 }
00266
00268 String GetStringProp(const String& key, const String& def) const
00269 {
00270 CheckHandleValidity(*static_cast<const H*>(this));
00271 return this->gp_get<String>(key,def);
00272 }
00273
00276 Real GetFloatProp(const String& key, Real def) const
00277 {
00278 CheckHandleValidity(*static_cast<const H*>(this));
00279 if(this->HasProp(key)) {
00280 GenericPropValue value=GetImpl()->GenericProp(key);
00281 switch (value.which()) {
00282 case 1:
00283 return boost::get<Real>(value);
00284 case 2:
00285 return static_cast<Real>(boost::get<int>(value));
00286 case 3:
00287 return static_cast<Real>(boost::get<bool>(value));
00288 }
00289 std::ostringstream m("");
00290 m << "property '" << key << "' is not numeric";
00291 throw GenericPropError(m.str());
00292 }
00293 return def;
00294 }
00295
00297 int GetIntProp(const String& key, int def) const
00298 {
00299 CheckHandleValidity(*static_cast<const H*>(this));
00300 if(this->HasProp(key)) {
00301 GenericPropValue value=GetImpl()->GenericProp(key);
00302 switch (value.which()) {
00303 case 2:
00304 return boost::get<int>(value);
00305 case 3:
00306 return static_cast<int>(boost::get<bool>(value));
00307 }
00308 std::ostringstream m("");
00309 m << "property '" << key << "' is not integral";
00310 throw GenericPropError(m.str());
00311 }
00312 return def;
00313 }
00314
00316 bool GetBoolProp(const String& key, bool def) const
00317 {
00318 CheckHandleValidity(*static_cast<const H*>(this));
00319 return this->gp_get<bool>(key, def);
00320 }
00321
00322 std::map<String,GenericPropValue> GetPropMap() const
00323 {
00324 CheckHandleValidity(*static_cast<const H*>(this));
00325 return this->GetImpl()->GetPropMap();
00326 }
00327
00328 std::vector<String> GetPropList() const
00329 {
00330 CheckHandleValidity(*static_cast<const H*>(this));
00331 return this->GetImpl()->GetPropList();
00332 }
00333 };
00334
00336 template <typename H>
00337 class TEMPLATE_EXPORT GenericPropContainer :
00338 public ConstGenericPropContainer<H>
00339 {
00340 public:
00341 void ClearProps()
00342 {
00343 CheckHandleValidity(*static_cast<const H*>(this));
00344 this->GetImpl()->ClearProps();
00345 }
00346
00348 void SetStringProp(const String& key, const String& value)
00349 {
00350 CheckHandleValidity(*static_cast<const H*>(this));
00351 this->GetImpl()->GenericProp(key)=value;
00352 }
00353
00355 void SetFloatProp(const String& key, Real value)
00356 {
00357 CheckHandleValidity(*static_cast<const H*>(this));
00358 this->GetImpl()->GenericProp(key)=value;
00359 }
00360
00362 void SetIntProp(const String& key, int value)
00363 {
00364 CheckHandleValidity(*static_cast<const H*>(this));
00365 this->GetImpl()->GenericProp(key)=value;
00366 }
00367
00369 void SetBoolProp(const String& key, bool value)
00370 {
00371 CheckHandleValidity(*static_cast<const H*>(this));
00372 this->GetImpl()->GenericProp(key)=value;
00373 }
00374
00376 void SetVec3Prop(const String& key, geom::Vec3 value)
00377 {
00378 CheckHandleValidity(*static_cast<const H*>(this));
00379 this->GetImpl()->GenericProp(key)=value;
00380 }
00381
00382 void RemoveProp(const String& key)
00383 {
00384 CheckHandleValidity(*static_cast<const H*>(this));
00385 this->GetImpl()->RemoveProp(key);
00386 }
00387 };
00388
00389
00390 }
00391
00392 #endif