2929#ifndef _TYPETRAITS_H_
3030# include " platform/typetraits.h"
3131#endif
32+ #include < memory>
3233
34+ class WeakRefBase ;
35+
36+ struct WeakControlBlock
37+ {
38+ explicit WeakControlBlock (WeakRefBase* obj);
39+ ~WeakControlBlock ();
40+
41+ WeakRefBase* object;
42+ };
3343
3444// / Base class for objects which can be weakly referenced
3545// / (i.e., reference goes away when object is destroyed).
3646class WeakRefBase
3747{
3848public:
3949
40- // / Weak reference to WeakRefBase.
4150 class WeakReference
4251 {
4352 public:
4453
45- [[nodiscard]] constexpr WeakRefBase* get () const { return mObject ; }
46- [[nodiscard]] constexpr U32 getRefCount () const { return mRefCount ; }
54+ WeakRefBase* get () const
55+ {
56+ auto locked = mWeak .lock ();
57+ return locked ? locked->object : NULL ;
58+ }
4759
48- constexpr void incRefCount () { mRefCount ++; }
49- constexpr void decRefCount () {
50- AssertFatal ( mRefCount > 0 , " WeakReference - decrementing count of zero!" );
51- if (--mRefCount ==0 )
52- delete this ;
60+ uint32_t getRefCount () const
61+ {
62+ return (uint32_t )mWeak .use_count ();
5363 }
54- private:
5564
56- friend class WeakRefBase ;
57- constexpr explicit WeakReference (WeakRefBase *object) :mObject(object), mRefCount( 0 ) { }
65+ void incRefCount () { /* compatibility no-op */ }
66+ void decRefCount () { /* compatibility no-op */ }
5867
59- ~WeakReference () { AssertFatal (mObject ==NULL , " Deleting weak reference which still points at an object." ); }
68+ private:
69+ friend class WeakRefBase ;
6070
61- // Object we reference
62- WeakRefBase *mObject ;
71+ explicit WeakReference (const std::shared_ptr<WeakControlBlock>& ctrl)
72+ : mWeak(ctrl) {
73+ }
6374
64- // reference count for this structure (not WeakObjectRef itself)
65- U32 mRefCount ;
75+ std::weak_ptr<WeakControlBlock> mWeak ;
6676 };
6777
6878public:
69- constexpr WeakRefBase () : mReference( NULL ) {}
70- virtual ~WeakRefBase () { clearWeakReferences (); }
79+ constexpr WeakRefBase () {}
80+ virtual ~WeakRefBase ();
7181
72- WeakReference* getWeakReference ();
82+ WeakReference* getWeakReference ()
83+ {
84+ ensureControl ();
85+ return new WeakReference (mControl );
86+ }
7387
7488protected:
75- void clearWeakReferences ();
7689
90+ void ensureControl ()
91+ {
92+ if (!mControl )
93+ mControl = std::shared_ptr<WeakControlBlock>(new WeakControlBlock (this ));
94+ }
95+
96+ std::shared_ptr<WeakControlBlock> mControl ;
7797private:
78- WeakReference * mReference ;
98+
99+
79100};
80101
81102template < typename T > class SimObjectPtr ;
@@ -192,7 +213,12 @@ class StrongRefBase : public WeakRefBase
192213 friend class StrongObjectRef ;
193214
194215public:
195- StrongRefBase () { mRefCount = 0 ; }
216+ StrongRefBase ()
217+ {
218+ mRefCount = 0 ;
219+ ensureControl ();
220+ mStrongControlRef = mControl ;
221+ }
196222
197223 U32 getRefCount () const { return mRefCount ; }
198224
@@ -209,12 +235,13 @@ class StrongRefBase : public WeakRefBase
209235 void decRefCount ()
210236 {
211237 AssertFatal (mRefCount , " Decrementing a reference with refcount 0!" );
212- if (!--mRefCount )
238+ if (!--mRefCount )
213239 destroySelf ();
214240 }
215241
216242protected:
217243 U32 mRefCount ; // /< reference counter for StrongRefPtr objects
244+ std::shared_ptr<WeakControlBlock> mStrongControlRef ;
218245};
219246
220247// / Base class for StrongRefBase strong reference pointers.
@@ -415,27 +442,25 @@ class StrongWeakRefPtr
415442};
416443
417444// ---------------------------------------------------------------
418-
419- inline void WeakRefBase::clearWeakReferences ()
420- {
421- if (mReference )
422- {
423- mReference ->mObject = NULL ;
424- mReference ->decRefCount ();
425- mReference = NULL ;
426- }
427- }
428-
429- inline WeakRefBase::WeakReference* WeakRefBase::getWeakReference ()
430- {
431- if (!mReference )
432- {
433- mReference = new WeakReference (this );
434- mReference ->incRefCount ();
435- }
436- return mReference ;
437- }
438-
445+ // inline void WeakRefBase::clearWeakReferences()
446+ // {
447+ // if (mReference)
448+ // {
449+ // mReference->mObject = NULL;
450+ // mReference->decRefCount();
451+ // mReference = NULL;
452+ // }
453+ // }
454+ //
455+ // inline WeakRefBase::WeakReference* WeakRefBase::getWeakReference()
456+ // {
457+ // if (!mReference)
458+ // {
459+ // mReference = new WeakReference(this);
460+ // mReference->incRefCount();
461+ // }
462+ // return mReference;
463+ // }
439464// ---------------------------------------------------------------
440465
441466template < typename T >
0 commit comments