Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

Properties.hpp

Go to the documentation of this file.
00001 /* ImLib3D
00002  * Copyright (c) 2001, ULP-IPB Strasbourg.
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or (at
00007  * your option) any later version.
00008  * 
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  * 
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 //      virtual void Write(ImLib3DFile *file,xmlpp::Element *parentNode=NULL,xmlpp::Element *node=NULL) const =0;
00039 //      virtual void Read( ImLib3DFile *file,xmlpp::Element *parentNode=NULL,xmlpp::Element *node=NULL)=0;
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;}//*ptr==*other.ptr;}
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     // sets a property
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 //      *ptr=obj;
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

Generated on Fri Jun 17 13:36:06 2005 for ImLib3D by  doxygen 1.4.2