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 #ifndef _PFACTORY_H
00032 #define _PFACTORY_H
00033
00034 #ifdef P_USE_PRAGMA
00035 #pragma interface
00036 #endif
00037
00038 #ifndef _PTLIB_H
00039 #include <ptlib.h>
00040 #endif
00041
00042 #include <string>
00043 #include <map>
00044 #include <vector>
00045
00046 #if defined(_MSC_VER)
00047 #pragma warning(disable:4786)
00048 #endif
00049
00101
00102
00103 typedef std::string PDefaultPFactoryKey;
00104
00105
00113 class PFactoryBase
00114 {
00115 protected:
00116 PFactoryBase()
00117 { }
00118 public:
00119 virtual ~PFactoryBase()
00120 { }
00121
00122 class FactoryMap : public std::map<std::string, PFactoryBase *>
00123 {
00124 public:
00125 FactoryMap() { }
00126 ~FactoryMap();
00127 };
00128
00129 static FactoryMap & GetFactories();
00130 static PMutex & GetFactoriesMutex();
00131
00132 PMutex mutex;
00133
00134 private:
00135 PFactoryBase(const PFactoryBase &) {}
00136 void operator=(const PFactoryBase &) {}
00137 };
00138
00139
00142 template <class _Abstract_T, typename _Key_T = PDefaultPFactoryKey>
00143 class PFactory : PFactoryBase
00144 {
00145 public:
00146 typedef _Key_T Key_T;
00147 typedef _Abstract_T Abstract_T;
00148
00149 class WorkerBase
00150 {
00151 protected:
00152 WorkerBase(bool singleton = false)
00153 : isDynamic(false),
00154 isSingleton(singleton),
00155 singletonInstance(NULL),
00156 deleteSingleton(false)
00157 { }
00158 WorkerBase(Abstract_T * instance)
00159 : isDynamic(true),
00160 isSingleton(true),
00161 singletonInstance(instance),
00162 deleteSingleton(true)
00163 { }
00164
00165 virtual ~WorkerBase()
00166 {
00167 if (deleteSingleton)
00168 delete singletonInstance;
00169 }
00170
00171 Abstract_T * CreateInstance(const Key_T & key)
00172 {
00173 if (!isSingleton)
00174 return Create(key);
00175
00176 if (singletonInstance == NULL)
00177 singletonInstance = Create(key);
00178 return singletonInstance;
00179 }
00180
00181 virtual Abstract_T * Create(const Key_T & ) const { return singletonInstance; }
00182
00183 bool isDynamic;
00184 bool isSingleton;
00185 Abstract_T * singletonInstance;
00186 bool deleteSingleton;
00187
00188 friend class PFactory<_Abstract_T, _Key_T>;
00189 };
00190
00191 template <class _Concrete_T>
00192 class Worker : WorkerBase
00193 {
00194 public:
00195 Worker(const Key_T & key, bool singleton = false)
00196 : WorkerBase(singleton)
00197 {
00198 PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE;
00199 PFactory<_Abstract_T, _Key_T>::Register(key, this);
00200 }
00201
00202 protected:
00203 virtual Abstract_T * Create(const Key_T & ) const
00204 {
00205 #if PMEMORY_HEAP
00206
00207 PBoolean previousIgnoreAllocations = PMemoryHeap::SetIgnoreAllocations(isSingleton);
00208 #endif
00209 Abstract_T * instance = new _Concrete_T;
00210 #if PMEMORY_HEAP
00211 PMemoryHeap::SetIgnoreAllocations(previousIgnoreAllocations);
00212 #endif
00213 return instance;
00214 }
00215 };
00216
00217 typedef std::map<_Key_T, WorkerBase *> KeyMap_T;
00218 typedef std::vector<_Key_T> KeyList_T;
00219
00220 static void Register(const _Key_T & key, WorkerBase * worker)
00221 {
00222 GetInstance().Register_Internal(key, worker);
00223 }
00224
00225 static void Register(const _Key_T & key, Abstract_T * instance)
00226 {
00227 GetInstance().Register_Internal(key, PNEW WorkerBase(instance));
00228 }
00229
00230 static PBoolean RegisterAs(const _Key_T & newKey, const _Key_T & oldKey)
00231 {
00232 return GetInstance().RegisterAs_Internal(newKey, oldKey);
00233 }
00234
00235 static void Unregister(const _Key_T & key)
00236 {
00237 GetInstance().Unregister_Internal(key);
00238 }
00239
00240 static void UnregisterAll()
00241 {
00242 GetInstance().UnregisterAll_Internal();
00243 }
00244
00245 static bool IsRegistered(const _Key_T & key)
00246 {
00247 return GetInstance().IsRegistered_Internal(key);
00248 }
00249
00250 static _Abstract_T * CreateInstance(const _Key_T & key)
00251 {
00252 return GetInstance().CreateInstance_Internal(key);
00253 }
00254
00255 static PBoolean IsSingleton(const _Key_T & key)
00256 {
00257 return GetInstance().IsSingleton_Internal(key);
00258 }
00259
00260 static KeyList_T GetKeyList()
00261 {
00262 return GetInstance().GetKeyList_Internal();
00263 }
00264
00265 static KeyMap_T & GetKeyMap()
00266 {
00267 return GetInstance().keyMap;
00268 }
00269
00270 static PMutex & GetMutex()
00271 {
00272 return GetInstance().mutex;
00273 }
00274
00275 protected:
00276 PFactory()
00277 { }
00278
00279 ~PFactory()
00280 {
00281 typename KeyMap_T::const_iterator entry;
00282 for (entry = keyMap.begin(); entry != keyMap.end(); ++entry) {
00283 if (entry->second->isDynamic)
00284 delete entry->second;
00285 }
00286 }
00287
00288 static PFactory & GetInstance()
00289 {
00290 std::string className = typeid(PFactory).name();
00291 PWaitAndSignal m(GetFactoriesMutex());
00292 FactoryMap & factories = GetFactories();
00293 FactoryMap::const_iterator entry = factories.find(className);
00294 if (entry != factories.end()) {
00295 PAssert(entry->second != NULL, "Factory map returned NULL for existing key");
00296 PFactoryBase * b = entry->second;
00297
00298
00299 return *(PFactory *)b;
00300 }
00301
00302 PMEMORY_IGNORE_ALLOCATIONS_FOR_SCOPE;
00303 PFactory * factory = new PFactory;
00304 factories[className] = factory;
00305 return *factory;
00306 }
00307
00308
00309 void Register_Internal(const _Key_T & key, WorkerBase * worker)
00310 {
00311 PWaitAndSignal m(mutex);
00312 if (keyMap.find(key) == keyMap.end())
00313 keyMap[key] = worker;
00314 }
00315
00316 PBoolean RegisterAs_Internal(const _Key_T & newKey, const _Key_T & oldKey)
00317 {
00318 PWaitAndSignal m(mutex);
00319 if (keyMap.find(oldKey) == keyMap.end())
00320 return PFalse;
00321 keyMap[newKey] = keyMap[oldKey];
00322 return PTrue;
00323 }
00324
00325 void Unregister_Internal(const _Key_T & key)
00326 {
00327 PWaitAndSignal m(mutex);
00328 keyMap.erase(key);
00329 }
00330
00331 void UnregisterAll_Internal()
00332 {
00333 PWaitAndSignal m(mutex);
00334 keyMap.erase(keyMap.begin(), keyMap.end());
00335 }
00336
00337 bool IsRegistered_Internal(const _Key_T & key)
00338 {
00339 PWaitAndSignal m(mutex);
00340 return keyMap.find(key) != keyMap.end();
00341 }
00342
00343 _Abstract_T * CreateInstance_Internal(const _Key_T & key)
00344 {
00345 PWaitAndSignal m(mutex);
00346 typename KeyMap_T::const_iterator entry = keyMap.find(key);
00347 if (entry != keyMap.end())
00348 return entry->second->CreateInstance(key);
00349 return NULL;
00350 }
00351
00352 bool IsSingleton_Internal(const _Key_T & key)
00353 {
00354 PWaitAndSignal m(mutex);
00355 if (keyMap.find(key) == keyMap.end())
00356 return false;
00357 return keyMap[key]->isSingleton;
00358 }
00359
00360 KeyList_T GetKeyList_Internal()
00361 {
00362 PWaitAndSignal m(mutex);
00363 KeyList_T list;
00364 typename KeyMap_T::const_iterator entry;
00365 for (entry = keyMap.begin(); entry != keyMap.end(); ++entry)
00366 list.push_back(entry->first);
00367 return list;
00368 }
00369
00370 KeyMap_T keyMap;
00371
00372 private:
00373 PFactory(const PFactory &) {}
00374 void operator=(const PFactory &) {}
00375 };
00376
00377
00378
00379
00380 #define PLOAD_FACTORY(AbstractType, KeyType) \
00381 namespace PWLibFactoryLoader { \
00382 extern int AbstractType##_##KeyType##_loader; \
00383 static int AbstractType##_##KeyType##_loader_instance = AbstractType##_##KeyType##_loader; \
00384 };
00385
00386
00387
00388
00389
00390
00391 #define PINSTANTIATE_FACTORY(AbstractType, KeyType) \
00392 namespace PWLibFactoryLoader { int AbstractType##_##KeyType##_loader; }
00393
00394
00395 #endif // _PFACTORY_H