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
|