00001
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
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
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
00163
00164
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
00207
00208 }
00209 #endif