Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 67 additions & 25 deletions Core/Libraries/Source/WWVegas/WWLib/ref_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,15 @@
copying.

To create a RefCountPtr<T> from a raw pointer, use the global template functions
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
Create_No_Add_Ref should be used when wrapping a pointer that has just been created with NEW
Create_No_Add_Ref 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_AddRef should be used when wrapping a pointer that has been returned from a "Peek" function
Create_Add_Ref 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_NoAddRef and Create_AddRef are provided to allow old code to migrate from manual reference count
Create_No_Add_Ref and Create_Add_Ref 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_NoAddRef and Create_AddRef.
Create_No_Add_Ref and Create_Add_Ref.

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
Expand Down Expand Up @@ -217,21 +217,23 @@ class RefCountPtr

// Creates a RefCountPtr<T> 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<T> Create_NoAddRef(T *t)
// Prefer using Assign_No_Add_Ref.
static RefCountPtr<T> Create_No_Add_Ref(T *t)
{
WWASSERT(t == nullptr || t->Num_Refs() >= 1);
return RefCountPtr<T>(t, RefCountPtr<T>::GET);
}

// Creates a RefCountPtr<T> and increments the reference counter of the passed object.
// Is generally used for objects returned by "Peek" functions.
static RefCountPtr<T> Create_AddRef(T *t)
// Prefer using Assign_Add_Ref.
static RefCountPtr<T> Create_Add_Ref(T *t)
{
return RefCountPtr<T>(t, RefCountPtr<T>::PEEK);
}

RefCountPtr()
: Referent(0)
: Referent(nullptr)
{
}

Expand All @@ -247,9 +249,9 @@ class RefCountPtr
// This allows construction of the smart pointer from 0 (null)
// Without allows unwanted conversions from T * (and related types, including void *)
RefCountPtr(DummyPtrType * dummy)
: Referent(0)
: Referent(nullptr)
{
WWASSERT(dummy == 0);
WWASSERT(dummy == nullptr);
}
#endif

Expand Down Expand Up @@ -292,12 +294,41 @@ class RefCountPtr
Referent->Release_Ref();
}

Referent = 0;
Referent = nullptr;

return *this;
}
#endif


// Assigns a pointer T and does not increment the reference counter of the passed object.
// Is generally used for objects returned by operator new and "Get" functions.
void Assign_No_Add_Ref(T *t)
{
WWASSERT(t == nullptr || t->Num_Refs() >= 1);

if (Referent) {
Referent->Release_Ref();
}

Referent = t;
}

// Assigns a pointer T and increments the reference counter of the passed object.
// Is generally used for objects returned by "Peek" functions.
void Assign_Add_Ref(T *t)
{
if (t != nullptr) {
t->Add_Ref();
}

if (Referent) {
Referent->Release_Ref();
}

Referent = t;
}

template <class RHS>
const RefCountPtr<T> & operator =(const RefCountPtr<RHS> & rhs)
{
Expand All @@ -320,7 +351,6 @@ class RefCountPtr
rhs.Referent->Add_Ref();
}


if (Referent) {
Referent->Release_Ref();
}
Expand All @@ -333,7 +363,7 @@ class RefCountPtr
{
if (Referent) {
Referent->Release_Ref();
Referent = 0;
Referent = nullptr;
}
}

Expand All @@ -353,7 +383,7 @@ class RefCountPtr
{
if (Referent) {
Referent->Release_Ref();
Referent = 0;
Referent = nullptr;
}
}

Expand All @@ -380,7 +410,7 @@ class RefCountPtr
T * Release()
{
T * p = Referent;
Referent = 0;
Referent = nullptr;
return p;
}

Expand All @@ -390,7 +420,7 @@ class RefCountPtr
RefCountPtr(T * referent, ReferenceHandling reference_handling)
: Referent(referent)
{
if (reference_handling == PEEK && 0 != referent) {
if (reference_handling == PEEK && nullptr != referent) {
referent->Add_Ref();
}
}
Expand All @@ -412,34 +442,46 @@ bool operator <(const RefCountPtr<LHS> & lhs, const RefCountPtr<RHS> & rhs)
return lhs.Peek() < rhs.Peek();
}

