The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

256 lines
8.0KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-10 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. #ifndef __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__
  19. #define __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__
  20. #include "../core/juce_Atomic.h"
  21. //==============================================================================
  22. /**
  23. Adds reference-counting to an object.
  24. To add reference-counting to a class, derive it from this class, and
  25. use the ReferenceCountedObjectPtr class to point to it.
  26. e.g. @code
  27. class MyClass : public ReferenceCountedObject
  28. {
  29. void foo();
  30. // This is a neat way of declaring a typedef for a pointer class,
  31. // rather than typing out the full templated name each time..
  32. typedef ReferenceCountedObjectPtr<MyClass> Ptr;
  33. };
  34. MyClass::Ptr p = new MyClass();
  35. MyClass::Ptr p2 = p;
  36. p = 0;
  37. p2->foo();
  38. @endcode
  39. Once a new ReferenceCountedObject has been assigned to a pointer, be
  40. careful not to delete the object manually.
  41. @see ReferenceCountedObjectPtr, ReferenceCountedArray
  42. */
  43. class JUCE_API ReferenceCountedObject
  44. {
  45. public:
  46. //==============================================================================
  47. /** Increments the object's reference count.
  48. This is done automatically by the smart pointer, but is public just
  49. in case it's needed for nefarious purposes.
  50. */
  51. inline void incReferenceCount() throw()
  52. {
  53. ++refCount;
  54. }
  55. /** Decreases the object's reference count.
  56. If the count gets to zero, the object will be deleted.
  57. */
  58. inline void decReferenceCount() throw()
  59. {
  60. jassert (getReferenceCount() > 0);
  61. if (--refCount == 0)
  62. delete this;
  63. }
  64. /** Returns the object's current reference count. */
  65. inline int getReferenceCount() const throw()
  66. {
  67. return refCount.get();
  68. }
  69. protected:
  70. //==============================================================================
  71. /** Creates the reference-counted object (with an initial ref count of zero). */
  72. ReferenceCountedObject()
  73. {
  74. }
  75. /** Destructor. */
  76. virtual ~ReferenceCountedObject()
  77. {
  78. // it's dangerous to delete an object that's still referenced by something else!
  79. jassert (getReferenceCount() == 0);
  80. }
  81. private:
  82. //==============================================================================
  83. Atomic <int> refCount;
  84. };
  85. //==============================================================================
  86. /**
  87. Used to point to an object of type ReferenceCountedObject.
  88. It's wise to use a typedef instead of typing out the templated name
  89. each time - e.g.
  90. typedef ReferenceCountedObjectPtr<MyClass> MyClassPtr;
  91. @see ReferenceCountedObject, ReferenceCountedObjectArray
  92. */
  93. template <class ReferenceCountedObjectClass>
  94. class ReferenceCountedObjectPtr
  95. {
  96. public:
  97. //==============================================================================
  98. /** Creates a pointer to a null object. */
  99. inline ReferenceCountedObjectPtr() throw()
  100. : referencedObject (0)
  101. {
  102. }
  103. /** Creates a pointer to an object.
  104. This will increment the object's reference-count if it is non-null.
  105. */
  106. inline ReferenceCountedObjectPtr (ReferenceCountedObjectClass* const refCountedObject) throw()
  107. : referencedObject (refCountedObject)
  108. {
  109. if (refCountedObject != 0)
  110. refCountedObject->incReferenceCount();
  111. }
  112. /** Copies another pointer.
  113. This will increment the object's reference-count (if it is non-null).
  114. */
  115. inline ReferenceCountedObjectPtr (const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& other) throw()
  116. : referencedObject (other.referencedObject)
  117. {
  118. if (referencedObject != 0)
  119. referencedObject->incReferenceCount();
  120. }
  121. /** Changes this pointer to point at a different object.
  122. The reference count of the old object is decremented, and it might be
  123. deleted if it hits zero. The new object's count is incremented.
  124. */
  125. ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& operator= (const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& other)
  126. {
  127. ReferenceCountedObjectClass* const newObject = other.referencedObject;
  128. if (newObject != referencedObject)
  129. {
  130. if (newObject != 0)
  131. newObject->incReferenceCount();
  132. ReferenceCountedObjectClass* const oldObject = referencedObject;
  133. referencedObject = newObject;
  134. if (oldObject != 0)
  135. oldObject->decReferenceCount();
  136. }
  137. return *this;
  138. }
  139. /** Changes this pointer to point at a different object.
  140. The reference count of the old object is decremented, and it might be
  141. deleted if it hits zero. The new object's count is incremented.
  142. */
  143. ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& operator= (ReferenceCountedObjectClass* const newObject)
  144. {
  145. if (referencedObject != newObject)
  146. {
  147. if (newObject != 0)
  148. newObject->incReferenceCount();
  149. ReferenceCountedObjectClass* const oldObject = referencedObject;
  150. referencedObject = newObject;
  151. if (oldObject != 0)
  152. oldObject->decReferenceCount();
  153. }
  154. return *this;
  155. }
  156. /** Destructor.
  157. This will decrement the object's reference-count, and may delete it if it
  158. gets to zero.
  159. */
  160. inline ~ReferenceCountedObjectPtr()
  161. {
  162. if (referencedObject != 0)
  163. referencedObject->decReferenceCount();
  164. }
  165. /** Returns the object that this pointer references.
  166. The pointer returned may be zero, of course.
  167. */
  168. inline operator ReferenceCountedObjectClass*() const throw()
  169. {
  170. return referencedObject;
  171. }
  172. /** Returns true if this pointer refers to the given object. */
  173. inline bool operator== (ReferenceCountedObjectClass* const object) const throw()
  174. {
  175. return referencedObject == object;
  176. }
  177. /** Returns true if this pointer doesn't refer to the given object. */
  178. inline bool operator!= (ReferenceCountedObjectClass* const object) const throw()
  179. {
  180. return referencedObject != object;
  181. }
  182. // the -> operator is called on the referenced object
  183. inline ReferenceCountedObjectClass* operator->() const throw()
  184. {
  185. return referencedObject;
  186. }
  187. /** Returns the object that this pointer references.
  188. The pointer returned may be zero, of course.
  189. */
  190. inline ReferenceCountedObjectClass* getObject() const throw()
  191. {
  192. return referencedObject;
  193. }
  194. private:
  195. //==============================================================================
  196. ReferenceCountedObjectClass* referencedObject;
  197. };
  198. #endif // __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__