pfactory.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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 #ifndef _PFACTORY_H
00114 #define _PFACTORY_H
00115
00116 #ifdef P_USE_PRAGMA
00117 #pragma interface
00118 #endif
00119
00120 #include <ptlib.h>
00121 #include <string>
00122 #include <map>
00123 #include <vector>
00124
00125 #if defined(_MSC_VER)
00126 #pragma warning(disable:4786)
00127 #endif
00128
00180
00181
00182 typedef std::string PDefaultPFactoryKey;
00183
00184
00192 class PFactoryBase
00193 {
00194 protected:
00195 PFactoryBase()
00196 { }
00197 public:
00198 virtual ~PFactoryBase()
00199 { }
00200
00201 class FactoryMap : public std::map<std::string, PFactoryBase *>
00202 {
00203 public:
00204 FactoryMap() { }
00205 ~FactoryMap();
00206 };
00207
00208 static FactoryMap & GetFactories();
00209 static PMutex & GetFactoriesMutex();
00210
00211 PMutex mutex;
00212
00213 private:
00214 PFactoryBase(const PFactoryBase &) {}
00215 void operator=(const PFactoryBase &) {}
00216 };
00217
00218
00221 template <class _Abstract_T, typename _Key_T = PDefaultPFactoryKey>
00222 class PFactory : PFactoryBase
00223 {
00224 public:
00225 typedef _Key_T Key_T;
00226 typedef _Abstract_T Abstract_T;
00227
00228 class WorkerBase
00229 {
00230 protected:
00231 WorkerBase(bool singleton = false)
00232 : isDynamic(false),
00233 isSingleton(singleton),
00234 singletonInstance(NULL),
00235 deleteSingleton(false)
00236 { }
00237 WorkerBase(Abstract_T * instance)
00238 : isDynamic(true),
00239 isSingleton(true),
00240 singletonInstance(instance),
00241 deleteSingleton(true)
00242 { }
00243
00244 virtual ~WorkerBase()
00245 {
00246 if (deleteSingleton)
00247 delete singletonInstance;
00248 }
00249
00250 Abstract_T * CreateInstance(const Key_T & key)
00251 {
00252 if (!isSingleton)
00253 return Create(key);
00254
00255 if (singletonInstance == NULL)
00256 singletonInstance = Create(key);
00257 return singletonInstance;
00258 }
00259
00260 virtual Abstract_T * Create(const Key_T & ) const { return singletonInstance; }
00261
00262 bool isDynamic;
00263 bool isSingleton;
00264 Abstract_T * singletonInstance;
00265 bool deleteSingleton;
00266
00267 friend class PFactory<_Abstract_T, _Key_T>;
00268 };
00269
00270 template <class _Concrete_T>
00271 class Worker : WorkerBase
00272 {
00273 public:
00274 Worker(const Key_T & key, bool singleton = false)
00275 : WorkerBase(singleton)
00276 {
00277 PFactory<_Abstract_T, _Key_T>::Register(key, this);
00278 }
00279
00280 protected:
00281 virtual Abstract_T * Create(const Key_T & ) const { return new _Concrete_T; }
00282 };
00283
00284 typedef std::map<_Key_T, WorkerBase *> KeyMap_T;
00285 typedef std::vector<_Key_T> KeyList_T;
00286
00287 static void Register(const _Key_T & key, WorkerBase * worker)
00288 {
00289 GetInstance().Register_Internal(key, worker);
00290 }
00291
00292 static void Register(const _Key_T & key, Abstract_T * instance)
00293 {
00294 GetInstance().Register_Internal(key, new WorkerBase(instance));
00295 }
00296
00297 static void Unregister(const _Key_T & key)
00298 {
00299 GetInstance().Unregister_Internal(key);
00300 }
00301
00302 static void UnregisterAll()
00303 {
00304 GetInstance().UnregisterAll_Internal();
00305 }
00306
00307 static bool IsRegistered(const _Key_T & key)
00308 {
00309 return GetInstance().IsRegistered_Internal(key);
00310 }
00311
00312 static _Abstract_T * CreateInstance(const _Key_T & key)
00313 {
00314 return GetInstance().CreateInstance_Internal(key);
00315 }
00316
00317 static BOOL IsSingleton(const _Key_T & key)
00318 {
00319 return GetInstance().IsSingleton_Internal(key);
00320 }
00321
00322 static KeyList_T GetKeyList()
00323 {
00324 return GetInstance().GetKeyList_Internal();
00325 }
00326
00327 static KeyMap_T & GetKeyMap()
00328 {
00329 return GetInstance().keyMap;
00330 }
00331
00332 static PMutex & GetMutex()
00333 {
00334 return GetInstance().mutex;
00335 }
00336
00337 protected:
00338 PFactory()
00339 { }
00340
00341 ~PFactory()
00342 {
00343 typename KeyMap_T::const_iterator entry;
00344 for (entry = keyMap.begin(); entry != keyMap.end(); ++entry) {
00345 if (entry->second->isDynamic)
00346 delete entry->second;
00347 }
00348 }
00349
00350 static PFactory & GetInstance()
00351 {
00352 std::string className = typeid(PFactory).name();
00353 PWaitAndSignal m(GetFactoriesMutex());
00354 FactoryMap & factories = GetFactories();
00355 FactoryMap::const_iterator entry = factories.find(className);
00356 if (entry != factories.end()) {
00357 PAssert(entry->second != NULL, "Factory map returned NULL for existing key");
00358 PFactoryBase * b = entry->second;
00359
00360
00361 return *(PFactory *)b;
00362 }
00363
00364 PFactory * factory = new PFactory;
00365 factories[className] = factory;
00366 return *factory;
00367 }
00368
00369
00370 void Register_Internal(const _Key_T & key, WorkerBase * worker)
00371 {
00372 PWaitAndSignal m(mutex);
00373 if (keyMap.find(key) == keyMap.end())
00374 keyMap[key] = worker;
00375 }
00376
00377 void Unregister_Internal(const _Key_T & key)
00378 {
00379 PWaitAndSignal m(mutex);
00380 keyMap.erase(key);
00381 }
00382
00383 void UnregisterAll_Internal()
00384 {
00385 PWaitAndSignal m(mutex);
00386 keyMap.erase(keyMap.begin(), keyMap.end());
00387 }
00388
00389 bool IsRegistered_Internal(const _Key_T & key)
00390 {
00391 PWaitAndSignal m(mutex);
00392 return keyMap.find(key) != keyMap.end();
00393 }
00394
00395 _Abstract_T * CreateInstance_Internal(const _Key_T & key)
00396 {
00397 PWaitAndSignal m(mutex);
00398 typename KeyMap_T::const_iterator entry = keyMap.find(key);
00399 if (entry != keyMap.end())
00400 return entry->second->CreateInstance(key);
00401 return NULL;
00402 }
00403
00404 bool IsSingleton_Internal(const _Key_T & key)
00405 {
00406 PWaitAndSignal m(mutex);
00407 if (keyMap.find(key) == keyMap.end())
00408 return false;
00409 return keyMap[key]->isSingleton;
00410 }
00411
00412 KeyList_T GetKeyList_Internal()
00413 {
00414 PWaitAndSignal m(mutex);
00415 KeyList_T list;
00416 typename KeyMap_T::const_iterator entry;
00417 for (entry = keyMap.begin(); entry != keyMap.end(); ++entry)
00418 list.push_back(entry->first);
00419 return list;
00420 }
00421
00422 KeyMap_T keyMap;
00423
00424 private:
00425 PFactory(const PFactory &) {}
00426 void operator=(const PFactory &) {}
00427 };
00428
00429
00430
00431
00432 #define PLOAD_FACTORY(AbstractType, KeyType) \
00433 PWLibFactoryLoader::AbstractType##_##KeyType##_loader = 1; \
00434
00435 #define PLOAD_FACTORY_DECLARE(AbstractType, KeyType) \
00436 namespace PWLibFactoryLoader { \
00437 extern int AbstractType##_##KeyType##_loader; \
00438 static class AbstractType##_##KeyType##_loader_Instantiate { \
00439 public: AbstractType##_##KeyType##_loader_Instantiate() { \
00440 PLOAD_FACTORY(AbstractType, KeyType); \
00441 } \
00442 } AbstractType##_##KeyType##_loader_instance; \
00443 }; \
00444
00445
00446
00447
00448
00449
00450 #define PINSTANTIATE_FACTORY(AbstractType, KeyType) \
00451 namespace PWLibFactoryLoader { int AbstractType##_##KeyType##_loader; }
00452
00453
00454 #endif // _PFACTORY_H