00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00025 #ifndef _Properties_hpp
00026 #define _Properties_hpp
00027
00028
00029 #include<sstream>
00030 #include<map>
00031 #include<ImLib3D/XMLTools.hpp>
00032
00034 class ImageProperty : public Streamable
00035 {
00036 public:
00037 string name;
00038
00039
00040 virtual ImageProperty *Duplicate() const=0;
00041 virtual bool operator==(const ImageProperty &other){return true;}
00042 bool IsXML();
00043 virtual ~ImageProperty(){;}
00044 ImageProperty(const string &_name):name(_name){;}
00045 };
00046
00048
00052 class PropertyXML : public ImageProperty
00053 {
00054 xmlpp::Document document;
00055 public:
00056 xmlpp::Element *RootElement() {return document.get_root_node();}
00057 const xmlpp::Element *RootElement() const {return document.get_root_node();}
00058 virtual void Write(ImLib3DFile *file,xmlpp::Element *parentNode=NULL,xmlpp::Element *node=NULL) const
00059 {
00060 parentNode->import_node(document.get_root_node());
00061 }
00062 virtual void Read(ImLib3DFile *file,xmlpp::Element *parentNode=NULL,xmlpp::Element *node=NULL)
00063 {
00064 document.create_root_node_by_import(node);
00065 }
00066 virtual ImageProperty *Duplicate() const
00067 {
00068 PropertyXML *res=new PropertyXML(name);
00069 res->document.create_root_node_by_import(document.get_root_node());
00070 return res;
00071 }
00072 PropertyXML(const string &_name):ImageProperty(_name){;}
00073 PropertyXML(const string &_name,const xmlpp::Element *node):
00074 ImageProperty(_name)
00075 {
00076 document.create_root_node_by_import(node);
00077 }
00078 };
00079
00080
00082 template<class PType>
00083 class TemplatedProperty : public ImageProperty
00084 {
00085 public:
00086 virtual PType &Get()=0;
00087 virtual const PType &Get() const =0;
00088 TemplatedProperty(const string &_name):ImageProperty(_name){;}
00089 };
00090
00091 template<class T>
00092 inline void
00093 PropertyWrapPtr_ReadFromString(const string &str,T *p)
00094 {
00095 istringstream ist(str);
00096 ist >> *p;
00097 }
00098 template<>
00099 inline void
00100 PropertyWrapPtr_ReadFromString<string>(const string &str,string *p)
00101 {
00102 *p=str;
00103 }
00104
00106
00107 template<class PType>
00108 class PropertyWrapPtr : public TemplatedProperty<PType>
00109 {
00110 typedef TemplatedProperty<PType> _Base;
00111 public:
00112 PType *ptr;
00113 virtual PType &Get(){return *ptr;}
00114 virtual const PType &Get() const {return *ptr;}
00115 virtual bool operator==(const ImageProperty &other){return true;}
00116 virtual void Write(ImLib3DFile *file,xmlpp::Element *parentNode=NULL,xmlpp::Element *node=NULL) const
00117 {
00118 node=CreateWriteNode(_Base::name,file,parentNode,node);
00119 ostringstream ost;
00120 ost << *ptr;
00121 node->set_attribute("value",ost.str());
00122 node->set_attribute("PropertyType","PropertyWrapPtr");
00123 node->set_attribute("type",TypeName<PType>());
00124 }
00125
00126 virtual void Read(ImLib3DFile *file,xmlpp::Element *parentNode=NULL,xmlpp::Element *node=NULL)
00127 {
00128 node=CreateReadNode(_Base::name,file,parentNode,node);
00129 if(!ptr){ptr=new PType();}
00130 mprintf("PropertyWrapPtr::Read: valueprop:%x\n",node->get_attribute("value" ));
00131 string value=node->get_attribute("value" )->get_value();
00132 mprintf("PropertyWrapPtr::Read: value:%s\n",value.c_str());
00133 PropertyWrapPtr_ReadFromString<PType>(value,ptr);
00134 }
00135 virtual ImageProperty *Duplicate() const
00136 {
00137 PropertyWrapPtr<PType> *res=new PropertyWrapPtr<PType>(_Base::name);
00138 res->ptr=new PType();
00139 *(res->ptr)=*ptr;
00140 return res;
00141 }
00142 virtual ~PropertyWrapPtr(){if(ptr)delete ptr;}
00143 PropertyWrapPtr(const string &_name,PType *_ptr):TemplatedProperty<PType>(_name),ptr(_ptr){;}
00144 PropertyWrapPtr(const string &_name):TemplatedProperty<PType>(_name),ptr(NULL){;}
00145 };
00146
00147
00148 class Mask3D;
00150
00151 class Properties : public Streamable
00152 {
00153 typedef ImageProperty Prop;
00154 typedef PropertyXML PropXML;
00155 mutable map<string,Prop *> properties;
00156 public:
00157
00159 void ClearProperties();
00160
00162 template<class PropClass>
00163 void Parse(const string &name)
00164 {
00165 map<string,Prop *>::iterator p=properties.find(name);
00166 if(p==properties.end()){ThrowError("Properties::Parse: could not find property:\"%s\"",name);}
00167 PropXML *propxml=(PropXML *)((*p).second);
00168 if(!propxml->IsXML())
00169 {
00170 mprintf("WARNING: Properties::Parse: \"%s\" not xml prop. Maybe it has already been parsed?\n",name);
00171 return;
00172 }
00173 properties.erase(p);
00174 properties[name]=new PropClass(name);
00175 ImLib3DFile file("","m");
00176 properties[name]->Read(&file,NULL,propxml->RootElement());
00177 delete propxml;
00178 }
00179
00180 template<class PType>
00181 void DefaultParse(const string &name)
00182 {
00183 Parse<PropertyWrapPtr<PType> >(name);
00184 }
00185
00186 void Set(const string &name,const ImageProperty *value)
00187 {
00188 map<string,Prop *>::iterator p=properties.find(name);
00189 if(p!=properties.end())
00190 {
00191 delete properties[name];
00192 }
00193 properties[name]=value->Duplicate();
00194 }
00195
00197 ImageProperty *Get(const string &name)
00198 {
00199 map<string,Prop *>::iterator p=properties.find(name);
00200 if(p==properties.end()){ThrowError("Properties::Get: could not find property:\"%s\"",name);}
00201 if((*p).second->IsXML()){ThrowError("Properties::Get: unparsed property \"%s\", you must parse it before accesing it",name);}
00202 return (*p).second;
00203 }
00204
00206 const ImageProperty *Get(const string &name) const
00207 {
00208 map<string,Prop *>::iterator p=properties.find(name);
00209 if(p==properties.end()){ThrowError("Properties::Get: could not find property:\"%s\"",name);}
00210 if((*p).second->IsXML()){ThrowError("Properties::Get: unparsed property \"%s\", you must parse it before accesing it",name);}
00211 return (*p).second;
00212 }
00213
00215 template<class PType>
00216 PType &GetTemplatedProperty(const string &name)
00217 {
00218 return dynamic_cast<TemplatedProperty<PType> *>(Get(name))->Get();
00219 }
00220
00222 template<class PType>
00223 const PType &GetTemplatedProperty(const string &name,PType dud=PType()) const
00224 {
00225 return dynamic_cast<const TemplatedProperty<PType> *>(Get(name))->Get();
00226 }
00227
00228 bool Has(const string &propname) const {return properties.find(propname)!=properties.end();}
00229
00231 void Add(const string &name,const char * str){Add(name,string(str));}
00232
00234 template<class PType>
00235 void Add(const string &name,PType* ptr)
00236 {
00237 if(properties.find(name)!=properties.end()){delete properties[name];}
00238 properties[name]=new PropertyWrapPtr<PType>(name,ptr);
00239 }
00241 template<class PType>
00242 void Add(const string &name,PType obj)
00243 {
00244 PType *ptr=new PType(obj);
00245
00246 Add(name,ptr);
00247 }
00248
00250
00252 void AddUnparsed(const string &name,const PropertyXML &unparsed)
00253 {
00254 properties[name]=unparsed.Duplicate();
00255 }
00256
00257
00259 void Remove(const string &name);
00260
00261 Mask3D *mask;
00262 Vect3Di *iCenter;
00263
00264 void operator=(const Properties &other);
00265 bool operator==(const Properties &other) const;
00266
00267 void Read( ImLib3DFile *file,xmlpp::Element *parentNode=NULL,xmlpp::Element *node=NULL);
00268 void Write(ImLib3DFile *file,xmlpp::Element *parentNode=NULL,xmlpp::Element *node=NULL) const;
00269
00270 void AddMask(const Size3D &size);
00271
00272 virtual ~Properties(){ClearProperties();}
00273
00274 template<class ImageType>
00275 Properties(ImageType *_image):
00276 mask(NULL),
00277 iCenter(NULL)
00278 {
00279 ;
00280 }
00281 };
00282 #endif // _Properties_hpp