// This comparison allows us to test our smart pointer against 0 using
// 0 == my_ptr
// This comparison allows us to test our smart pointer against null using
// nullptr == my_ptr
template <class RHS>
bool operator ==(DummyPtrType * dummy, const RefCountPtr<RHS> & rhs)
{
if (0 != dummy) {
if (nullptr != dummy) {
WWASSERT(0);
return false;
}

return 0 == rhs.Peek();
return nullptr == rhs.Peek();
}

// This comparison allows us to test our smart pointer against 0 using
// 0 != my_ptr
// This comparison allows us to test our smart pointer against null using
// nullptr != my_ptr
template <class RHS>
bool operator !=(DummyPtrType * dummy, const RefCountPtr<RHS> & rhs)
{
if (0 != dummy) {
if (nullptr != dummy) {
WWASSERT(0);
return true;
}

return 0 != rhs.Peek();
return nullptr != rhs.Peek();
}

template <class Derived, class Base>
RefCountPtr<Derived> Static_Cast(const RefCountPtr<Base> & base)
{
return RefCountPtr<Derived>::Create_AddRef((Derived *)base.Peek());
return RefCountPtr<Derived>::Create_Add_Ref(static_cast<Derived *>(base.Peek()));
}

template <class T>
RefCountPtr<T> Create_Add_Ref(T *ptr)
{
return RefCountPtr<T>::Create_Add_Ref(ptr);
}

template <class T>
RefCountPtr<T> Create_No_Add_Ref(T *ptr)
{
return RefCountPtr<T>::Create_No_Add_Ref(ptr);
}
2 changes: 1 addition & 1 deletion Generals/Code/GameEngine/Source/Common/StateMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,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<StateMachine> refThis = RefCountPtr<StateMachine>::Create_AddRef(this);
RefCountPtr<StateMachine> refThis = Create_Add_Ref(this);

// update() can change m_currentState, so save it for a moment...
State* stateBeforeUpdate = m_currentState;
Expand Down
3 changes: 2 additions & 1 deletion Generals/Code/GameEngine/Source/GameLogic/AI/AI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,8 @@ AIGroupPtr AI::createGroup()
#if RETAIL_COMPATIBLE_AIGROUP
AIGroup *group = newInstance(AIGroup);
#else
AIGroupPtr group = AIGroupPtr::Create_NoAddRef(newInstance(AIGroup));
AIGroupPtr group;
group.Assign_No_Add_Ref(newInstance(AIGroup));
#endif

// add it to the list
Expand Down
6 changes: 3 additions & 3 deletions Generals/Code/GameEngine/Source/GameLogic/AI/AIGroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ Bool AIGroup::remove( Object *obj )
{
#if !RETAIL_COMPATIBLE_AIGROUP
// Defer deletion until the end of this function.
AIGroupPtr refThis = AIGroupPtr::Create_AddRef(this);
AIGroupPtr refThis = Create_Add_Ref(this);
#endif

// DEBUG_LOG(("***AIGROUP %x is removing Object %x (%s).", this, obj, obj->getTemplate()->getName().str()));
Expand Down Expand Up @@ -250,7 +250,7 @@ void AIGroup::removeAll()
{
#if !RETAIL_COMPATIBLE_AIGROUP
// Defer deletion until the end of this function.
AIGroupPtr refThis = AIGroupPtr::Create_AddRef(this);
AIGroupPtr refThis = Create_Add_Ref(this);
#endif

std::list<Object *> memberList;
Expand Down Expand Up @@ -2762,7 +2762,7 @@ void AIGroup::groupSell( CommandSourceType cmdSource )
{
#if !RETAIL_COMPATIBLE_AIGROUP
// Defer deletion until the end of this function.
AIGroupPtr refThis = AIGroupPtr::Create_AddRef(this);
AIGroupPtr refThis = Create_Add_Ref(this);
#endif

std::list<Object *>::iterator i;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5613,7 +5613,7 @@ void Object::enterGroup( AIGroup *group )
#if RETAIL_COMPATIBLE_AIGROUP
m_group = group;
#else
m_group = AIGroupPtr::Create_AddRef(group);
m_group.Assign_Add_Ref(group);
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion GeneralsMD/Code/GameEngine/Source/Common/StateMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,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<StateMachine> refThis = RefCountPtr<StateMachine>::Create_AddRef(this);
RefCountPtr<StateMachine> refThis = Create_Add_Ref(this);

// update() can change m_currentState, so save it for a moment...
State* stateBeforeUpdate = m_currentState;
Expand Down
3 changes: 2 additions & 1 deletion GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,8 @@ AIGroupPtr AI::createGroup()
#if RETAIL_COMPATIBLE_AIGROUP
AIGroup *group = newInstance(AIGroup);
#else
AIGroupPtr group = AIGroupPtr::Create_NoAddRef(newInstance(AIGroup));
AIGroupPtr group;
group.Assign_No_Add_Ref(newInstance(AIGroup));
#endif

// add it to the list
Expand Down
6 changes: 3 additions & 3 deletions GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIGroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ Bool AIGroup::remove( Object *obj )
{
#if !RETAIL_COMPATIBLE_AIGROUP
// Defer deletion until the end of this function.
AIGroupPtr refThis = AIGroupPtr::Create_AddRef(this);
AIGroupPtr refThis = Create_Add_Ref(this);
#endif

// DEBUG_LOG(("***AIGROUP %x is removing Object %x (%s).", this, obj, obj->getTemplate()->getName().str()));
Expand Down Expand Up @@ -250,7 +250,7 @@ void AIGroup::removeAll()
{
#if !RETAIL_COMPATIBLE_AIGROUP
// Defer deletion until the end of this function.
AIGroupPtr refThis = AIGroupPtr::Create_AddRef(this);
AIGroupPtr refThis = Create_Add_Ref(this);
#endif

std::list<Object *> memberList;
Expand Down Expand Up @@ -2835,7 +2835,7 @@ void AIGroup::groupSell( CommandSourceType cmdSource )
{
#if !RETAIL_COMPATIBLE_AIGROUP
// Defer deletion until the end of this function.
AIGroupPtr refThis = AIGroupPtr::Create_AddRef(this);
AIGroupPtr refThis = Create_Add_Ref(this);
#endif

std::list<Object *>::iterator i;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6456,7 +6456,7 @@ void Object::enterGroup( AIGroup *group )
#if RETAIL_COMPATIBLE_AIGROUP
m_group = group;
#else
m_group = AIGroupPtr::Create_AddRef(group);
m_group.Assign_Add_Ref(group);
#endif
}

Expand Down
Loading