OpenRTM
1.0.0
|
00001 // -*- C++ -*- 00020 #ifndef COIL_FACTORY_H 00021 #define COIL_FACTORY_H 00022 00023 #include <string> 00024 #include <map> 00025 #include <algorithm> 00026 #include <vector> 00027 #include <coil/Singleton.h> 00028 00029 // for Windows DLL export 00030 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) 00031 # ifdef LIBRARY_EXPORTS 00032 # define EXTERN 00033 # define DLL_PLUGIN __declspec(dllexport) 00034 # else 00035 # define EXTERN extern 00036 # define DLL_PLUGIN __declspec(dllimport) 00037 # endif 00038 #else 00039 # define DLL_PLUGIN 00040 # define EXTERN 00041 #endif /* Windows */ 00042 00043 00044 namespace coil 00045 { 00057 template <class AbstractClass, class ConcreteClass> 00058 AbstractClass* Creator() 00059 { 00060 return new ConcreteClass(); 00061 } 00062 00074 template <class AbstractClass, class ConcreteClass> 00075 void Destructor(AbstractClass*& obj) 00076 { 00077 if (obj == 0) { return; } 00078 ConcreteClass* tmp = dynamic_cast<ConcreteClass*>(obj); 00079 if (tmp == 0) { return; } 00080 delete obj; 00081 obj = 0; 00082 } 00083 00097 template < 00098 class AbstractClass, 00099 typename Identifier = std::string, 00100 typename Compare = std::less<Identifier>, 00101 typename Creator = AbstractClass* (*)(), 00102 typename Destructor = void (*)(AbstractClass*&) 00103 > 00104 class Factory 00105 { 00106 class FactoryEntry; 00107 public: 00108 00109 typedef std::map<Identifier, FactoryEntry> FactoryMap; 00110 typedef typename FactoryMap::iterator FactoryMapIt; 00111 00112 enum ReturnCode 00113 { 00114 FACTORY_OK, 00115 FACTORY_ERROR, 00116 ALREADY_EXISTS, 00117 NOT_FOUND, 00118 INVALID_ARG, 00119 UNKNOWN_ERROR 00120 }; 00121 00145 bool hasFactory(const Identifier& id) 00146 { 00147 if (m_creators.count(id) == 0) { return false; } 00148 return true; 00149 } 00150 00170 std::vector<Identifier> getIdentifiers() 00171 { 00172 std::vector<Identifier> idlist; 00173 idlist.reserve(m_creators.size()); 00174 00175 FactoryMapIt it(m_creators.begin()); 00176 FactoryMapIt it_end(m_creators.end()); 00177 00178 while (it != it_end) 00179 { 00180 idlist.push_back(it->first); 00181 ++it; 00182 } 00183 return idlist; 00184 } 00185 00217 ReturnCode addFactory(const Identifier& id, 00218 Creator creator, 00219 Destructor destructor) 00220 { 00221 if (creator == 0 || destructor == 0) { return INVALID_ARG; } 00222 if (m_creators.count(id) != 0) { return ALREADY_EXISTS; } 00223 FactoryEntry f(creator, destructor); 00224 m_creators[id] = f; 00225 return FACTORY_OK; 00226 } 00227 00253 ReturnCode removeFactory(const Identifier& id) 00254 { 00255 if (m_creators.count(id) == 0) { return NOT_FOUND; } 00256 00257 m_creators.erase(id); 00258 return FACTORY_OK; 00259 } 00260 00284 AbstractClass* createObject(const Identifier& id) 00285 { 00286 if (m_creators.count(id) == 0) { return 0; } 00287 return m_creators[id].creator_(); 00288 } 00289 00311 void deleteObject(const Identifier& id, AbstractClass*& obj) 00312 { 00313 if (m_creators.count(id) == 0) { return; } 00314 m_creators[id].destructor_(obj); 00315 } 00316 00336 void deleteObject(AbstractClass*& obj) 00337 { 00338 FactoryMapIt it(m_creators.begin()); 00339 FactoryMapIt it_end(m_creators.end()); 00340 00341 while (it != it_end) 00342 { 00343 it->second.destructor_(obj); 00344 ++it; 00345 } 00346 } 00347 00348 private: 00349 00363 class FactoryEntry 00364 { 00365 public: 00366 explicit FactoryEntry() 00367 { 00368 } 00369 00391 FactoryEntry(Creator creator, Destructor destructor) 00392 : creator_(creator), destructor_(destructor) 00393 { 00394 } 00395 Creator creator_; 00396 Destructor destructor_; 00397 }; 00398 FactoryMap m_creators; 00399 }; 00400 00401 00402 00416 template < 00417 class AbstractClass, 00418 typename Identifier = std::string, 00419 typename Compare = std::less<Identifier>, 00420 typename Creator = AbstractClass* (*)(), 00421 typename Destructor = void (*)(AbstractClass*&) 00422 > 00423 class GlobalFactory 00424 : public Factory<AbstractClass, Identifier, Compare, Creator, Destructor>, 00425 public coil::Singleton<GlobalFactory<AbstractClass, 00426 Identifier, 00427 Compare, 00428 Creator, 00429 Destructor> > 00430 { 00431 public: 00432 00433 private: 00449 GlobalFactory(){} 00450 00466 ~GlobalFactory(){} 00467 00468 friend class Singleton<GlobalFactory>; 00469 }; 00470 00471 }; // namespace coil 00472 #endif // COIL_FACTORY_H