diff --git a/Core/Libraries/Source/WWVegas/WWLib/ref_ptr.h b/Core/Libraries/Source/WWVegas/WWLib/ref_ptr.h index 0e66d434cd6..8bbffff8ec7 100644 --- a/Core/Libraries/Source/WWVegas/WWLib/ref_ptr.h +++ b/Core/Libraries/Source/WWVegas/WWLib/ref_ptr.h @@ -138,15 +138,15 @@ copying. To create a RefCountPtr from a raw pointer, use the global template functions - Create_NEW should be used when wrapping a pointer that has just been created with NEW - Create_Get should be used when wrapping a pointer that has been returned from a "Get" function + Create_NoAddRef should be used when wrapping a pointer that has just been created with NEW + Create_NoAddRef should be used when wrapping a pointer that has been returned from a "Get" function (the function added a reference prior to returning the pointer) - Create_Peek should be used when wrapping a pointer that has been returned from a "Peek" function + Create_AddRef should be used when wrapping a pointer that has been returned from a "Peek" function (the function did not add a reference prior to returning the pointer). - Create_Get and Create_Peek are provided to allow old code to migrate from manual reference count + Create_NoAddRef and Create_AddRef are provided to allow old code to migrate from manual reference count management to RefCountPtr. New code written with RefCountPtr should rarely if ever use - Create_Get and Create_Peek. + Create_NoAddRef and Create_AddRef. If it is absolutely necessary to extract the raw pointer, use Peek. Peek does not add a new reference to the object. Using a Peek'd object after its RefCountPtr has gone out of scope requires @@ -158,7 +158,7 @@ Automatic construction of a RefCountPtr from a raw pointer is enabled if ALLOW_AUTOMATIC_REF_COUNT_PTR_CONSTRUCTION is defined. - This may be useful when migrating existing code to use RefCountPtr, but is completely safe, + This may be useful when migrating existing code to use RefCountPtr, but is not completely safe, since it is not possible to determine if the pointer is being Get'd or Peek'd. Please note that the constructor WILL add a reference to the object, which errs on the side of leaking references rather than prematurely deleting objects. Whenever possible, use the @@ -216,7 +216,6 @@ }; */ -#define ALLOW_AUTOMATIC_REF_COUNT_PTR_CONSTRUCTION class DummyPtrType; @@ -224,17 +223,18 @@ template class RefCountPtr { public: - friend RefCountPtr Create_NEW(T *t) - { - return RefCountPtr(t, RefCountPtr::GET); - } - friend RefCountPtr Create_Get(T *t) + // Creates a RefCountPtr and does not increment the reference counter of the passed object. + // Is generally used for objects returned by operator new and "Get" functions. + static RefCountPtr Create_NoAddRef(T *t) { + WWASSERT(t == NULL || t->Num_Refs() >= 1); return RefCountPtr(t, RefCountPtr::GET); } - friend RefCountPtr Create_Peek(T *t) + // Creates a RefCountPtr and increments the reference counter of the passed object. + // Is generally used for objects returned by "Peek" functions. + static RefCountPtr Create_AddRef(T *t) { return RefCountPtr(t, RefCountPtr::PEEK); } @@ -373,20 +373,28 @@ class RefCountPtr T & operator *(void) const { - G_ASSERT(0 != Referent); + WWASSERT(0 != Referent); return *Referent; } - // Note : This should typiccally only be used when mixing code that uses RefCountPtr and + // Note : This should typically only be used when mixing code that uses RefCountPtr and // manually managed ref counts on raw points. - // Code that consistently uses RefCountPtr should never get ahold of a raw T* + // Code that consistently uses RefCountPtr should never get a hold of a raw T* T * Peek(void) const { return Referent; } + // Releases the held pointer without changing its reference counter. + T * Release(void) + { + T * p = Referent; + Referent = 0; + return p; + } + private: - enum ReferenceHandling { GET, PEEK}; + enum ReferenceHandling { GET, PEEK }; RefCountPtr(T * referent, ReferenceHandling reference_handling) : Referent(referent) @@ -442,7 +450,7 @@ bool operator !=(DummyPtrType * dummy, const RefCountPtr & rhs) template RefCountPtr Static_Cast(const RefCountPtr & base) { - return Create_Peek((Derived *)base.Peek()); + return RefCountPtr::Create_AddRef((Derived *)base.Peek()); } #endif diff --git a/Core/Libraries/Source/WWVegas/WWLib/refcount.h b/Core/Libraries/Source/WWVegas/WWLib/refcount.h index 340f78b58de..41a5789a739 100644 --- a/Core/Libraries/Source/WWVegas/WWLib/refcount.h +++ b/Core/Libraries/Source/WWVegas/WWLib/refcount.h @@ -48,6 +48,8 @@ #include "LISTNODE.H" #endif +#include "wwdebug.h" + class RefCountClass; @@ -148,7 +150,7 @@ class RefCountClass Dec_Total_Refs(this); #endif NumRefs--; - assert(NumRefs >= 0); + WWASSERT(NumRefs >= 0); if (NumRefs == 0) const_cast(this)->Delete_This(); } @@ -182,7 +184,7 @@ class RefCountClass #ifndef NDEBUG Remove_Active_Ref(this); #endif - assert(NumRefs == 0); + WWASSERT(NumRefs == 0); } private: diff --git a/Generals/Code/GameEngine/Source/Common/StateMachine.cpp b/Generals/Code/GameEngine/Source/Common/StateMachine.cpp index 2bc58351b11..71f4fea7a01 100644 --- a/Generals/Code/GameEngine/Source/Common/StateMachine.cpp +++ b/Generals/Code/GameEngine/Source/Common/StateMachine.cpp @@ -439,7 +439,7 @@ StateReturnType StateMachine::updateStateMachine() // Calling m_currentState->update() can release this state machine in certain circumstances, // for example if something kills the entity of this state machine as a result of this state update. // See https://github.com/TheSuperHackers/GeneralsGameCode/issues/212 - RefCountPtr refThis(this); + RefCountPtr refThis = RefCountPtr::Create_AddRef(this); // update() can change m_currentState, so save it for a moment... State* stateBeforeUpdate = m_currentState; diff --git a/GeneralsMD/Code/GameEngine/Source/Common/StateMachine.cpp b/GeneralsMD/Code/GameEngine/Source/Common/StateMachine.cpp index 3a453729888..7c4de27d48b 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/StateMachine.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/StateMachine.cpp @@ -439,7 +439,7 @@ StateReturnType StateMachine::updateStateMachine() // Calling m_currentState->update() can release this state machine in certain circumstances, // for example if something kills the entity of this state machine as a result of this state update. // See https://github.com/TheSuperHackers/GeneralsGameCode/issues/212 - RefCountPtr refThis(this); + RefCountPtr refThis = RefCountPtr::Create_AddRef(this); // update() can change m_currentState, so save it for a moment... State* stateBeforeUpdate = m_currentState;