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