refBase.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _REFBASE_H_
  23. #define _REFBASE_H_
  24. #ifndef _PLATFORMASSERT_H_
  25. # include "platform/platformAssert.h"
  26. #endif
  27. #ifndef _TYPETRAITS_H_
  28. # include "platform/typetraits.h"
  29. #endif
  30. /// Base class for objects which can be weakly referenced
  31. /// (i.e., reference goes away when object is destroyed).
  32. class WeakRefBase
  33. {
  34. public:
  35. /// Weak reference to WeakRefBase.
  36. class WeakReference
  37. {
  38. public:
  39. WeakRefBase * get() { return mObject; }
  40. void incRefCount() { mRefCount++; }
  41. void decRefCount()
  42. {
  43. AssertFatal( mRefCount > 0, "WeakReference - decrementing count of zero!" );
  44. if (--mRefCount==0)
  45. delete this;
  46. }
  47. U32 getRefCount() { return mRefCount; }
  48. private:
  49. friend class WeakRefBase;
  50. WeakReference(WeakRefBase *object) { mObject = object; mRefCount = 0; }
  51. ~WeakReference() { AssertFatal(mObject==NULL, "Deleting weak reference which still points at an object."); }
  52. // Object we reference
  53. WeakRefBase *mObject;
  54. // reference count for this structure (not WeakObjectRef itself)
  55. U32 mRefCount;
  56. };
  57. public:
  58. WeakRefBase() { mReference = NULL; }
  59. virtual ~WeakRefBase() { clearWeakReferences(); }
  60. WeakReference * getWeakReference();
  61. protected:
  62. void clearWeakReferences();
  63. private:
  64. WeakReference * mReference;
  65. };
  66. template< typename T > class SimObjectPtr;
  67. /// Weak reference pointer class.
  68. /// Instances of this template class can be used as pointers to
  69. /// instances of WeakRefBase and its subclasses.
  70. /// When the object referenced by a WeakRefPtr instance is deleted,
  71. /// the pointer to the object is set to NULL in the WeakRefPtr instance.
  72. template <class T> class WeakRefPtr
  73. {
  74. public:
  75. WeakRefPtr() { mReference = NULL; }
  76. WeakRefPtr(T *ptr) { mReference = NULL; set(ptr); }
  77. WeakRefPtr(const WeakRefPtr<T> & ref) { mReference = NULL; set(ref.mReference); }
  78. ~WeakRefPtr() { set((WeakRefBase::WeakReference*)NULL); }
  79. WeakRefPtr<T>& operator=(const WeakRefPtr<T>& ref)
  80. {
  81. set(ref.mReference);
  82. return *this;
  83. }
  84. WeakRefPtr<T>& operator=(T *ptr)
  85. {
  86. set(ptr);
  87. return *this;
  88. }
  89. /// Returns true if the pointer is not set.
  90. bool isNull() const { return mReference == NULL || mReference->get() == NULL; }
  91. /// Returns true if the pointer is set.
  92. bool isValid() const { return mReference && mReference->get(); }
  93. T* operator->() const { return getPointer(); }
  94. T& operator*() const { return *getPointer(); }
  95. operator T*() const { return getPointer(); }
  96. /// Returns the pointer.
  97. T* getPointer() const { return mReference ? ( T* ) mReference->get() : NULL; }
  98. protected:
  99. void set(WeakRefBase::WeakReference * ref)
  100. {
  101. if (mReference)
  102. mReference->decRefCount();
  103. mReference = NULL;
  104. if (ref)
  105. {
  106. mReference = ref;
  107. mReference->incRefCount();
  108. }
  109. }
  110. void set(T * obj) { set(obj ? obj->getWeakReference() : (WeakRefBase::WeakReference *)NULL); }
  111. private:
  112. template< typename > friend class SimObjectPtr;
  113. WeakRefBase::WeakReference * mReference;
  114. };
  115. /// Union of an arbitrary type with a WeakRefBase. The exposed type will
  116. /// remain accessible so long as the WeakRefBase is not cleared. Once
  117. /// it is cleared, accessing the exposed type will result in a NULL pointer.
  118. template<class ExposedType>
  119. class WeakRefUnion
  120. {
  121. typedef WeakRefUnion<ExposedType> Union;
  122. public:
  123. WeakRefUnion() : mPtr(NULL) {}
  124. WeakRefUnion(const WeakRefPtr<WeakRefBase> & ref, ExposedType * ptr) : mPtr(NULL) { set(ref, ptr); }
  125. WeakRefUnion(const Union & lock) : mPtr(NULL) { *this = lock; }
  126. WeakRefUnion(WeakRefBase * ref) : mPtr(NULL) { set(ref, dynamic_cast<ExposedType*>(ref)); }
  127. ~WeakRefUnion() { mWeakReference = NULL; }
  128. Union & operator=(const Union & ptr)
  129. {
  130. set(ptr.mWeakReference, ptr.getPointer());
  131. return *this;
  132. }
  133. void set(const WeakRefPtr<WeakRefBase> & ref, ExposedType * ptr)
  134. {
  135. mWeakReference = ref;
  136. mPtr = ptr;
  137. }
  138. bool operator == (const ExposedType * t ) const { return getPointer() == t; }
  139. bool operator != (const ExposedType * t ) const { return getPointer() != t; }
  140. bool operator == (const Union &t ) const { return getPointer() == t.getPointer(); }
  141. bool operator != (const Union &t ) const { return getPointer() != t.getPointer(); }
  142. bool isNull() const { return mWeakReference.isNull() || !mPtr; }
  143. ExposedType* getPointer() const { return !mWeakReference.isNull() ? mPtr : NULL; }
  144. ExposedType* operator->() const { return getPointer(); }
  145. ExposedType& operator*() const { return *getPointer(); }
  146. operator ExposedType*() const { return getPointer(); }
  147. WeakRefPtr<WeakRefBase> getRef() const { return mWeakReference; }
  148. private:
  149. WeakRefPtr<WeakRefBase> mWeakReference;
  150. ExposedType * mPtr;
  151. };
  152. /// Base class for objects which can be strongly referenced
  153. /// (i.e., as long as reference exists, object will exist,
  154. /// when all strong references go away, object is destroyed).
  155. class StrongRefBase : public WeakRefBase
  156. {
  157. friend class StrongObjectRef;
  158. public:
  159. StrongRefBase() { mRefCount = 0; }
  160. U32 getRefCount() const { return mRefCount; }
  161. /// object destroy self call (from StrongRefPtr). Override if this class has specially allocated memory.
  162. virtual void destroySelf() { delete this; }
  163. /// Increments the reference count.
  164. void incRefCount()
  165. {
  166. mRefCount++;
  167. }
  168. /// Decrements the reference count.
  169. void decRefCount()
  170. {
  171. AssertFatal(mRefCount, "Decrementing a reference with refcount 0!");
  172. if(!--mRefCount)
  173. destroySelf();
  174. }
  175. protected:
  176. U32 mRefCount; ///< reference counter for StrongRefPtr objects
  177. };
  178. /// Base class for StrongRefBase strong reference pointers.
  179. class StrongObjectRef
  180. {
  181. public:
  182. /// Constructor, assigns from the object and increments its reference count if it's not NULL
  183. StrongObjectRef(StrongRefBase *object = NULL) : mObject( object )
  184. {
  185. mObject = object;
  186. incRef();
  187. }
  188. /// Destructor, dereferences the object, if there is one
  189. ~StrongObjectRef() { decRef(); }
  190. /// Assigns this reference object from an existing StrongRefBase instance
  191. void set(StrongRefBase *object)
  192. {
  193. if( mObject != object )
  194. {
  195. decRef();
  196. mObject = object;
  197. incRef();
  198. }
  199. }
  200. protected:
  201. StrongRefBase *mObject; ///< the object this RefObjectRef references
  202. /// increments the reference count on the referenced object
  203. void incRef()
  204. {
  205. if(mObject)
  206. mObject->incRefCount();
  207. }
  208. /// decrements the reference count on the referenced object
  209. void decRef()
  210. {
  211. if(mObject)
  212. mObject->decRefCount();
  213. }
  214. };
  215. /// Reference counted object template pointer class
  216. /// Instances of this template class can be used as pointers to
  217. /// instances of StrongRefBase and its subclasses. The object will not
  218. /// be deleted until all of the StrongRefPtr instances pointing to it
  219. /// have been destructed.
  220. template <class T> class StrongRefPtr : protected StrongObjectRef
  221. {
  222. public:
  223. StrongRefPtr() : StrongObjectRef() {}
  224. StrongRefPtr(T *ptr) : StrongObjectRef(ptr) {}
  225. StrongRefPtr(const StrongRefPtr<T>& ref) : StrongObjectRef(ref.mObject) {}
  226. ~StrongRefPtr() {}
  227. StrongRefPtr<T>& operator=(const StrongRefPtr<T>& ref)
  228. {
  229. set(ref.mObject);
  230. return *this;
  231. }
  232. StrongRefPtr<T>& operator=(T *ptr)
  233. {
  234. set(ptr);
  235. return *this;
  236. }
  237. bool isNull() const { return mObject == 0; }
  238. bool isValid() const { return mObject != 0; }
  239. T* operator->() const { return getPointer(); }
  240. T& operator*() const { return *getPointer(); }
  241. operator T*() const { return getPointer(); }
  242. T* getPointer() const { return const_cast<T*>(static_cast<T* const>(mObject)); }
  243. };
  244. /// Union of an arbitrary type with a StrongRefBase. StrongRefBase will remain locked
  245. /// until the union is destructed. Handy for when the exposed class will
  246. /// become invalid whenever the reference becomes invalid and you want to make sure that doesn't
  247. /// happen.
  248. template<class ExposedType>
  249. class StrongRefUnion
  250. {
  251. typedef StrongRefUnion<ExposedType> Union;
  252. public:
  253. StrongRefUnion() : mPtr(NULL) {}
  254. StrongRefUnion(const StrongRefPtr<StrongRefBase> & ref, ExposedType * ptr) : mPtr(NULL) { set(ref, ptr); }
  255. StrongRefUnion(const Union & lock) : mPtr(NULL) { *this = lock; }
  256. StrongRefUnion(StrongRefBase * ref) : mPtr(NULL) { set(ref, dynamic_cast<ExposedType*>(ref)); }
  257. ~StrongRefUnion() { mReference = NULL; }
  258. Union & operator=(const Union & ptr)
  259. {
  260. set(ptr.mReference, ptr.mPtr);
  261. return *this;
  262. }
  263. void set(const StrongRefPtr<StrongRefBase> & ref, ExposedType * ptr)
  264. {
  265. mReference = ref;
  266. mPtr = ptr;
  267. }
  268. bool operator == (const ExposedType * t ) const { return mPtr == t; }
  269. bool operator != (const ExposedType * t ) const { return mPtr != t; }
  270. bool operator == (const Union &t ) const { return mPtr == t.mPtr; }
  271. bool operator != (const Union &t ) const { return mPtr != t.mPtr; }
  272. bool isNull() const { return mReference.isNull() || !mPtr; }
  273. bool isValid() const { return mReference.isValid() && mPtr; }
  274. ExposedType* operator->() const { return mPtr; }
  275. ExposedType& operator*() const { return *mPtr; }
  276. operator ExposedType*() const { return mPtr; }
  277. ExposedType* getPointer() const { return mPtr; }
  278. StrongRefPtr<StrongRefBase> getRef() const { return mReference; }
  279. private:
  280. StrongRefPtr<StrongRefBase> mReference;
  281. ExposedType * mPtr;
  282. };
  283. /// This oxymoron is a pointer that reference-counts the referenced
  284. /// object but also NULLs out if the object goes away.
  285. ///
  286. /// This is useful for situations where an object's lifetime is ultimately
  287. /// governed by a superior entity but where individual objects may also die
  288. /// independently of the superior entity. All client code should use
  289. /// StrongWeakRefs that keep object live as long as the superior entity doesn't
  290. /// step in and kill them (in which case, the client code sees the reference
  291. /// disappear).
  292. template< class T >
  293. class StrongWeakRefPtr
  294. {
  295. public:
  296. StrongWeakRefPtr() : mReference( NULL ) {}
  297. StrongWeakRefPtr( T* ptr ) : mReference( NULL ) { _set( ptr ); }
  298. ~StrongWeakRefPtr()
  299. {
  300. if( mReference )
  301. {
  302. T* ptr = _get();
  303. if( ptr )
  304. ptr->decRefCount();
  305. mReference->decRefCount();
  306. }
  307. }
  308. bool isNull() const { return ( _get() == NULL ); }
  309. bool operator ==( T* ptr ) const { return ( _get() == ptr ); }
  310. bool operator !=( T* ptr ) const { return ( _get() != ptr ); }
  311. bool operator !() const { return isNull(); }
  312. T* operator ->() const { return _get(); }
  313. T& operator *() const { return *( _get() ); }
  314. operator T*() const { return _get(); }
  315. T* getPointer() const { return _get(); }
  316. StrongWeakRefPtr& operator =( T* ptr )
  317. {
  318. _set( ptr );
  319. return *this;
  320. }
  321. private:
  322. WeakRefBase::WeakReference* mReference;
  323. T* _get() const
  324. {
  325. if( mReference )
  326. return static_cast< T* >( mReference->get() );
  327. else
  328. return NULL;
  329. }
  330. void _set( T* ptr )
  331. {
  332. if( mReference )
  333. {
  334. T* old = _get();
  335. if( old )
  336. old->decRefCount();
  337. mReference->decRefCount();
  338. }
  339. if( ptr )
  340. {
  341. ptr->incRefCount();
  342. mReference = ptr->getWeakReference();
  343. mReference->incRefCount();
  344. }
  345. else
  346. mReference = NULL;
  347. }
  348. };
  349. //---------------------------------------------------------------
  350. inline void WeakRefBase::clearWeakReferences()
  351. {
  352. if (mReference)
  353. {
  354. mReference->mObject = NULL;
  355. mReference->decRefCount();
  356. mReference = NULL;
  357. }
  358. }
  359. inline WeakRefBase::WeakReference * WeakRefBase::getWeakReference()
  360. {
  361. if (!mReference)
  362. {
  363. mReference = new WeakReference(this);
  364. mReference->incRefCount();
  365. }
  366. return mReference;
  367. }
  368. //---------------------------------------------------------------
  369. template< typename T >
  370. struct TypeTraits< WeakRefPtr< T > > : public _TypeTraits< WeakRefPtr< T > >
  371. {
  372. typedef typename TypeTraits< T >::BaseType BaseType;
  373. };
  374. template< typename T >
  375. struct TypeTraits< StrongRefPtr< T > > : public _TypeTraits< StrongRefPtr< T > >
  376. {
  377. typedef typename TypeTraits< T >::BaseType BaseType;
  378. };
  379. template< typename T >
  380. struct TypeTraits< StrongWeakRefPtr< T > > : public _TypeTraits< StrongWeakRefPtr< T > >
  381. {
  382. typedef typename TypeTraits< T >::BaseType BaseType;
  383. };
  384. template< typename T >
  385. inline T& Deref( WeakRefPtr< T >& ref )
  386. {
  387. return *ref;
  388. }
  389. template< typename T >
  390. inline T& Deref( StrongRefPtr< T >& ref )
  391. {
  392. return *ref;
  393. }
  394. template< typename T >
  395. inline T& Deref( StrongWeakRefPtr< T >& ref )
  396. {
  397. return *ref;
  398. }
  399. #endif