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

Object.h

00001 // Copyright (C) 1999 Jean-Marc Valin
00002 
00003 #ifndef _OBJECT_H_
00004 #define _OBJECT_H_
00005 
00006 #include "typemap.h"
00007 #include "rc_ptrs.h"
00008 #include <string>
00009 #include <map>
00010 #include "BaseException.h"
00011 #include <typeinfo>
00012 #include "multithread.h"
00013 
00014 namespace FD {
00015 
00016 class _ObjectFactory;
00017 
00022 class Object
00023 {
00024    protected:
00025    
00026       AtomicCounter ref_count;
00027    
00028    public:
00029 
00031       Object() : ref_count(1) {}
00032 
00034       virtual ~Object() { }
00035 
00037       void ref() 
00038       {
00039          ref_count.inc();
00040       }
00041 
00043       void unref()
00044       {
00045          if (ref_count.dec()==0)
00046          {
00047             destroy();
00048          }
00049       }
00050 
00052       int unique () {return ref_count.unique();}
00053 
00055       virtual void destroy()
00056       {
00057          delete this;
00058       }
00059 
00061       virtual void serialize(std::ostream &out) const;
00062 
00064       virtual void unserialize(std::istream &in);
00065    
00067       virtual void doesNotUnderstand(std::string method);
00068 
00070       virtual void printOn(std::ostream &out=std::cout) const = 0;
00071 
00073       virtual bool isNil() const {return false;}
00074    
00076       virtual void prettyPrint(std::ostream &out=std::cout) const
00077       {
00078          printOn(out);
00079       }
00080 
00082       virtual void readFrom(std::istream &in=std::cin)
00083       {
00084          throw new GeneralException("Trying to read undefined Object", __FILE__, __LINE__);
00085       }
00086 
00088       friend std::ostream &operator << (std::ostream &out, const Object& obj) 
00089       {
00090          obj.printOn (out);
00091          return out;
00092       }
00093 
00095       virtual ObjectRef clone()
00096       {
00097          std::string message = "Method clone() not implemented for this object : ";
00098          message += typeid(this).name();
00099          throw new GeneralException(message, __FILE__, __LINE__);
00100       }
00101 
00103       virtual std::string className() const;
00104       
00106       static ObjectRef newObject(const std::string &objType);
00107 
00109       template<class T>
00110       static int addObjectType(const std::string &objType, _ObjectFactory *factory)
00111       {
00112          if (ObjectFactoryDictionary().find(objType) != ObjectFactoryDictionary().end())
00113          {
00114                  std::cerr<< "Duplicated object type found : "
00115                           << objType << ", it not be inserted in the ObjectFactoryDictionary."<<std::endl;
00116                  
00117                  return -1;
00118          }
00119          else
00120          {
00121                 ObjectFactoryDictionary()[objType] = factory;
00122                 TypeidDictionary()[&typeid(T)] = factory;
00123                 return 0;
00124          }
00125       }
00126 
00127       static std::map<std::string, _ObjectFactory*>& ObjectFactoryDictionary();
00128       static TypeMap<_ObjectFactory*>& TypeidDictionary();
00129       //static map<const type_info *, _ObjectFactory*>& TypeidDictionary();
00130 };
00131 
00132 class _ObjectFactory 
00133 {
00134    std::string typeName;
00135 
00136    public:
00137       _ObjectFactory(const std::string &_name) : typeName(_name) {}
00138       virtual ~_ObjectFactory() {}
00139       virtual ObjectRef create() = 0;
00140       const std::string &getName() {return typeName;}
00141 };
00142 
00143 template <class T>
00144 class ObjectFactory : public _ObjectFactory
00145 {
00146    public:
00147       ObjectFactory(const std::string &_name) : _ObjectFactory(_name) {}
00148       virtual ObjectRef create() {return ObjectRef(new T);}
00149 };
00150 
00151 
00152 /* This used to be Object::GetClassName<T>() but it changed because of stupid MSVC++ bugs*/
00153 template<class T>
00154 std::string ObjectGetClassName()
00155 {
00156    static TypeMap<_ObjectFactory*> &m = Object::TypeidDictionary();
00157    static TypeMap<_ObjectFactory*>::iterator found = m.find(&typeid(T));
00158    if (found != m.end())
00159       return found->second->getName();
00160    else
00161    {
00162       //throw GeneralException ("Object::GetClassName() failed, object type is not registered",
00163       //                      __FILE__, __LINE__);
00164       //static const string unknown("unknown");
00165       return "unknown";
00166    }
00167 }
00168 
00169 
00170 #define UNIQUE_STRING(line) dummy_init_for ## line
00171 
00172 #define DECLARE_TYPE2A(type, dummyID) static int UNIQUE_STRING(dummyID) = \
00173                Object::addObjectType<type > (# type, new ObjectFactory<type > (#type));
00174 
00175 #define DECLARE_TYPE3A(str, type, dummyID) static int UNIQUE_STRING(dummyID) = \
00176                Object::addObjectType<type > (str, new ObjectFactory<type > (str));
00177 
00178 #define DECLARE_TYPE(type) DECLARE_TYPE2A(type, __LINE__)
00179 #define DECLARE_TYPE2(str, type) DECLARE_TYPE3A(str, type, __LINE__)
00180 
00181 
00182 class NilObject : public Object 
00183 {
00184    public:
00185       virtual void printOn(std::ostream &out=std::cout) const
00186       {
00187          out << "<NilObject >";
00188       }
00189 
00191       virtual bool isNil() const { return true; }
00192 
00193       virtual void readFrom(std::istream &in=std::cin)
00194       {
00195          char ch;
00196          in >> ch;
00197          if (ch != '>')
00198             throw new GeneralException("Error reading NilObject: '>' expected", __FILE__, __LINE__); 
00199       }
00200 
00201 };
00202 
00203 extern ObjectRef nilObject;
00204 
00205 
00206 //ObjectRef ObjectFactory<NilObject>::create() {return nilObject;}
00207 
00208 }//namespace FD
00209 #endif

Generated on Wed Oct 5 14:28:55 2005 for FlowDesigner by  doxygen 1.4.4