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_CORE_OBJECTFACTORY_H
00028 #define SOFA_CORE_OBJECTFACTORY_H
00029
00030 #include <sofa/helper/system/config.h>
00031 #include <sofa/core/objectmodel/BaseObjectDescription.h>
00032 #include <sofa/core/objectmodel/BaseContext.h>
00033 #include <sofa/core/objectmodel/ContextObject.h>
00034 #include <sofa/core/VisualModel.h>
00035 #include <sofa/core/BehaviorModel.h>
00036 #include <sofa/core/CollisionModel.h>
00037 #include <sofa/core/BaseMapping.h>
00038 #include <sofa/core/componentmodel/topology/TopologicalMapping.h>
00039 #include <sofa/core/componentmodel/behavior/BaseMechanicalState.h>
00040 #include <sofa/core/componentmodel/behavior/BaseForceField.h>
00041 #include <sofa/core/componentmodel/behavior/InteractionForceField.h>
00042 #include <sofa/core/componentmodel/behavior/BaseConstraint.h>
00043 #include <sofa/core/componentmodel/behavior/BaseMechanicalMapping.h>
00044 #include <sofa/core/componentmodel/behavior/BaseMass.h>
00045 #include <sofa/core/componentmodel/behavior/OdeSolver.h>
00046 #include <sofa/core/componentmodel/behavior/LinearSolver.h>
00047 #include <sofa/core/componentmodel/behavior/MasterSolver.h>
00048 #include <sofa/core/componentmodel/topology/Topology.h>
00049 #include <sofa/core/componentmodel/topology/BaseTopologyObject.h>
00050 #include <sofa/core/componentmodel/behavior/BaseController.h>
00051
00052 #include <map>
00053 #include <iostream>
00054 #include <typeinfo>
00055
00056 namespace sofa
00057 {
00058
00059 namespace core
00060 {
00061
00074 class ObjectFactory
00075 {
00076 public:
00077
00079 class Creator
00080 {
00081 public:
00082 virtual ~Creator() { }
00086 virtual bool canCreate(objectmodel::BaseContext* context, objectmodel::BaseObjectDescription* arg) = 0;
00087
00091 virtual objectmodel::BaseObject* createInstance(objectmodel::BaseContext* context, objectmodel::BaseObjectDescription* arg) = 0;
00092
00094 virtual const std::type_info& type() = 0;
00095 };
00096
00098 class ClassEntry
00099 {
00100 public:
00101 std::string className;
00102 std::set<std::string> baseClasses;
00103 std::set<std::string> aliases;
00104 std::string description;
00105 std::string authors;
00106 std::string license;
00107 std::string defaultTemplate;
00108 std::list< std::pair<std::string, Creator*> > creatorList;
00109 std::map<std::string, Creator*> creatorMap;
00110
00111 };
00112
00113 protected:
00114
00116 std::map<std::string,ClassEntry*> registry;
00117
00118 public:
00119
00121 ClassEntry* getEntry(std::string classname);
00122
00124 void getAllEntries(std::vector<ClassEntry*>& result);
00125
00132 bool addAlias(std::string name, std::string result, bool force=false, ClassEntry** previous = NULL);
00133
00138 void resetAlias(std::string name, ClassEntry* previous);
00139
00141 objectmodel::BaseObject* createObject(objectmodel::BaseContext* context, objectmodel::BaseObjectDescription* arg);
00142
00144 static ObjectFactory* getInstance();
00145
00147 static objectmodel::BaseObject* CreateObject(objectmodel::BaseContext* context, objectmodel::BaseObjectDescription* arg)
00148 {
00149 return getInstance()->createObject(context, arg);
00150 }
00151
00153 static bool AddAlias(std::string name, std::string result, bool force=false, ClassEntry** previous = NULL)
00154 {
00155 return getInstance()->addAlias(name, result, force, previous);
00156 }
00157
00159 static void ResetAlias(std::string name, ClassEntry* previous)
00160 {
00161 getInstance()->resetAlias(name, previous);
00162 }
00163
00165 void dump(std::ostream& out = std::cout);
00166
00168 void dumpXML(std::ostream& out = std::cout);
00169
00171 void dumpHTML(std::ostream& out = std::cout);
00172 };
00173
00177 template<class RealObject>
00178 class ObjectCreator : public ObjectFactory::Creator
00179 {
00180 public:
00181 bool canCreate(objectmodel::BaseContext* context, objectmodel::BaseObjectDescription* arg)
00182 {
00183 RealObject* instance = NULL;
00184 return RealObject::canCreate(instance, context, arg);
00185 }
00186 objectmodel::BaseObject *createInstance(objectmodel::BaseContext* context, objectmodel::BaseObjectDescription* arg)
00187 {
00188 RealObject* instance = NULL;
00189 RealObject::create(instance, context, arg);
00190 return instance;
00191 }
00192 const std::type_info& type()
00193 {
00194 return typeid(RealObject);
00195 }
00196 };
00197
00216 class RegisterObject
00217 {
00218 protected:
00220 ObjectFactory::ClassEntry entry;
00221 public:
00222
00224 RegisterObject(const std::string& description);
00225
00227 RegisterObject& addAlias(std::string val);
00228
00230 RegisterObject& addDescription(std::string val);
00231
00233 RegisterObject& addAuthor(std::string val);
00234
00236 RegisterObject& addLicense(std::string val);
00237
00241 RegisterObject& addCreator(std::string classname, std::string templatename, ObjectFactory::Creator* creator);
00242
00246 template <class T, class U>
00247 class Conversion
00248 {
00249 typedef char Small;
00250 class Big {char dummy[2];};
00251 static Small Test(U*);
00252 static Big Test(...);
00253 static T* MakeT();
00254 public:
00255 enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };
00256 static int Exists() { return exists; }
00257 };
00258
00261 template<class RealClass, class BaseClass>
00262 bool implements()
00263 {
00264 bool res = Conversion<RealClass, BaseClass>::exists;
00265
00266
00267
00268
00269
00270
00271 return res;
00272 }
00273
00277 template<class RealObject>
00278 RegisterObject& add(bool defaultTemplate=false)
00279 {
00280 RealObject* p = NULL;
00281 std::string classname = RealObject::className(p);
00282 std::string templatename = RealObject::templateName(p);
00283
00284 if (defaultTemplate)
00285 entry.defaultTemplate = templatename;
00286
00287
00288
00289
00290 if (implements<RealObject,objectmodel::ContextObject>())
00291 entry.baseClasses.insert("ContextObject");
00292 if (implements<RealObject,VisualModel>())
00293 entry.baseClasses.insert("VisualModel");
00294 if (implements<RealObject,BehaviorModel>())
00295 entry.baseClasses.insert("BehaviorModel");
00296 if (implements<RealObject,CollisionModel>())
00297 entry.baseClasses.insert("CollisionModel");
00298 if (implements<RealObject,core::componentmodel::behavior::BaseMechanicalState>())
00299 entry.baseClasses.insert("MechanicalState");
00300 if (implements<RealObject,core::componentmodel::behavior::BaseForceField>())
00301 entry.baseClasses.insert("ForceField");
00302 if (implements<RealObject,core::componentmodel::behavior::InteractionForceField>())
00303 entry.baseClasses.insert("InteractionForceField");
00304 if (implements<RealObject,core::componentmodel::behavior::BaseConstraint>())
00305 entry.baseClasses.insert("Constraint");
00306 if (implements<RealObject,core::BaseMapping>())
00307 entry.baseClasses.insert("Mapping");
00308 if (implements<RealObject,core::componentmodel::behavior::BaseMechanicalMapping>())
00309 entry.baseClasses.insert("MechanicalMapping");
00310 if (implements<RealObject,core::componentmodel::topology::TopologicalMapping>())
00311 entry.baseClasses.insert("TopologicalMapping");
00312 if (implements<RealObject,core::componentmodel::behavior::BaseMass>())
00313 entry.baseClasses.insert("Mass");
00314 if (implements<RealObject,core::componentmodel::behavior::OdeSolver>())
00315 entry.baseClasses.insert("OdeSolver");
00316 if (implements<RealObject,core::componentmodel::behavior::LinearSolver>())
00317 entry.baseClasses.insert("Linear Solver");
00318 if (implements<RealObject,core::componentmodel::behavior::MasterSolver>())
00319 entry.baseClasses.insert("MasterSolver");
00320 if (implements<RealObject,core::componentmodel::topology::Topology>())
00321 entry.baseClasses.insert("Topology");
00322 if (implements<RealObject,core::componentmodel::topology::BaseTopologyObject>())
00323 entry.baseClasses.insert("TopologyObject");
00324 if (implements<RealObject,core::componentmodel::behavior::BaseController>())
00325 entry.baseClasses.insert("Controller");
00326
00327
00328
00329
00330 return addCreator(classname, templatename, new ObjectCreator<RealObject>);
00331 }
00332
00334 operator int();
00335 };
00336
00337 }
00338
00339 }
00340
00341 #endif