ovr_sdk

annotate LibOVR/Src/Kernel/OVR_RefCount.h @ 0:1b39a1b46319

initial 0.4.4
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 14 Jan 2015 06:51:16 +0200
parents
children
rev   line source
nuclear@0 1 /************************************************************************************
nuclear@0 2
nuclear@0 3 PublicHeader: Kernel
nuclear@0 4 Filename : OVR_RefCount.h
nuclear@0 5 Content : Reference counting implementation headers
nuclear@0 6 Created : September 19, 2012
nuclear@0 7 Notes :
nuclear@0 8
nuclear@0 9 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
nuclear@0 10
nuclear@0 11 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
nuclear@0 12 you may not use the Oculus VR Rift SDK except in compliance with the License,
nuclear@0 13 which is provided at the time of installation or download, or which
nuclear@0 14 otherwise accompanies this software in either electronic or hard copy form.
nuclear@0 15
nuclear@0 16 You may obtain a copy of the License at
nuclear@0 17
nuclear@0 18 http://www.oculusvr.com/licenses/LICENSE-3.2
nuclear@0 19
nuclear@0 20 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
nuclear@0 21 distributed under the License is distributed on an "AS IS" BASIS,
nuclear@0 22 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
nuclear@0 23 See the License for the specific language governing permissions and
nuclear@0 24 limitations under the License.
nuclear@0 25
nuclear@0 26 ************************************************************************************/
nuclear@0 27
nuclear@0 28 #ifndef OVR_RefCount_h
nuclear@0 29 #define OVR_RefCount_h
nuclear@0 30
nuclear@0 31 #include "OVR_Types.h"
nuclear@0 32 #include "OVR_Allocator.h"
nuclear@0 33
nuclear@0 34 namespace OVR {
nuclear@0 35
nuclear@0 36 //-----------------------------------------------------------------------------------
nuclear@0 37 // ***** Reference Counting
nuclear@0 38
nuclear@0 39 // There are three types of reference counting base classes:
nuclear@0 40 //
nuclear@0 41 // RefCountBase - Provides thread-safe reference counting (Default).
nuclear@0 42 // RefCountBaseNTS - Non Thread Safe version of reference counting.
nuclear@0 43
nuclear@0 44
nuclear@0 45 // ***** Declared classes
nuclear@0 46
nuclear@0 47 template<class C>
nuclear@0 48 class RefCountBase;
nuclear@0 49 template<class C>
nuclear@0 50 class RefCountBaseNTS;
nuclear@0 51
nuclear@0 52 class RefCountImpl;
nuclear@0 53 class RefCountNTSImpl;
nuclear@0 54
nuclear@0 55
nuclear@0 56 //-----------------------------------------------------------------------------------
nuclear@0 57 // ***** Implementation For Reference Counting
nuclear@0 58
nuclear@0 59 // RefCountImplCore holds RefCount value and defines a few utility
nuclear@0 60 // functions shared by all implementations.
nuclear@0 61
nuclear@0 62 class RefCountImplCore
nuclear@0 63 {
nuclear@0 64 protected:
nuclear@0 65 volatile int RefCount;
nuclear@0 66
nuclear@0 67 public:
nuclear@0 68 // RefCountImpl constructor always initializes RefCount to 1 by default.
nuclear@0 69 OVR_FORCE_INLINE RefCountImplCore() : RefCount(1) { }
nuclear@0 70
nuclear@0 71 // Need virtual destructor
nuclear@0 72 // This: 1. Makes sure the right destructor's called.
nuclear@0 73 // 2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem()
nuclear@0 74 virtual ~RefCountImplCore();
nuclear@0 75
nuclear@0 76 // Debug method only.
nuclear@0 77 int GetRefCount() const { return RefCount; }
nuclear@0 78
nuclear@0 79 // This logic is used to detect invalid 'delete' calls of reference counted
nuclear@0 80 // objects. Direct delete calls are not allowed on them unless they come in
nuclear@0 81 // internally from Release.
nuclear@0 82 #ifdef OVR_BUILD_DEBUG
nuclear@0 83 static void OVR_CDECL reportInvalidDelete(void *pmem);
nuclear@0 84 inline static void checkInvalidDelete(RefCountImplCore *pmem)
nuclear@0 85 {
nuclear@0 86 if (pmem->RefCount != 0)
nuclear@0 87 reportInvalidDelete(pmem);
nuclear@0 88 }
nuclear@0 89 #else
nuclear@0 90 inline static void checkInvalidDelete(RefCountImplCore *) { }
nuclear@0 91 #endif
nuclear@0 92
nuclear@0 93 // Base class ref-count content should not be copied.
nuclear@0 94 void operator = (const RefCountImplCore &) { }
nuclear@0 95 };
nuclear@0 96
nuclear@0 97 class RefCountNTSImplCore
nuclear@0 98 {
nuclear@0 99 protected:
nuclear@0 100 mutable int RefCount;
nuclear@0 101
nuclear@0 102 public:
nuclear@0 103 // RefCountImpl constructor always initializes RefCount to 1 by default.
nuclear@0 104 OVR_FORCE_INLINE RefCountNTSImplCore() : RefCount(1) { }
nuclear@0 105
nuclear@0 106 // Need virtual destructor
nuclear@0 107 // This: 1. Makes sure the right destructor's called.
nuclear@0 108 // 2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem()
nuclear@0 109 virtual ~RefCountNTSImplCore();
nuclear@0 110
nuclear@0 111 // Debug method only.
nuclear@0 112 int GetRefCount() const { return RefCount; }
nuclear@0 113
nuclear@0 114 // This logic is used to detect invalid 'delete' calls of reference counted
nuclear@0 115 // objects. Direct delete calls are not allowed on them unless they come in
nuclear@0 116 // internally from Release.
nuclear@0 117 #ifdef OVR_BUILD_DEBUG
nuclear@0 118 static void OVR_CDECL reportInvalidDelete(void *pmem);
nuclear@0 119 OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *pmem)
nuclear@0 120 {
nuclear@0 121 if (pmem->RefCount != 0)
nuclear@0 122 reportInvalidDelete(pmem);
nuclear@0 123 }
nuclear@0 124 #else
nuclear@0 125 OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *) { }
nuclear@0 126 #endif
nuclear@0 127
nuclear@0 128 // Base class ref-count content should not be copied.
nuclear@0 129 void operator = (const RefCountNTSImplCore &) { }
nuclear@0 130 };
nuclear@0 131
nuclear@0 132
nuclear@0 133
nuclear@0 134 // RefCountImpl provides Thread-Safe implementation of reference counting, so
nuclear@0 135 // it should be used by default in most places.
nuclear@0 136
nuclear@0 137 class RefCountImpl : public RefCountImplCore
nuclear@0 138 {
nuclear@0 139 public:
nuclear@0 140 // Thread-Safe Ref-Count Implementation.
nuclear@0 141 void AddRef();
nuclear@0 142 void Release();
nuclear@0 143 };
nuclear@0 144
nuclear@0 145 // RefCountVImpl provides Thread-Safe implementation of reference counting, plus,
nuclear@0 146 // virtual AddRef and Release.
nuclear@0 147
nuclear@0 148 class RefCountVImpl : virtual public RefCountImplCore
nuclear@0 149 {
nuclear@0 150 public:
nuclear@0 151 // Thread-Safe Ref-Count Implementation.
nuclear@0 152 virtual void AddRef();
nuclear@0 153 virtual void Release();
nuclear@0 154 };
nuclear@0 155
nuclear@0 156
nuclear@0 157 // RefCountImplNTS provides Non-Thread-Safe implementation of reference counting,
nuclear@0 158 // which is slightly more efficient since it doesn't use atomics.
nuclear@0 159
nuclear@0 160 class RefCountNTSImpl : public RefCountNTSImplCore
nuclear@0 161 {
nuclear@0 162 public:
nuclear@0 163 OVR_FORCE_INLINE void AddRef() const { RefCount++; }
nuclear@0 164 void Release() const;
nuclear@0 165 };
nuclear@0 166
nuclear@0 167
nuclear@0 168
nuclear@0 169 // RefCountBaseStatImpl<> is a common class that adds new/delete override with Stat tracking
nuclear@0 170 // to the reference counting implementation. Base must be one of the RefCountImpl classes.
nuclear@0 171
nuclear@0 172 template<class Base>
nuclear@0 173 class RefCountBaseStatImpl : public Base
nuclear@0 174 {
nuclear@0 175 public:
nuclear@0 176 RefCountBaseStatImpl() { }
nuclear@0 177
nuclear@0 178 // *** Override New and Delete
nuclear@0 179
nuclear@0 180 // DOM-IGNORE-BEGIN
nuclear@0 181 // Undef new temporarily if it is being redefined
nuclear@0 182 #ifdef OVR_DEFINE_NEW
nuclear@0 183 #undef new
nuclear@0 184 #endif
nuclear@0 185
nuclear@0 186 #ifdef OVR_BUILD_DEBUG
nuclear@0 187 // Custom check used to detect incorrect calls of 'delete' on ref-counted objects.
nuclear@0 188 #define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p) \
nuclear@0 189 do {if (p) Base::checkInvalidDelete((class_name*)p); } while(0)
nuclear@0 190 #else
nuclear@0 191 #define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p)
nuclear@0 192 #endif
nuclear@0 193
nuclear@0 194 // Redefine all new & delete operators.
nuclear@0 195 OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE)
nuclear@0 196
nuclear@0 197 #undef OVR_REFCOUNTALLOC_CHECK_DELETE
nuclear@0 198
nuclear@0 199 #ifdef OVR_DEFINE_NEW
nuclear@0 200 #define new OVR_DEFINE_NEW
nuclear@0 201 #endif
nuclear@0 202 // OVR_BUILD_DEFINE_NEW
nuclear@0 203 // DOM-IGNORE-END
nuclear@0 204 };
nuclear@0 205
nuclear@0 206
nuclear@0 207 template<class Base>
nuclear@0 208 class RefCountBaseStatVImpl : virtual public Base
nuclear@0 209 {
nuclear@0 210 public:
nuclear@0 211 RefCountBaseStatVImpl() { }
nuclear@0 212
nuclear@0 213 // *** Override New and Delete
nuclear@0 214
nuclear@0 215 // DOM-IGNORE-BEGIN
nuclear@0 216 // Undef new temporarily if it is being redefined
nuclear@0 217 #ifdef OVR_DEFINE_NEW
nuclear@0 218 #undef new
nuclear@0 219 #endif
nuclear@0 220
nuclear@0 221 #define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p)
nuclear@0 222
nuclear@0 223 // Redefine all new & delete operators.
nuclear@0 224 OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE)
nuclear@0 225
nuclear@0 226 #undef OVR_REFCOUNTALLOC_CHECK_DELETE
nuclear@0 227
nuclear@0 228 #ifdef OVR_DEFINE_NEW
nuclear@0 229 #define new OVR_DEFINE_NEW
nuclear@0 230 #endif
nuclear@0 231 // OVR_BUILD_DEFINE_NEW
nuclear@0 232 // DOM-IGNORE-END
nuclear@0 233 };
nuclear@0 234
nuclear@0 235
nuclear@0 236
nuclear@0 237 //-----------------------------------------------------------------------------------
nuclear@0 238 // *** End user RefCountBase<> classes
nuclear@0 239
nuclear@0 240
nuclear@0 241 // RefCountBase is a base class for classes that require thread-safe reference
nuclear@0 242 // counting; it also overrides the new and delete operators to use MemoryHeap.
nuclear@0 243 //
nuclear@0 244 // Reference counted objects start out with RefCount value of 1. Further lifetime
nuclear@0 245 // management is done through the AddRef() and Release() methods, typically
nuclear@0 246 // hidden by Ptr<>.
nuclear@0 247
nuclear@0 248 template<class C>
nuclear@0 249 class RefCountBase : public RefCountBaseStatImpl<RefCountImpl>
nuclear@0 250 {
nuclear@0 251 public:
nuclear@0 252 // Constructor.
nuclear@0 253 OVR_FORCE_INLINE RefCountBase() : RefCountBaseStatImpl<RefCountImpl>() { }
nuclear@0 254 };
nuclear@0 255
nuclear@0 256 // RefCountBaseV is the same as RefCountBase but with virtual AddRef/Release
nuclear@0 257
nuclear@0 258 template<class C>
nuclear@0 259 class RefCountBaseV : virtual public RefCountBaseStatVImpl<RefCountVImpl>
nuclear@0 260 {
nuclear@0 261 public:
nuclear@0 262 // Constructor.
nuclear@0 263 OVR_FORCE_INLINE RefCountBaseV() : RefCountBaseStatVImpl<RefCountVImpl>() { }
nuclear@0 264 };
nuclear@0 265
nuclear@0 266
nuclear@0 267 // RefCountBaseNTS is a base class for classes that require Non-Thread-Safe reference
nuclear@0 268 // counting; it also overrides the new and delete operators to use MemoryHeap.
nuclear@0 269 // This class should only be used if all pointers to it are known to be assigned,
nuclear@0 270 // destroyed and manipulated within one thread.
nuclear@0 271 //
nuclear@0 272 // Reference counted objects start out with RefCount value of 1. Further lifetime
nuclear@0 273 // management is done through the AddRef() and Release() methods, typically
nuclear@0 274 // hidden by Ptr<>.
nuclear@0 275
nuclear@0 276 template<class C>
nuclear@0 277 class RefCountBaseNTS : public RefCountBaseStatImpl<RefCountNTSImpl>
nuclear@0 278 {
nuclear@0 279 public:
nuclear@0 280 // Constructor.
nuclear@0 281 OVR_FORCE_INLINE RefCountBaseNTS() : RefCountBaseStatImpl<RefCountNTSImpl>() { }
nuclear@0 282 };
nuclear@0 283
nuclear@0 284 //-----------------------------------------------------------------------------------
nuclear@0 285 // ***** Pickable template pointer
nuclear@0 286 enum PickType { PickValue };
nuclear@0 287
nuclear@0 288 template <typename T>
nuclear@0 289 class Pickable
nuclear@0 290 {
nuclear@0 291 public:
nuclear@0 292 Pickable() : pV(NULL) {}
nuclear@0 293 explicit Pickable(T* p) : pV(p) {}
nuclear@0 294 Pickable(T* p, PickType) : pV(p)
nuclear@0 295 {
nuclear@0 296 OVR_ASSERT(pV);
nuclear@0 297 if (pV)
nuclear@0 298 pV->AddRef();
nuclear@0 299 }
nuclear@0 300 template <typename OT>
nuclear@0 301 Pickable(const Pickable<OT>& other) : pV(other.GetPtr()) {}
nuclear@0 302
nuclear@0 303 public:
nuclear@0 304 Pickable& operator =(const Pickable& other)
nuclear@0 305 {
nuclear@0 306 OVR_ASSERT(pV == NULL);
nuclear@0 307 pV = other.pV;
nuclear@0 308 // Extra check.
nuclear@0 309 //other.pV = NULL;
nuclear@0 310 return *this;
nuclear@0 311 }
nuclear@0 312
nuclear@0 313 public:
nuclear@0 314 T* GetPtr() const { return pV; }
nuclear@0 315 T* operator->() const
nuclear@0 316 {
nuclear@0 317 return pV;
nuclear@0 318 }
nuclear@0 319 T& operator*() const
nuclear@0 320 {
nuclear@0 321 OVR_ASSERT(pV);
nuclear@0 322 return *pV;
nuclear@0 323 }
nuclear@0 324
nuclear@0 325 private:
nuclear@0 326 T* pV;
nuclear@0 327 };
nuclear@0 328
nuclear@0 329 template <typename T>
nuclear@0 330 OVR_FORCE_INLINE
nuclear@0 331 Pickable<T> MakePickable(T* p)
nuclear@0 332 {
nuclear@0 333 return Pickable<T>(p);
nuclear@0 334 }
nuclear@0 335
nuclear@0 336 //-----------------------------------------------------------------------------------
nuclear@0 337 // ***** Ref-Counted template pointer
nuclear@0 338
nuclear@0 339 // Automatically AddRefs and Releases interfaces
nuclear@0 340
nuclear@0 341 void* ReturnArg0(void* p);
nuclear@0 342
nuclear@0 343 template<class C>
nuclear@0 344 class Ptr
nuclear@0 345 {
nuclear@0 346 #ifdef OVR_CC_ARM
nuclear@0 347 static C* ReturnArg(void* p) { return (C*)ReturnArg0(p); }
nuclear@0 348 #endif
nuclear@0 349
nuclear@0 350 protected:
nuclear@0 351 C *pObject;
nuclear@0 352
nuclear@0 353 public:
nuclear@0 354
nuclear@0 355 // Constructors
nuclear@0 356 OVR_FORCE_INLINE Ptr() : pObject(0)
nuclear@0 357 { }
nuclear@0 358 #ifdef OVR_CC_ARM
nuclear@0 359 OVR_FORCE_INLINE Ptr(C &robj) : pObject(ReturnArg(&robj))
nuclear@0 360 #else
nuclear@0 361 OVR_FORCE_INLINE Ptr(C &robj) : pObject(&robj)
nuclear@0 362 #endif
nuclear@0 363 { }
nuclear@0 364 OVR_FORCE_INLINE Ptr(Pickable<C> v) : pObject(v.GetPtr())
nuclear@0 365 {
nuclear@0 366 // No AddRef() on purpose.
nuclear@0 367 }
nuclear@0 368 OVR_FORCE_INLINE Ptr(Ptr<C>& other, PickType) : pObject(other.pObject)
nuclear@0 369 {
nuclear@0 370 other.pObject = NULL;
nuclear@0 371 // No AddRef() on purpose.
nuclear@0 372 }
nuclear@0 373 OVR_FORCE_INLINE Ptr(C *pobj)
nuclear@0 374 {
nuclear@0 375 if (pobj) pobj->AddRef();
nuclear@0 376 pObject = pobj;
nuclear@0 377 }
nuclear@0 378 OVR_FORCE_INLINE Ptr(const Ptr<C> &src)
nuclear@0 379 {
nuclear@0 380 if (src.pObject) src.pObject->AddRef();
nuclear@0 381 pObject = src.pObject;
nuclear@0 382 }
nuclear@0 383
nuclear@0 384 template<class R>
nuclear@0 385 OVR_FORCE_INLINE Ptr(Ptr<R> &src)
nuclear@0 386 {
nuclear@0 387 if (src) src->AddRef();
nuclear@0 388 pObject = src;
nuclear@0 389 }
nuclear@0 390 template<class R>
nuclear@0 391 OVR_FORCE_INLINE Ptr(Pickable<R> v) : pObject(v.GetPtr())
nuclear@0 392 {
nuclear@0 393 // No AddRef() on purpose.
nuclear@0 394 }
nuclear@0 395
nuclear@0 396 // Destructor
nuclear@0 397 OVR_FORCE_INLINE ~Ptr()
nuclear@0 398 {
nuclear@0 399 if (pObject) pObject->Release();
nuclear@0 400 }
nuclear@0 401
nuclear@0 402 // Compares
nuclear@0 403 OVR_FORCE_INLINE bool operator == (const Ptr &other) const { return pObject == other.pObject; }
nuclear@0 404 OVR_FORCE_INLINE bool operator != (const Ptr &other) const { return pObject != other.pObject; }
nuclear@0 405
nuclear@0 406 OVR_FORCE_INLINE bool operator == (C *pother) const { return pObject == pother; }
nuclear@0 407 OVR_FORCE_INLINE bool operator != (C *pother) const { return pObject != pother; }
nuclear@0 408
nuclear@0 409
nuclear@0 410 OVR_FORCE_INLINE bool operator < (const Ptr &other) const { return pObject < other.pObject; }
nuclear@0 411
nuclear@0 412 // Assignment
nuclear@0 413 template<class R>
nuclear@0 414 OVR_FORCE_INLINE const Ptr<C>& operator = (const Ptr<R> &src)
nuclear@0 415 {
nuclear@0 416 // By design we don't check for src == pObject, as we don't expect that to be the case the large majority of the time.
nuclear@0 417 if (src) src->AddRef();
nuclear@0 418 if (pObject) pObject->Release();
nuclear@0 419 pObject = src;
nuclear@0 420 return *this;
nuclear@0 421 }
nuclear@0 422 // Specialization
nuclear@0 423 OVR_FORCE_INLINE const Ptr<C>& operator = (const Ptr<C> &src)
nuclear@0 424 {
nuclear@0 425 if (src) src->AddRef();
nuclear@0 426 if (pObject) pObject->Release();
nuclear@0 427 pObject = src;
nuclear@0 428 return *this;
nuclear@0 429 }
nuclear@0 430
nuclear@0 431 OVR_FORCE_INLINE const Ptr<C>& operator = (C *psrc)
nuclear@0 432 {
nuclear@0 433 if (psrc) psrc->AddRef();
nuclear@0 434 if (pObject) pObject->Release();
nuclear@0 435 pObject = psrc;
nuclear@0 436 return *this;
nuclear@0 437 }
nuclear@0 438 OVR_FORCE_INLINE const Ptr<C>& operator = (C &src)
nuclear@0 439 {
nuclear@0 440 if (pObject) pObject->Release();
nuclear@0 441 pObject = &src;
nuclear@0 442 return *this;
nuclear@0 443 }
nuclear@0 444 OVR_FORCE_INLINE Ptr<C>& operator = (Pickable<C> src)
nuclear@0 445 {
nuclear@0 446 return Pick(src);
nuclear@0 447 }
nuclear@0 448 template<class R>
nuclear@0 449 OVR_FORCE_INLINE Ptr<C>& operator = (Pickable<R> src)
nuclear@0 450 {
nuclear@0 451 return Pick(src);
nuclear@0 452 }
nuclear@0 453
nuclear@0 454 // Set Assignment
nuclear@0 455 template<class R>
nuclear@0 456 OVR_FORCE_INLINE Ptr<C>& SetPtr(const Ptr<R> &src)
nuclear@0 457 {
nuclear@0 458 if (src) src->AddRef();
nuclear@0 459 if (pObject) pObject->Release();
nuclear@0 460 pObject = src;
nuclear@0 461 return *this;
nuclear@0 462 }
nuclear@0 463 // Specialization
nuclear@0 464 OVR_FORCE_INLINE Ptr<C>& SetPtr(const Ptr<C> &src)
nuclear@0 465 {
nuclear@0 466 if (src) src->AddRef();
nuclear@0 467 if (pObject) pObject->Release();
nuclear@0 468 pObject = src;
nuclear@0 469 return *this;
nuclear@0 470 }
nuclear@0 471
nuclear@0 472 OVR_FORCE_INLINE Ptr<C>& SetPtr(C *psrc)
nuclear@0 473 {
nuclear@0 474 if (psrc) psrc->AddRef();
nuclear@0 475 if (pObject) pObject->Release();
nuclear@0 476 pObject = psrc;
nuclear@0 477 return *this;
nuclear@0 478 }
nuclear@0 479 OVR_FORCE_INLINE Ptr<C>& SetPtr(C &src)
nuclear@0 480 {
nuclear@0 481 if (pObject) pObject->Release();
nuclear@0 482 pObject = &src;
nuclear@0 483 return *this;
nuclear@0 484 }
nuclear@0 485 OVR_FORCE_INLINE Ptr<C>& SetPtr(Pickable<C> src)
nuclear@0 486 {
nuclear@0 487 return Pick(src);
nuclear@0 488 }
nuclear@0 489
nuclear@0 490 // Nulls ref-counted pointer without decrement
nuclear@0 491 OVR_FORCE_INLINE void NullWithoutRelease()
nuclear@0 492 {
nuclear@0 493 pObject = 0;
nuclear@0 494 }
nuclear@0 495
nuclear@0 496 // Clears the pointer to the object
nuclear@0 497 OVR_FORCE_INLINE void Clear()
nuclear@0 498 {
nuclear@0 499 if (pObject) pObject->Release();
nuclear@0 500 pObject = 0;
nuclear@0 501 }
nuclear@0 502
nuclear@0 503 // Obtain pointer reference directly, for D3D interfaces
nuclear@0 504 OVR_FORCE_INLINE C*& GetRawRef() { return pObject; }
nuclear@0 505
nuclear@0 506 // Access Operators
nuclear@0 507 OVR_FORCE_INLINE C* GetPtr() const { return pObject; }
nuclear@0 508 OVR_FORCE_INLINE C& operator * () const { return *pObject; }
nuclear@0 509 OVR_FORCE_INLINE C* operator -> () const { return pObject; }
nuclear@0 510 // Conversion
nuclear@0 511 OVR_FORCE_INLINE operator C* () const { return pObject; }
nuclear@0 512
nuclear@0 513 // Pickers.
nuclear@0 514
nuclear@0 515 // Pick a value.
nuclear@0 516 OVR_FORCE_INLINE Ptr<C>& Pick(Ptr<C>& other)
nuclear@0 517 {
nuclear@0 518 if (&other != this)
nuclear@0 519 {
nuclear@0 520 if (pObject) pObject->Release();
nuclear@0 521 pObject = other.pObject;
nuclear@0 522 other.pObject = 0;
nuclear@0 523 }
nuclear@0 524
nuclear@0 525 return *this;
nuclear@0 526 }
nuclear@0 527
nuclear@0 528 OVR_FORCE_INLINE Ptr<C>& Pick(Pickable<C> v)
nuclear@0 529 {
nuclear@0 530 if (v.GetPtr() != pObject)
nuclear@0 531 {
nuclear@0 532 if (pObject) pObject->Release();
nuclear@0 533 pObject = v.GetPtr();
nuclear@0 534 }
nuclear@0 535
nuclear@0 536 return *this;
nuclear@0 537 }
nuclear@0 538
nuclear@0 539 template<class R>
nuclear@0 540 OVR_FORCE_INLINE Ptr<C>& Pick(Pickable<R> v)
nuclear@0 541 {
nuclear@0 542 if (v.GetPtr() != pObject)
nuclear@0 543 {
nuclear@0 544 if (pObject) pObject->Release();
nuclear@0 545 pObject = v.GetPtr();
nuclear@0 546 }
nuclear@0 547
nuclear@0 548 return *this;
nuclear@0 549 }
nuclear@0 550
nuclear@0 551 OVR_FORCE_INLINE Ptr<C>& Pick(C* p)
nuclear@0 552 {
nuclear@0 553 if (p != pObject)
nuclear@0 554 {
nuclear@0 555 if (pObject) pObject->Release();
nuclear@0 556 pObject = p;
nuclear@0 557 }
nuclear@0 558
nuclear@0 559 return *this;
nuclear@0 560 }
nuclear@0 561 };
nuclear@0 562
nuclear@0 563 } // OVR
nuclear@0 564
nuclear@0 565 #endif