Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
Object.hpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #ifndef Object_INCLUDE_ONCE
33 #define Object_INCLUDE_ONCE
34 
35 #include <vlCore/checks.hpp>
36 #include <vlCore/IMutex.hpp>
37 #include <vlCore/TypeInfo.hpp>
38 #include <string>
39 
40 #if VL_DEBUG_LIVING_OBJECTS
41  #include <set>
42 #endif
43 
44 namespace vl
45 {
46  //------------------------------------------------------------------------------
47  // ref
48  //------------------------------------------------------------------------------
54  template<class T>
55  class ref
56  {
57  public:
58  // 'const' is required as the copy constructor must have this signature.
59  ref(const ref& other)
60  {
61  mObject = NULL;
62  *this = other;
63  }
64 
65  ref(const T* object=NULL)
66  {
67  mObject = const_cast<T*>(object);
68  if (mObject)
69  mObject->incReference();
70  }
71 
72  template<class T2> ref(const ref<T2>& other)
73  {
74  mObject = NULL;
75  *this = other;
76  }
77 
78  ~ref()
79  {
80  if (mObject)
81  mObject->decReference();
82  mObject = NULL;
83  }
84 
85  // 'const' is required because operator= must have this signature.
86  ref& operator=(const ref& other)
87  {
88  if (other)
89  other->incReference();
90  if (mObject)
91  mObject->decReference();
92  mObject = const_cast<T*>(other.get());
93  return *this;
94  }
95 
96  // 'const' is required because operator= must have this signature.
97  ref& operator=(const T* other)
98  {
99  if (other)
100  other->incReference();
101  if (mObject)
102  mObject->decReference();
103  mObject = const_cast<T*>(other);
104  return *this;
105  }
106 
107  // 'const' is required because operator= must have this signature.
108  template<class T2> ref& operator=(const ref<T2>& other)
109  {
110  if (other)
111  other->incReference();
112  if (mObject)
113  mObject->decReference();
114  mObject = const_cast<T2*>(other.get());
115  return *this;
116  }
117 
118  void swap(ref& other)
119  {
120  T* tmp = other.mObject;
121  other = mObject;
122  mObject = tmp;
123  }
124 
126  T* get_writable() const { return mObject; }
127 
128  const T* get() const { return mObject; }
129  const T* operator->() const { VL_CHECK(mObject); return mObject; }
130  const T& operator*() const { VL_CHECK(mObject); return *mObject; }
131 
132  T* get() { return mObject; }
133  T* operator->() { VL_CHECK(mObject); return mObject; }
134  T& operator*() { VL_CHECK(mObject); return *mObject; }
135 
136  bool operator<(const ref& other) const { return mObject < other.mObject; }
137 
138  operator bool() const { return mObject != NULL; }
139 
140  protected:
142  };
143  // interaction with the other types
144  template<class T1, class T2> inline bool operator==(const ref<T1> & o1, const ref<T2> & o2) { return o1.get() == o2.get(); }
145  template<class T1, class T2> inline bool operator!=(const ref<T1> & o1, const ref<T2> & o2) { return o1.get() != o2.get(); }
146  template<class T1, class T2> inline bool operator==(const ref<T1> & o1, T2 * o2) { return o1.get() == o2; }
147  template<class T1, class T2> inline bool operator!=(const ref<T1> & o1, T2 * o2) { return o1.get() != o2; }
148  template<class T1, class T2> inline bool operator==(T1 * o1, const ref<T2> & o2) { return o1 == o2.get(); }
149  template<class T1, class T2> inline bool operator!=(T1 * o1, const ref<T2> & o2) { return o1 != o2.get(); }
150 
151  //------------------------------------------------------------------------------
152  // Object
153  //------------------------------------------------------------------------------
159  {
161 
162  public:
165  {
166  VL_DEBUG_SET_OBJECT_NAME()
167  mRefCountMutex = NULL;
168  mReferenceCount = 0;
169  mAutomaticDelete = true;
170  // user data
171  #ifdef VL_USER_DATA_OBJECT
172  mUserData = NULL;
173  #endif
174  #if VL_DEBUG_LIVING_OBJECTS
175  debug_living_objects()->insert(this);
176  // mDebug_LivingObjects.insert(this);
177  #endif
178  }
179 
181  Object(const Object& other)
182  {
183  // copy the name, the ref count mutex and the user data.
184  mObjectName = other.mObjectName;
185  mRefCountMutex = other.mRefCountMutex;
186  #ifdef VL_USER_DATA_OBJECT
187  mUserData = other.mUserData;
188  #endif
189 
190  // mReferenceCount and mAutomaticDelete are not copiable.
191  mReferenceCount = 0;
192  mAutomaticDelete = true;
193 
194  // debug living object
195  #if VL_DEBUG_LIVING_OBJECTS
196  debug_living_objects()->insert(this);
197  #endif
198  }
199 
201  Object& operator=(const Object& other)
202  {
203  // copy the name, the ref count mutex and the user data.
204  mObjectName = other.mObjectName;
205  mRefCountMutex = other.mRefCountMutex;
206  #ifdef VL_USER_DATA_OBJECT
207  mUserData = other.mUserData;
208  #endif
209 
210  // mReferenceCount and mAutomaticDelete are not copiable.
211  // ...
212 
213  return *this;
214  }
215 
217  const std::string& objectName() const { return mObjectName; }
218 
220  void setObjectName(const char* name) { mObjectName = name; }
221 
223  void setObjectName(const std::string& name) { mObjectName = name; }
224 
226  void setRefCountMutex(IMutex* mutex) { mRefCountMutex = mutex; }
227 
229  IMutex* refCountMutex() { return mRefCountMutex; }
230 
232  const IMutex* refCountMutex() const { return mRefCountMutex; }
233 
235  int referenceCount() const
236  {
237  return mReferenceCount;
238  }
239 
241  void incReference() const
242  {
243  // Lock mutex
244  if (refCountMutex())
245  const_cast<IMutex*>(refCountMutex())->lock();
246 
247  ++mReferenceCount;
248 
249  // Unlock mutex
250  if(refCountMutex())
251  const_cast<IMutex*>(refCountMutex())->unlock();
252  }
253 
256  {
257  // Save local copy in case of deletion.
258  IMutex* mutex = mRefCountMutex;
259 
260  // Lock mutex.
261  if (mutex)
262  mutex->lock();
263 
264  VL_CHECK(mReferenceCount)
265  --mReferenceCount;
266  if (mReferenceCount == 0 && automaticDelete())
267  delete this;
268 
269  // Unlock mutex.
270  if (mutex)
271  mutex->unlock();
272  }
273 
275  void setAutomaticDelete(bool autodel_on) { mAutomaticDelete = autodel_on; }
276 
278  bool automaticDelete() const { return mAutomaticDelete; }
279 
281  template<class T>
282  T* as() { return cast<T>(this); }
283 
285  template<class T>
286  const T* as() const { return cast<const T>(this); }
287 
288 #ifdef VL_USER_DATA_OBJECT
289  public:
290  const Object* userData() const { return mUserData.get(); }
291  Object* userData() { return mUserData.get(); }
292  void setUserData(Object* user_data) { mUserData = user_data; }
293 
294  private:
295  ref<Object> mUserData;
296 #endif
297 
298  protected:
299  virtual ~Object();
300  std::string mObjectName;
301 
303  mutable int mReferenceCount;
305 
306  // debugging facilities
307 
308  public:
309  #if VL_DEBUG_LIVING_OBJECTS
310  static std::set< Object* >* mDebug_LivingObjects;
311  static std::set< Object* >* debug_living_objects()
312  {
313  if (!mDebug_LivingObjects)
314  mDebug_LivingObjects = new std::set< Object* >;
315  return mDebug_LivingObjects;
316  }
317  #endif
318  };
319 
320 }
321 
322 #endif
ref(const T *object=NULL)
Definition: Object.hpp:65
const T * operator->() const
Definition: Object.hpp:129
const T & operator*() const
Definition: Object.hpp:130
ref & operator=(const ref &other)
Definition: Object.hpp:86
T * mObject
Definition: Object.hpp:141
void setAutomaticDelete(bool autodel_on)
If set to true the Object is deleted when its reference count reaches 0.
Definition: Object.hpp:275
const T * get() const
Definition: Object.hpp:128
void setObjectName(const char *name)
The name of the object, by default set to the object&#39;s class name in debug builds.
Definition: Object.hpp:220
const IMutex * refCountMutex() const
The mutex used to protect the reference counting of an Object across multiple threads.
Definition: Object.hpp:232
bool mAutomaticDelete
Definition: Object.hpp:304
Object()
Constructor.
Definition: Object.hpp:164
Set of macros and templates implementing a simple and portable RTTI system.
IMutex * mRefCountMutex
Definition: Object.hpp:302
T * operator->()
Definition: Object.hpp:133
Object(const Object &other)
Copy constructor: copies the name, ref count mutex and user data.
Definition: Object.hpp:181
IMutex * refCountMutex()
The mutex used to protect the reference counting of an Object across multiple threads.
Definition: Object.hpp:229
#define VL_INSTRUMENT_BASE_CLASS(ClassName)
Definition: TypeInfo.hpp:80
ref & operator=(const T *other)
Definition: Object.hpp:97
int mReferenceCount
Definition: Object.hpp:303
Visualization Library main namespace.
void swap(ref &other)
Definition: Object.hpp:118
void setRefCountMutex(IMutex *mutex)
The mutex used to protect the reference counting of an Object across multiple threads.
Definition: Object.hpp:226
void setObjectName(const std::string &name)
The name of the object, by default set to the object&#39;s class name in debug builds.
Definition: Object.hpp:223
bool operator!=(const ref< T1 > &o1, const ref< T2 > &o2)
Definition: Object.hpp:145
~ref()
Definition: Object.hpp:78
The base class for all the reference counted objects.
Definition: Object.hpp:158
An interface to implement simple platform-independent mutexes used to protect critical sections...
Definition: IMutex.hpp:44
ref & operator=(const ref< T2 > &other)
Definition: Object.hpp:108
T * as()
Casts an Object to the specified class.
Definition: Object.hpp:282
#define NULL
Definition: OpenGLDefs.hpp:81
int referenceCount() const
Returns the number of references of an object.
Definition: Object.hpp:235
T * get_writable() const
This is mainly useful when using ref<> with std::map, std::set, etc.
Definition: Object.hpp:126
const std::string & objectName() const
The name of the object, by default set to the object&#39;s class name.
Definition: Object.hpp:217
virtual void lock()=0
Locks the mutex.
bool operator<(const ref &other) const
Definition: Object.hpp:136
const T * as() const
Casts an Object to the specified class.
Definition: Object.hpp:286
bool automaticDelete() const
If set to true the Object is deleted when its reference count reaches 0.
Definition: Object.hpp:278
bool operator==(const ref< T1 > &o1, const ref< T2 > &o2)
Definition: Object.hpp:144
ref(const ref< T2 > &other)
Definition: Object.hpp:72
The ref<> class is used to reference-count an Object.
Definition: Object.hpp:55
virtual void unlock()=0
Unlocks the mutex.
ref(const ref &other)
Definition: Object.hpp:59
T & operator*()
Definition: Object.hpp:134
void decReference()
Decrements the reference count of an object and deletes it if both automaticDelete() is true the coun...
Definition: Object.hpp:255
std::string mObjectName
Definition: Object.hpp:300
#define VL_CHECK(expr)
Definition: checks.hpp:73
Object & operator=(const Object &other)
Copy operator: copies the object&#39;s name, ref count mutex and user data.
Definition: Object.hpp:201
void incReference() const
Increments the reference count of an object.
Definition: Object.hpp:241