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