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 #ifndef _PFACTORY_H
00105 #define _PFACTORY_H
00106
00107 #ifdef P_USE_PRAGMA
00108 #pragma interface
00109 #endif
00110
00111 #include <ptlib.h>
00112 #include <string>
00113 #include <map>
00114 #include <vector>
00115
00116 #if defined(_MSC_VER)
00117 #pragma warning(disable:4786)
00118 #endif
00119
00178 class PFactoryBase
00179 {
00180 protected:
00181 PFactoryBase()
00182 { }
00183 public:
00184 virtual ~PFactoryBase()
00185 { }
00186
00187 class FactoryMap : public std::map<std::string, PFactoryBase *>
00188 {
00189 public:
00190 FactoryMap() { }
00191 ~FactoryMap();
00192 };
00193
00194 static FactoryMap & GetFactories();
00195 static PMutex & GetFactoriesMutex();
00196
00197 PMutex mutex;
00198
00199 private:
00200 PFactoryBase(const PFactoryBase &) {}
00201 void operator=(const PFactoryBase &) {}
00202 };
00203
00204
00207 template <class _Abstract_T, typename _Key_T = PString>
00208 class PFactory : PFactoryBase
00209 {
00210 public:
00211 typedef _Key_T Key_T;
00212 typedef _Abstract_T Abstract_T;
00213
00214 class WorkerBase
00215 {
00216 protected:
00217 WorkerBase(bool singleton = false)
00218 : isDynamic(false),
00219 isSingleton(singleton),
00220 singletonInstance(NULL),
00221 deleteSingleton(false)
00222 { }
00223 WorkerBase(Abstract_T * instance)
00224 : isDynamic(true),
00225 isSingleton(true),
00226 singletonInstance(instance),
00227 deleteSingleton(true)
00228 { }
00229
00230 virtual ~WorkerBase()
00231 {
00232 if (deleteSingleton)
00233 delete singletonInstance;
00234 }
00235
00236 Abstract_T * CreateInstance(const Key_T & key)
00237 {
00238 if (!isSingleton)
00239 return Create(key);
00240
00241 if (singletonInstance == NULL)
00242 singletonInstance = Create(key);
00243 return singletonInstance;
00244 }
00245
00246 virtual Abstract_T * Create(const Key_T & ) const { return singletonInstance; }
00247
00248 bool isDynamic;
00249 bool isSingleton;
00250 Abstract_T * singletonInstance;
00251 bool deleteSingleton;
00252
00253 friend class PFactory<_Abstract_T, _Key_T>;
00254 };
00255
00256 template <class _Concrete_T>
00257 class Worker : WorkerBase
00258 {
00259 public:
00260 Worker(const Key_T & key, bool singleton = false)
00261 : WorkerBase(singleton)
00262 {
00263 PFactory<_Abstract_T, _Key_T>::Register(key, this);
00264 }
00265
00266 protected:
00267 virtual Abstract_T * Create(const Key_T & ) const { return new _Concrete_T; }
00268 };
00269
00270 typedef std::map<_Key_T, WorkerBase *> KeyMap_T;
00271 typedef std::vector<_Key_T> KeyList_T;
00272
00273 static void Register(const _Key_T & key, WorkerBase * worker)
00274 {
00275 GetInstance().Register_Internal(key, worker);
00276 }
00277
00278 static void Register(const _Key_T & key, Abstract_T * instance)
00279 {
00280 GetInstance().Register_Internal(key, new WorkerBase(instance));
00281 }
00282
00283 static void Unregister(const _Key_T & key)
00284 {
00285 GetInstance().Unregister_Internal(key);
00286 }
00287
00288 static void UnregisterAll()
00289 {
00290 GetInstance().UnregisterAll_Internal();
00291 }
00292
00293 static bool IsRegistered(const _Key_T & key)
00294 {
00295 return GetInstance().IsRegistered_Internal(key);
00296 }
00297
00298 static _Abstract_T * CreateInstance(const _Key_T & key)
00299 {
00300 return GetInstance().CreateInstance_Internal(key);
00301 }
00302
00303 static BOOL IsSingleton(const _Key_T & key)
00304 {
00305 return GetInstance().IsSingleton_Internal(key);
00306 }
00307
00308 static KeyList_T GetKeyList()
00309 {
00310 return GetInstance().GetKeyList_Internal();
00311 }
00312
00313 static KeyMap_T & GetKeyMap()
00314 {
00315 return GetInstance().keyMap;
00316 }
00317
00318 static PMutex & GetMutex()
00319 {
00320 return GetInstance().mutex;
00321 }
00322
00323 protected:
00324 PFactory()
00325 { }
00326
00327 ~PFactory()
00328 {
00329 typename KeyMap_T::const_iterator entry;
00330 for (entry = keyMap.begin(); entry != keyMap.end(); ++entry) {
00331 if (entry->second->isDynamic)
00332 delete entry->second;
00333 }
00334 }
00335
00336 static PFactory & GetInstance()
00337 {
00338 std::string className = typeid(PFactory).name();
00339 PWaitAndSignal m(GetFactoriesMutex());
00340 FactoryMap & factories = GetFactories();
00341 FactoryMap::const_iterator entry = factories.find(className);
00342 if (entry != factories.end()) {
00343 PAssert(entry->second != NULL, "Factory map returned NULL for existing key");
00344 PFactoryBase * b = entry->second;
00345
00346
00347 return *(PFactory *)b;
00348 }
00349
00350 PFactory * factory = new PFactory;
00351 factories[className] = factory;
00352 return *factory;
00353 }
00354
00355
00356 void Register_Internal(const _Key_T & key, WorkerBase * worker)
00357 {
00358 PWaitAndSignal m(mutex);
00359 if (keyMap.find(key) == keyMap.end())
00360 keyMap[key] = worker;
00361 }
00362
00363 void Unregister_Internal(const _Key_T & key)
00364 {
00365 PWaitAndSignal m(mutex);
00366 keyMap.erase(key);
00367 }
00368
00369 void UnregisterAll_Internal()
00370 {
00371 PWaitAndSignal m(mutex);
00372 keyMap.erase(keyMap.begin(), keyMap.end());
00373 }
00374
00375 bool IsRegistered_Internal(const _Key_T & key)
00376 {
00377 PWaitAndSignal m(mutex);
00378 return keyMap.find(key) != keyMap.end();
00379 }
00380
00381 _Abstract_T * CreateInstance_Internal(const _Key_T & key)
00382 {
00383 PWaitAndSignal m(mutex);
00384 typename KeyMap_T::const_iterator entry = keyMap.find(key);
00385 if (entry != keyMap.end())
00386 return entry->second->CreateInstance(key);
00387 return NULL;
00388 }
00389
00390 bool IsSingleton_Internal(const _Key_T & key)
00391 {
00392 PWaitAndSignal m(mutex);
00393 if (keyMap.find(key) == keyMap.end())
00394 return false;
00395 return keyMap[key]->isSingleton;
00396 }
00397
00398 KeyList_T GetKeyList_Internal()
00399 {
00400 PWaitAndSignal m(mutex);
00401 KeyList_T list;
00402 typename KeyMap_T::const_iterator entry;
00403 for (entry = keyMap.begin(); entry != keyMap.end(); ++entry)
00404 list.push_back(entry->first);
00405 return list;
00406 }
00407
00408 KeyMap_T keyMap;
00409
00410 private:
00411 PFactory(const PFactory &) {}
00412 void operator=(const PFactory &) {}
00413 };
00414
00415
00416
00417
00418 #define PLOAD_FACTORY_DECLARE(AbstractType, KeyType) \
00419 namespace PWLibFactoryLoader { extern int AbstractType##_##KeyType; }
00420
00421 #define PLOAD_FACTORY(AbstractType, KeyType) \
00422 PWLibFactoryLoader::AbstractType##_##KeyType = 1;
00423
00424
00425
00426
00427
00428 #define PINSTANTIATE_FACTORY(AbstractType, KeyType) \
00429 namespace PWLibFactoryLoader { int AbstractType##_##KeyType; };
00430
00431 #endif // _PFACTORY_H