00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef RESOURCE_H
00025 #define RESOURCE_H
00026
00027 #include "parametersettable.h"
00028 #include "configurationconfig.h"
00029 #include "configurationexceptions.h"
00030 #include <QMap>
00031 #include <QString>
00032 #include <QMutex>
00033 #include <QSet>
00034
00035 class QObject;
00036
00037 namespace farsa {
00038
00039 class ResourceHandler;
00040 class ResourceCollection;
00041 class ResourcesUser;
00042
00056 class FARSA_CONF_TEMPLATE Resource
00057 {
00058 public:
00062 enum ResourceChangeType {
00063 Created,
00064 Modified,
00065 Deleted
00066 };
00067
00068 public:
00072 virtual ~Resource()
00073 {
00074 }
00075 };
00076
00084 class FARSA_CONF_API ResourceMutexHolder
00085 {
00086 public:
00090 ResourceMutexHolder();
00091
00098 ResourceMutexHolder(const ResourceMutexHolder& other) throw();
00099
00106 ResourceMutexHolder& operator=(const ResourceMutexHolder& other) throw();
00107
00111 ~ResourceMutexHolder() throw();
00112
00121 bool operator==(const ResourceMutexHolder& other) const throw()
00122 {
00123 return (m_shared == other.m_shared);
00124 }
00125
00131 QMutex& operator*() const throw()
00132 {
00133 return m_shared->resourceLock;
00134 }
00135
00142 QMutex* operator->() const throw()
00143 {
00144 return &(m_shared->resourceLock);
00145 }
00146
00147 private:
00152 struct MutexAndRefCounter
00153 {
00157 MutexAndRefCounter() :
00158 resourceLock(QMutex::Recursive),
00159 referenceCounter(0)
00160 {
00161 }
00162
00166 QMutex resourceLock;
00167
00171 int referenceCounter;
00172 };
00173
00177 MutexAndRefCounter* m_shared;
00178 };
00179
00189 class FARSA_CONF_API ResourceHandler
00190 {
00191 public:
00199 ResourceHandler(QString name);
00200
00204 ~ResourceHandler();
00205
00211 QString name() const
00212 {
00213 return m_name;
00214 }
00215
00225 void shareLockWith(ResourceHandler* other);
00226
00233 void set(int* res);
00234
00241 void set(float* res);
00242
00249 void set(double* res);
00250
00257 void set(bool* res);
00258
00265 void set(Resource* res);
00266
00273 void set(ParameterSettable* res);
00274
00281 void set(QObject* res);
00282
00288 void unset();
00289
00297 template<class T>
00298 T* get() const
00299 {
00300 switch(m_type) {
00301 case t_resource:
00302 return dynamic_cast<T*>(m_pointers.res);
00303 case t_paramSettable:
00304 return dynamic_cast<T*>(m_pointers.par);
00305 case t_qObject:
00306 return dynamic_cast<T*>(m_pointers.obj);
00307 default:
00308 return NULL;
00309 }
00310 }
00311
00317 QMutex& getLock()
00318 {
00319 return *m_lock;
00320 }
00321
00327 bool exists() const
00328 {
00329 return (m_type != t_nonExistent);
00330 }
00331
00337 void addNotifee(ResourcesUser *n);
00338
00345 void removeNotifee(ResourcesUser *n);
00346
00353 bool isNotifee(ResourcesUser *n) const;
00354
00355 private:
00361 void notifyAll(Resource::ResourceChangeType changeType);
00362
00366 const QString m_name;
00367
00373 enum Type
00374 {
00375 t_resource,
00376 t_paramSettable,
00377 t_qObject,
00378 t_int,
00379 t_float,
00380 t_double,
00381 t_bool,
00382 t_nonExistent
00383 } m_type;
00384
00388 union Pointers
00389 {
00390 Resource* res;
00391 ParameterSettable* par;
00392 QObject* obj;
00393 int* intp;
00394 float* floatp;
00395 double* doublep;
00396 bool* boolp;
00397 } m_pointers;
00398
00405 ResourceMutexHolder m_lock;
00406
00411 QSet<ResourcesUser *> m_notifees;
00412
00416 ResourceHandler(const ResourceHandler&);
00417
00421 ResourceHandler& operator=(const ResourceHandler&);
00422 };
00423
00424 template<>
00425 inline int* ResourceHandler::get<int>() const
00426 {
00427 if (m_type == t_int) {
00428 return m_pointers.intp;
00429 } else {
00430 return NULL;
00431 }
00432 }
00433
00434 template<>
00435 inline float* ResourceHandler::get<float>() const
00436 {
00437 if (m_type == t_float) {
00438 return m_pointers.floatp;
00439 } else {
00440 return NULL;
00441 }
00442 }
00443
00444 template<>
00445 inline double* ResourceHandler::get<double>() const
00446 {
00447 if (m_type == t_double) {
00448 return m_pointers.doublep;
00449 } else {
00450 return NULL;
00451 }
00452 }
00453
00454 template<>
00455 inline bool* ResourceHandler::get<bool>() const
00456 {
00457 if (m_type == t_bool) {
00458 return m_pointers.boolp;
00459 } else {
00460 return NULL;
00461 }
00462 }
00463
00464
00473 class FARSA_CONF_API ResourceCollection
00474 {
00475 public:
00479 ResourceCollection();
00480
00484 ~ResourceCollection();
00485
00491 QMutex& getLock()
00492 {
00493 return m_lock;
00494 }
00495
00501 QWaitCondition& getWaitCondition()
00502 {
00503 return m_waitCondition;
00504 }
00505
00511 int incrementReferenceCounter() throw()
00512 {
00513 return ++m_referenceCounter;
00514 }
00515
00521 int decrementReferenceCounter() throw()
00522 {
00523 return --m_referenceCounter;
00524 }
00525
00531 int getReferenceCounter() throw()
00532 {
00533 return m_referenceCounter;
00534 }
00535
00546 ResourceHandler* getResource(QString name, bool create = false);
00547
00555 bool hasResource(QString name) const
00556 {
00557 return (m_resources.contains(name) && m_resources[name]->exists());
00558 }
00559
00560 private:
00566 QMap<QString, ResourceHandler*> m_resources;
00567
00574 QMutex m_lock;
00575
00585 QWaitCondition m_waitCondition;
00586
00590 int m_referenceCounter;
00591
00595 ResourceCollection(const ResourceCollection&);
00596
00600 ResourceCollection& operator=(const ResourceCollection&);
00601 };
00602
00612 class FARSA_CONF_API ResourceCollectionHolder
00613 {
00614 public:
00618 ResourceCollectionHolder();
00619
00627 ResourceCollectionHolder(const ResourceCollectionHolder& other) throw();
00628
00637 ResourceCollectionHolder& operator=(const ResourceCollectionHolder& other) throw();
00638
00642 ~ResourceCollectionHolder() throw();
00643
00650 void setUseLock(bool useLock) throw()
00651 {
00652 m_useLocks = useLock;
00653 }
00654
00663 bool operator==(const ResourceCollectionHolder& other) const throw()
00664 {
00665 return (m_resourceCollection == other.m_resourceCollection);
00666 }
00667
00673 ResourceCollection& operator*() const throw()
00674 {
00675 return *m_resourceCollection;
00676 }
00677
00684 ResourceCollection* operator->() const throw()
00685 {
00686 return m_resourceCollection;
00687 }
00688
00689 private:
00693 ResourceCollection* m_resourceCollection;
00694
00699 bool m_useLocks;
00700 };
00701
00702 }
00703
00704 #endif