00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _GOFACTORY_H
00034 #define _GOFACTORY_H
00035
00036 #include <map>
00037 #include "GeomObject.h"
00038 #include <boost/smart_ptr.hpp>
00039
00040
00041 namespace Go
00042 {
00045
00049 class Creator
00050 {
00051 public:
00052 virtual GeomObject* create() = 0;
00053 virtual ~Creator() {}
00054 };
00055
00059 template <class T>
00060 class ConcreteCreator : public Creator
00061 {
00062 public:
00063 ConcreteCreator() {}
00064 GeomObject* create()
00065 {
00066 return new T;
00067 }
00068 };
00069
00078 class Factory
00079 {
00080 public:
00081 ~Factory()
00082 {
00083 std::map<ClassType, Creator*>::iterator it;
00084 for (it = themap_.begin(); it != themap_.end(); ++it)
00085 delete it->second;
00086 }
00087
00092 static GeomObject* createObject(ClassType class_type)
00093 {
00094 return globalFactory()->doCreateObject(class_type);
00095 }
00096
00106 void registerClass(ClassType class_type, Creator* c)
00107 {
00108 themap_[class_type] = c;
00109 }
00110
00113 static Factory* globalFactory()
00114 {
00115 if (global_factory_.get() == 0)
00116 global_factory_ = boost::shared_ptr<Factory>(new Factory);
00117 return global_factory_.get();
00118 }
00119 private:
00120
00121
00122 Factory()
00123 {
00124 }
00125
00126 GeomObject* doCreateObject(ClassType class_type)
00127 {
00128 std::map<ClassType, Creator*>::iterator it;
00129 it = themap_.find(class_type);
00130 if (it==themap_.end()) {
00131 THROW("Class type number " << class_type
00132 << " is not registered.");
00133 }
00134 return it->second->create();
00135 }
00136 static boost::shared_ptr<Factory> global_factory_;
00137 std::map<ClassType, Creator*> themap_;
00138 };
00139
00146 template <class T>
00147 void Register()
00148 {
00149 Factory* f = Factory::globalFactory();
00150 ConcreteCreator<T>* c = new ConcreteCreator<T>;
00151 f->registerClass(T::classType(), c);
00152 }
00153
00158
00159
00165 template <class T>
00166 class Registrator
00167 {
00168 public:
00169 Registrator()
00170 {
00171 Factory* f = Factory::globalFactory();
00172 ConcreteCreator<T>* c = new ConcreteCreator<T>;
00173 f->registerClass(T::classType(), c);
00174 }
00175 };
00176
00177
00179 }
00180
00181 #endif // _GOFACTORY_H
00182
00183