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