Factory.h
Go to the documentation of this file.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 #ifndef SOFA_HELPER_FACTORY_H
00028 #define SOFA_HELPER_FACTORY_H
00029
00030 #include <map>
00031 #include <iostream>
00032 #include <typeinfo>
00033
00034 #include <sofa/helper/system/config.h>
00035
00036 namespace sofa
00037 {
00038
00039 namespace helper
00040 {
00041
00043 std::string gettypename(const std::type_info& t);
00044
00046 void logFactoryRegister(std::string baseclass, std::string classname, std::string key, bool multi);
00047
00049 void printFactoryLog(std::ostream& out = std::cout);
00050
00051 template <class Object, class Argument>
00052 class BaseCreator
00053 {
00054 public:
00055 virtual ~BaseCreator() { }
00056 virtual Object *createInstance(Argument arg) = 0;
00057 virtual const std::type_info& type() = 0;
00058 };
00059
00060 template <typename TKey, class TObject, typename TArgument>
00061 class Factory
00062 {
00063 public:
00064 typedef TKey Key;
00065 typedef TObject Object;
00066 typedef TArgument Argument;
00067 typedef BaseCreator<Object, Argument> Creator;
00068
00069 protected:
00070 std::multimap<Key, Creator*> registry;
00071
00072 public:
00073 bool registerCreator(Key key, Creator* creator, bool multi=false)
00074 {
00075 if(!multi && this->registry.find(key) != this->registry.end())
00076 return false;
00077 logFactoryRegister(gettypename(typeid(Object)), gettypename(creator->type()), key, multi);
00078
00079
00080 this->registry.insert(std::pair<Key, Creator*>(key, creator));
00081 return true;
00082 }
00083
00084 Object* createObject(Key key, Argument arg);
00085
00086 static Factory<Key, Object, Argument>* getInstance();
00087
00088 static Object* CreateObject(Key key, Argument arg)
00089 {
00090 return getInstance()->createObject(key, arg);
00091 }
00092
00093 typedef typename std::multimap<Key, Creator*>::iterator iterator;
00094 iterator begin() { return registry.begin(); }
00095 iterator end() { return registry.end(); }
00096 typedef typename std::multimap<Key, Creator*>::const_iterator const_iterator;
00097 const_iterator begin() const { return registry.begin(); }
00098 const_iterator end() const { return registry.end(); }
00099 };
00100
00101 template <class Factory, class RealObject>
00102 class Creator : public Factory::Creator, public Factory::Key
00103 {
00104 public:
00105 typedef typename Factory::Object Object;
00106 typedef typename Factory::Argument Argument;
00107 typedef typename Factory::Key Key;
00108 Creator(Key key, bool multi=false)
00109 : Key(key)
00110 {
00111 Factory::getInstance()->registerCreator(key, this, multi);
00112 }
00113 Object *createInstance(Argument arg)
00114 {
00115 RealObject* instance = NULL;
00116
00117 RealObject::create(instance, arg);
00118 return instance;
00119 }
00120 const std::type_info& type()
00121 {
00122 return typeid(RealObject);
00123 }
00124 };
00125
00127
00128
00129
00130
00131
00132
00133 template <class Factory, class RealObject>
00134 class CreatorFn : public Factory::Creator, public Factory::Key
00135 {
00136 public:
00137 typedef typename Factory::Object Object;
00138 typedef typename Factory::Argument Argument;
00139 typedef typename Factory::Key Key;
00140 typedef void Fn(RealObject*& obj, Argument arg);
00141 Fn* constructor;
00142
00143 CreatorFn(Key key, Fn* constructor, bool multi=false)
00144 : Key(key), constructor(constructor)
00145 {
00146 Factory::getInstance()->registerCreator(key, this, multi);
00147 }
00148
00149 Object *createInstance(Argument arg)
00150 {
00151 RealObject* instance = NULL;
00152 (*constructor)(instance, arg);
00153 return instance;
00154 }
00155 };
00156
00157
00158 }
00159
00160 }
00161
00162
00163 using sofa::helper::Creator;
00164
00165 #endif