resource.h
1 /********************************************************************************
2  * FARSA Experiments Library *
3  * Copyright (C) 2007-2012 *
4  * Gianluca Massera <emmegian@yahoo.it> *
5  * Stefano Nolfi <stefano.nolfi@istc.cnr.it> *
6  * Onofrio Gigliotta <onofrio.gigliotta@istc.cnr.it> *
7  * Tomassino Ferrauto <tomassino.ferrauto@istc.cnr.it> *
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  * This program is distributed in the hope that it will be useful, *
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17  * GNU General Public License for more details. *
18  * *
19  * You should have received a copy of the GNU General Public License *
20  * along with this program; if not, write to the Free Software *
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
22  ********************************************************************************/
23 
24 #ifndef RESOURCE_H
25 #define RESOURCE_H
26 
27 #include "parametersettable.h"
28 #include "configurationconfig.h"
29 #include "configurationexceptions.h"
30 #include <QMap>
31 #include <QString>
32 #include <QMutex>
33 #include <QSet>
34 
35 class QObject;
36 
37 namespace farsa {
38 
39 class ResourceHandler;
40 class ResourceCollection;
41 class ResourcesUser;
42 
56 class FARSA_CONF_TEMPLATE Resource
57 {
58 public:
63  Created,
64  Modified,
65  Deleted
66  };
67 
68 public:
72  virtual ~Resource()
73  {
74  }
75 };
76 
84 class FARSA_CONF_API ResourceMutexHolder
85 {
86 public:
91 
98  ResourceMutexHolder(const ResourceMutexHolder& other) throw();
99 
106  ResourceMutexHolder& operator=(const ResourceMutexHolder& other) throw();
107 
111  ~ResourceMutexHolder() throw();
112 
121  bool operator==(const ResourceMutexHolder& other) const throw()
122  {
123  return (m_shared == other.m_shared);
124  }
125 
131  QMutex& operator*() const throw()
132  {
133  return m_shared->resourceLock;
134  }
135 
142  QMutex* operator->() const throw()
143  {
144  return &(m_shared->resourceLock);
145  }
146 
147 private:
152  struct MutexAndRefCounter
153  {
157  MutexAndRefCounter() :
158  resourceLock(QMutex::Recursive),
159  referenceCounter(0)
160  {
161  }
162 
166  QMutex resourceLock;
167 
171  int referenceCounter;
172  };
173 
177  MutexAndRefCounter* m_shared;
178 };
179 
189 class FARSA_CONF_API ResourceHandler
190 {
191 public:
199  ResourceHandler(QString name);
200 
204  ~ResourceHandler();
205 
211  QString name() const
212  {
213  return m_name;
214  }
215 
225  void shareLockWith(ResourceHandler* other);
226 
233  void set(int* res);
234 
241  void set(float* res);
242 
249  void set(double* res);
250 
257  void set(bool* res);
258 
265  void set(Resource* res);
266 
273  void set(ParameterSettable* res);
274 
281  void set(QObject* res);
282 
288  void unset();
289 
297  template<class T>
298  T* get() const
299  {
300  switch(m_type) {
301  case t_resource:
302  return dynamic_cast<T*>(m_pointers.res);
303  case t_paramSettable:
304  return dynamic_cast<T*>(m_pointers.par);
305  case t_qObject:
306  return dynamic_cast<T*>(m_pointers.obj);
307  default:
308  return NULL;
309  }
310  }
311 
317  QMutex& getLock()
318  {
319  return *m_lock;
320  }
321 
327  bool exists() const
328  {
329  return (m_type != t_nonExistent);
330  }
331 
337  void addNotifee(ResourcesUser *n);
338 
345  void removeNotifee(ResourcesUser *n);
346 
353  bool isNotifee(ResourcesUser *n) const;
354 
355 private:
361  void notifyAll(Resource::ResourceChangeType changeType);
362 
366  const QString m_name;
367 
373  enum Type
374  {
375  t_resource,
376  t_paramSettable,
377  t_qObject,
378  t_int,
379  t_float,
380  t_double,
381  t_bool,
382  t_nonExistent
383  } m_type;
384 
388  union Pointers
389  {
390  Resource* res;
391  ParameterSettable* par;
392  QObject* obj;
393  int* intp;
394  float* floatp;
395  double* doublep;
396  bool* boolp;
397  } m_pointers;
398 
405  ResourceMutexHolder m_lock;
406 
411  QSet<ResourcesUser *> m_notifees;
412 
416  ResourceHandler(const ResourceHandler&);
417 
421  ResourceHandler& operator=(const ResourceHandler&);
422 };
423 
424 template<>
425 inline int* ResourceHandler::get<int>() const
426 {
427  if (m_type == t_int) {
428  return m_pointers.intp;
429  } else {
430  return NULL;
431  }
432 }
433 
434 template<>
435 inline float* ResourceHandler::get<float>() const
436 {
437  if (m_type == t_float) {
438  return m_pointers.floatp;
439  } else {
440  return NULL;
441  }
442 }
443 
444 template<>
445 inline double* ResourceHandler::get<double>() const
446 {
447  if (m_type == t_double) {
448  return m_pointers.doublep;
449  } else {
450  return NULL;
451  }
452 }
453 
454 template<>
455 inline bool* ResourceHandler::get<bool>() const
456 {
457  if (m_type == t_bool) {
458  return m_pointers.boolp;
459  } else {
460  return NULL;
461  }
462 }
463 
464 
473 class FARSA_CONF_API ResourceCollection
474 {
475 public:
480 
485 
491  QMutex& getLock()
492  {
493  return m_lock;
494  }
495 
501  QWaitCondition& getWaitCondition()
502  {
503  return m_waitCondition;
504  }
505 
511  int incrementReferenceCounter() throw()
512  {
513  return ++m_referenceCounter;
514  }
515 
521  int decrementReferenceCounter() throw()
522  {
523  return --m_referenceCounter;
524  }
525 
531  int getReferenceCounter() throw()
532  {
533  return m_referenceCounter;
534  }
535 
546  ResourceHandler* getResource(QString name, bool create = false);
547 
555  bool hasResource(QString name) const
556  {
557  return (m_resources.contains(name) && m_resources[name]->exists());
558  }
559 
560 private:
566  QMap<QString, ResourceHandler*> m_resources;
567 
574  QMutex m_lock;
575 
585  QWaitCondition m_waitCondition;
586 
590  int m_referenceCounter;
591 
596 
600  ResourceCollection& operator=(const ResourceCollection&);
601 };
602 
612 class FARSA_CONF_API ResourceCollectionHolder
613 {
614 public:
619 
628 
637  ResourceCollectionHolder& operator=(const ResourceCollectionHolder& other) throw();
638 
642  ~ResourceCollectionHolder() throw();
643 
650  void setUseLock(bool useLock) throw()
651  {
652  m_useLocks = useLock;
653  }
654 
663  bool operator==(const ResourceCollectionHolder& other) const throw()
664  {
665  return (m_resourceCollection == other.m_resourceCollection);
666  }
667 
673  ResourceCollection& operator*() const throw()
674  {
675  return *m_resourceCollection;
676  }
677 
684  ResourceCollection* operator->() const throw()
685  {
686  return m_resourceCollection;
687  }
688 
689 private:
693  ResourceCollection* m_resourceCollection;
694 
699  bool m_useLocks;
700 };
701 
702 } // end namespace farsa
703 
704 #endif