17 #ifndef INC_KY_Kernel_RefCount_H
18 #define INC_KY_Kernel_RefCount_H
36 template<
class C,
int StatType>
38 template<
class C,
int StatType>
39 class RefCountBaseNTS;
40 template<
class C,
int StatType>
41 class RefCountBaseWeakSupport;
44 class RefCountNTSImpl;
45 class RefCountWeakSupportImpl;
58 #define KY_REFCOUNT_NORMAL 0x00000000
59 #define KY_REFCOUNT_THREADSAFE 0x00000001
67 class RefCountImplCore
70 volatile int RefCount;
74 KY_INLINE RefCountImplCore() : RefCount(1) { }
79 KY_EXPORT
virtual ~RefCountImplCore();
82 int GetRefCount()
const {
return RefCount; }
88 static void KY_CDECL reportInvalidDelete(
void *pmem);
89 inline static void checkInvalidDelete(RefCountImplCore *pmem)
91 if (pmem->RefCount != 0)
92 reportInvalidDelete(pmem);
95 inline static void checkInvalidDelete(RefCountImplCore *) { }
99 RefCountImplCore(
const RefCountImplCore &) : RefCount(1) { }
100 void operator = (
const RefCountImplCore &) { }
103 class RefCountNTSImplCore
106 mutable int RefCount;
110 KY_INLINE RefCountNTSImplCore() : RefCount(1) { }
115 KY_EXPORT
virtual ~RefCountNTSImplCore();
118 int GetRefCount()
const {
return RefCount; }
123 #ifdef KY_BUILD_DEBUG
124 static void KY_CDECL reportInvalidDelete(
void *pmem);
125 KY_INLINE
static void checkInvalidDelete(RefCountNTSImplCore *pmem)
127 if (pmem->RefCount != 0)
128 reportInvalidDelete(pmem);
131 KY_INLINE
static void checkInvalidDelete(RefCountNTSImplCore *) { }
135 RefCountNTSImplCore(
const RefCountNTSImplCore &) : RefCount(1) { }
136 void operator = (
const RefCountNTSImplCore &) { }
144 class RefCountImpl :
public RefCountImplCore
148 KY_EXPORT
void AddRef();
149 KY_EXPORT
void Release();
155 class RefCountVImpl :
public RefCountImplCore
159 virtual void AddRef();
160 virtual void Release();
167 class RefCountNTSImpl :
public RefCountNTSImplCore
170 KY_INLINE
void AddRef()
const { RefCount++; }
171 KY_EXPORT
void Release()
const;
179 class RefCountWeakSupportImpl :
public RefCountNTSImpl
182 mutable WeakPtrProxy* pWeakProxy;
184 RefCountWeakSupportImpl() { pWeakProxy = 0; }
185 KY_EXPORT
virtual ~RefCountWeakSupportImpl();
188 WeakPtrProxy* CreateWeakProxy()
const;
195 template<
class Base,
int StatType>
196 class RefCountBaseStatImpl :
public Base
199 RefCountBaseStatImpl() { }
205 #ifdef KY_BUILD_DEFINE_NEW
211 #ifdef KY_BUILD_DEBUG
213 #define KY_REFCOUNTALLOC_CHECK_DELETE(class_name, p) \
214 do {if (p) Base::checkInvalidDelete((class_name*)p); } while(0)
216 #define KY_REFCOUNTALLOC_CHECK_DELETE(class_name, p)
220 KY_MEMORY_REDEFINE_NEW_IMPL(Base, KY_REFCOUNTALLOC_CHECK_DELETE, StatType)
223 #define new KY_DEFINE_NEW
242 template<
class C,
int Stat>
243 class RefCountBase :
public RefCountBaseStatImpl<RefCountImpl, Stat>
246 enum { StatType = Stat };
248 KY_INLINE RefCountBase() : RefCountBaseStatImpl<RefCountImpl, Stat>() { }
253 template<
class C,
int Stat>
254 class RefCountBaseV :
public RefCountBaseStatImpl<RefCountVImpl, Stat>
257 enum { StatType = Stat };
259 KY_INLINE RefCountBaseV() : RefCountBaseStatImpl<RefCountVImpl, Stat>() { }
272 template<
class C,
int Stat>
273 class RefCountBaseNTS :
public RefCountBaseStatImpl<RefCountNTSImpl, Stat>
276 enum { StatType = Stat };
278 KY_INLINE RefCountBaseNTS() : RefCountBaseStatImpl<RefCountNTSImpl, Stat>() { }
290 template<
class C,
int Stat>
291 class RefCountBaseWeakSupport :
public RefCountBaseStatImpl<RefCountWeakSupportImpl, Stat>
294 enum { StatType = Stat };
296 KY_INLINE RefCountBaseWeakSupport() : RefCountBaseStatImpl<RefCountWeakSupportImpl, Stat>() { }
302 enum PickType { PickValue };
304 template <
typename T>
308 Pickable() : pV(NULL) {}
309 explicit Pickable(T* p) : pV(p) {}
310 Pickable(T* p, PickType) : pV(p)
316 template <
typename OT>
317 Pickable(
const Pickable<OT>& other) : pV(other.GetPtr()) {}
320 Pickable& operator =(
const Pickable& other)
322 KY_ASSERT(pV == NULL);
330 T* GetPtr()
const {
return pV; }
331 T* operator->()
const
345 template <
typename T>
347 Pickable<T> MakePickable(T* p)
349 return Pickable<T>(p);
356 void* ReturnArg0(
void* p);
362 static C* ReturnArg(
void* p) {
return (C*)ReturnArg0(p); }
371 KY_INLINE Ptr() : pObject(0)
374 KY_INLINE Ptr(C &robj) : pObject(ReturnArg(&robj))
376 KY_INLINE Ptr(C &robj) : pObject(&robj)
379 KY_INLINE Ptr(Pickable<C> v) : pObject(v.GetPtr())
383 KY_INLINE Ptr(Ptr<C>& other, PickType) : pObject(other.pObject)
385 other.pObject = NULL;
388 KY_INLINE Ptr(C *pobj)
390 if (pobj) pobj->AddRef();
393 KY_INLINE Ptr(
const Ptr<C> &src)
395 if (src.pObject) src.pObject->AddRef();
396 pObject = src.pObject;
400 KY_INLINE Ptr(Ptr<R> &src)
402 if (src) src->AddRef();
406 KY_INLINE Ptr(Pickable<R> v) : pObject(v.GetPtr())
414 if (pObject) pObject->Release();
418 KY_INLINE
bool operator == (
const Ptr &other)
const {
return pObject == other.pObject; }
419 KY_INLINE
bool operator != (
const Ptr &other)
const {
return pObject != other.pObject; }
421 KY_INLINE
bool operator == (C *pother)
const {
return pObject == pother; }
422 KY_INLINE
bool operator != (C *pother)
const {
return pObject != pother; }
425 KY_INLINE
bool operator < (
const Ptr &other)
const {
return pObject < other.pObject; }
429 KY_INLINE
const Ptr<C>& operator = (
const Ptr<R> &src)
431 if (src) src->AddRef();
432 if (pObject) pObject->Release();
437 KY_INLINE
const Ptr<C>& operator = (
const Ptr<C> &src)
439 if (src) src->AddRef();
440 if (pObject) pObject->Release();
445 KY_INLINE
const Ptr<C>& operator = (C *psrc)
447 if (psrc) psrc->AddRef();
448 if (pObject) pObject->Release();
452 KY_INLINE
const Ptr<C>& operator = (C &src)
454 if (pObject) pObject->Release();
458 KY_INLINE Ptr<C>& operator = (Pickable<C> src)
463 KY_INLINE Ptr<C>& operator = (Pickable<R> src)
470 KY_INLINE Ptr<C>& SetPtr(
const Ptr<R> &src)
472 if (src) src->AddRef();
473 if (pObject) pObject->Release();
478 KY_INLINE Ptr<C>& SetPtr(
const Ptr<C> &src)
480 if (src) src->AddRef();
481 if (pObject) pObject->Release();
486 KY_INLINE Ptr<C>& SetPtr(C *psrc)
488 if (psrc) psrc->AddRef();
489 if (pObject) pObject->Release();
493 KY_INLINE Ptr<C>& SetPtr(C &src)
495 if (pObject) pObject->Release();
499 KY_INLINE Ptr<C>& SetPtr(Pickable<C> src)
505 KY_INLINE
void NullWithoutRelease()
511 KY_INLINE
void Clear()
513 if (pObject) pObject->Release();
518 KY_INLINE C*& GetRawRef() {
return pObject; }
521 KY_INLINE C* GetPtr()
const {
return pObject; }
522 KY_INLINE C&
operator * ()
const {
return *pObject; }
523 KY_INLINE C* operator -> ()
const {
return pObject; }
525 KY_INLINE
operator C* ()
const {
return pObject; }
530 KY_INLINE Ptr<C>& Pick(Ptr<C>& other)
534 if (pObject) pObject->Release();
535 pObject = other.pObject;
542 KY_INLINE Ptr<C>& Pick(Pickable<C> v)
544 if (v.GetPtr() != pObject)
546 if (pObject) pObject->Release();
547 pObject = v.GetPtr();
554 KY_INLINE Ptr<C>& Pick(Pickable<R> v)
556 if (v.GetPtr() != pObject)
558 if (pObject) pObject->Release();
559 pObject = v.GetPtr();
565 KY_INLINE Ptr<C>& Pick(C* p)
569 if (pObject) pObject->Release();
584 class WeakPtrProxy :
public NewOverrideBase<Stat_Default_Mem>
587 WeakPtrProxy(RefCountWeakSupportImpl* pobject)
588 : RefCount(1), pObject(pobject)
592 KY_INLINE
bool IsAlive()
const {
return (pObject != 0); }
595 KY_INLINE
void NotifyObjectDied() { pObject = 0; }
597 RefCountWeakSupportImpl* GetObject()
const {
return pObject; }
599 KY_INLINE
void AddRef()
606 KY_INLINE
void Release()
618 WeakPtrProxy(
const WeakPtrProxy& w) { KY_UNUSED(w); }
619 void operator=(
const WeakPtrProxy& w) { KY_UNUSED(w); }
622 RefCountWeakSupportImpl* pObject;
645 KY_INLINE WeakPtr(C* ptr)
646 : pProxy(*(ptr ? ptr->CreateWeakProxy() : (WeakPtrProxy*)0))
648 KY_INLINE WeakPtr(
const Ptr<C>& ptr)
649 : pProxy(*(ptr.GetPtr() ? ptr->CreateWeakProxy() : (WeakPtrProxy*)0))
653 KY_INLINE
void operator = (C* ptr)
657 pProxy = *ptr->CreateWeakProxy();
665 KY_INLINE
void operator = (
const Ptr<C>& ptr)
666 { operator=(ptr.GetPtr()); }
669 inline operator Ptr<C>()
const
671 return Ptr<C>(GetObjectThroughProxy());
674 KY_INLINE
bool operator == (C* ptr)
675 {
return GetObjectThroughProxy() == ptr; }
676 KY_INLINE
bool operator == (
const Ptr<C>& ptr)
677 {
return GetObjectThroughProxy() == ptr.GetPtr(); }
682 KY_INLINE C* GetObjectThroughProxy()
const
688 if (pProxy->IsAlive())
690 pobject = (C*)pProxy->GetObject();
701 mutable Ptr<WeakPtrProxy> pProxy;
Definition: gamekitcrowddispersion.h:20
Vec2f operator*(KyFloat32 s, const Vec2f &v)
Multiplies the X and Y coordinates of v by s.
Definition: vec2f.h:184