00001
00020 #ifndef COIL_FACTORY_H
00021 #define COIL_FACTORY_H
00022
00023 #include <assert.h>
00024 #include <string>
00025 #include <map>
00026 #include <algorithm>
00027 #include <vector>
00028 #include <coil/Singleton.h>
00029
00030
00031 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
00032 # ifdef LIBRARY_EXPORTS
00033 # define EXTERN
00034 # define DLL_PLUGIN __declspec(dllexport)
00035 # else
00036 # define EXTERN extern
00037 # define DLL_PLUGIN __declspec(dllimport)
00038 # endif
00039 #else
00040 # define DLL_PLUGIN
00041 # define EXTERN
00042 #endif
00043
00044
00045 namespace coil
00046 {
00058 template <class AbstractClass, class ConcreteClass>
00059 AbstractClass* Creator()
00060 {
00061 return new ConcreteClass();
00062 }
00063
00075 template <class AbstractClass, class ConcreteClass>
00076 void Destructor(AbstractClass*& obj)
00077 {
00078 if (obj == 0) { return; }
00079 ConcreteClass* tmp = dynamic_cast<ConcreteClass*>(obj);
00080 if (tmp == 0) { return; }
00081 delete obj;
00082 obj = 0;
00083 }
00084
00098 template <
00099 class AbstractClass,
00100 typename Identifier = std::string,
00101 typename Compare = std::less<Identifier>,
00102 typename Creator = AbstractClass* (*)(),
00103 typename Destructor = void (*)(AbstractClass*&)
00104 >
00105 class Factory
00106 {
00107 class FactoryEntry;
00108 public:
00109
00110 typedef std::map<Identifier, FactoryEntry> FactoryMap;
00111 typedef typename FactoryMap::iterator FactoryMapIt;
00112 typedef std::map<AbstractClass*, FactoryEntry> ObjectMap;
00113 typedef typename ObjectMap::iterator ObjectMapIt;
00114
00115 enum ReturnCode
00116 {
00117 FACTORY_OK,
00118 FACTORY_ERROR,
00119 ALREADY_EXISTS,
00120 NOT_FOUND,
00121 INVALID_ARG,
00122 UNKNOWN_ERROR
00123 };
00124
00148 bool hasFactory(const Identifier& id)
00149 {
00150 if (m_creators.count(id) == 0) { return false; }
00151 return true;
00152 }
00153
00173 std::vector<Identifier> getIdentifiers()
00174 {
00175 std::vector<Identifier> idlist;
00176 idlist.reserve(m_creators.size());
00177
00178 FactoryMapIt it(m_creators.begin());
00179 FactoryMapIt it_end(m_creators.end());
00180
00181 while (it != it_end)
00182 {
00183 idlist.push_back(it->first);
00184 ++it;
00185 }
00186 return idlist;
00187 }
00188
00220 ReturnCode addFactory(const Identifier& id,
00221 Creator creator,
00222 Destructor destructor)
00223 {
00224 if (creator == 0 || destructor == 0) { return INVALID_ARG; }
00225 if (m_creators.count(id) != 0) { return ALREADY_EXISTS; }
00226 FactoryEntry f(id, creator, destructor);
00227 m_creators[id] = f;
00228 return FACTORY_OK;
00229 }
00230
00256 ReturnCode removeFactory(const Identifier& id)
00257 {
00258 if (m_creators.count(id) == 0) { return NOT_FOUND; }
00259 m_creators.erase(id);
00260 return FACTORY_OK;
00261 }
00262
00286 AbstractClass* createObject(const Identifier& id)
00287 {
00288 if (m_creators.count(id) == 0) { return 0; }
00289 AbstractClass* obj = m_creators[id].creator_();
00290 assert(m_objects.count(obj) == 0);
00291 m_objects[obj] = m_creators[id];
00292 return obj;
00293 }
00294
00316 ReturnCode deleteObject(const Identifier& id, AbstractClass*& obj)
00317 {
00318 if (m_creators.count(id) == 0)
00319 {
00320 return deleteObject(obj);
00321 }
00322 m_creators[id].destructor_(obj);
00323 m_objects.erase(obj);
00324 return FACTORY_OK;
00325 }
00326
00346 ReturnCode deleteObject(AbstractClass*& obj)
00347 {
00348 if (m_objects.count(obj) == 0) { return NOT_FOUND; }
00349 AbstractClass* tmp(obj);
00350 m_objects[obj].destructor_(obj);
00351 m_objects.erase(tmp);
00352 return FACTORY_OK;
00353 }
00354
00374 std::vector<AbstractClass*> createdObjects()
00375 {
00376 std::vector<AbstractClass*> objects;
00377 for (ObjectMapIt it(m_objects.begin()); it != m_objects.end(); ++it)
00378 {
00379 objects.push_back(it->first);
00380 }
00381 return objects;
00382 }
00383
00405 bool isProducerOf(AbstractClass* obj)
00406 {
00407 return m_objects.count(obj) != 0;
00408 }
00409
00433 ReturnCode objectToIdentifier(AbstractClass* obj, Identifier& id)
00434 {
00435 if (m_objects.count(obj) == 0) { return NOT_FOUND; }
00436 id = m_objects[obj].id_;
00437 return FACTORY_OK;
00438 }
00439
00465 Creator objectToCreator(AbstractClass* obj)
00466 {
00467 return m_objects[obj].creator_;
00468 }
00469
00495 Destructor objectToDestructor(AbstractClass* obj)
00496 {
00497 return m_objects[obj].destructor_;
00498 }
00499
00500 private:
00501
00515 class FactoryEntry
00516 {
00517 public:
00518 explicit FactoryEntry()
00519 {
00520 }
00521
00543 FactoryEntry(Identifier id, Creator creator, Destructor destructor)
00544 : id_(id), creator_(creator), destructor_(destructor)
00545 {
00546 }
00547 std::string id_;
00548 Creator creator_;
00549 Destructor destructor_;
00550 };
00551 FactoryMap m_creators;
00552 ObjectMap m_objects;
00553 };
00554
00555
00556
00570 template <
00571 class AbstractClass,
00572 typename Identifier = std::string,
00573 typename Compare = std::less<Identifier>,
00574 typename Creator = AbstractClass* (*)(),
00575 typename Destructor = void (*)(AbstractClass*&)
00576 >
00577 class GlobalFactory
00578 : public Factory<AbstractClass, Identifier, Compare, Creator, Destructor>,
00579 public coil::Singleton<GlobalFactory<AbstractClass,
00580 Identifier,
00581 Compare,
00582 Creator,
00583 Destructor> >
00584 {
00585 public:
00586
00587 private:
00603 GlobalFactory(){}
00604
00620 ~GlobalFactory(){}
00621
00622 friend class Singleton<GlobalFactory>;
00623 };
00624
00625 };
00626 #endif // COIL_FACTORY_H