WeakRefBase is now threadsafe and uses an actual weak_ptr to drive its logic, strongrefbase is next.
This commit is contained in:
marauder2k7 2026-02-22 00:02:20 +00:00
parent 1fed963d82
commit f1f09efbfa
6 changed files with 120 additions and 62 deletions

View file

@ -290,6 +290,7 @@ static void initRoot()
gNameDictionary = new SimManagerNameDictionary;
sgStreamingInstance = new SceneStreaming;
sgStreamingInstance->smStreaming = false;
gRootGroup = new SimGroup();
gRootGroup->incRefCount();
@ -631,20 +632,28 @@ void SimDataBlockGroup::sort()
void SceneStreaming::processTick()
{
if (true)
if (smPendingRegister.empty())
return;
U32 start = Platform::getRealMilliseconds();
while (!smPendingRegister.empty())
{
for (U32 i = 0; i < mMaxObjects && !smPendingRegister.empty(); i++)
{
SimObject* obj = smPendingRegister.first();
smPendingRegister.pop_front();
SimObject* obj = smPendingRegister.first();
smPendingRegister.pop_front();
Sim::gIdDictionary->insert(obj);
Sim::gIdDictionary->insert(obj);
Sim::gNameDictionary->insert(obj);
Sim::gNameDictionary->insert(obj);
if (!obj->onAdd())
obj->unregisterObject();
}
if (!obj->onAdd())
obj->unregisterObject();
U32 now = Platform::getRealMilliseconds();
if ((now - start) >= 2)
break;
}
}

View file

@ -46,6 +46,7 @@
#include "scene/sceneObject.h"
#include "T3D/camera.h"
#include "T3D/player.h"
#include "T3D/gameBase/gameConnection.h"
ImplementBitfieldType(GameTypeMasksType,
"The type of animation effect to apply to this material.\n"
@ -725,9 +726,7 @@ bool SimObject::registerObject()
AssertFatal(Sim::gIdDictionary && Sim::gNameDictionary,
"SimObject::registerObject - tried to register an object before Sim::init()!");
if (true && dynamic_cast<SceneObject*>(this) &&
!(dynamic_cast<Camera*>(this) || dynamic_cast<Player*>(this)) &&
if (Sim::sgStreamingInstance->smStreaming && dynamic_cast<SceneObject*>(this) &&
!gEditingMission
)
{

View file

@ -609,6 +609,7 @@ class SimObject: public ConsoleObject, public TamlCallbacks
/// @name Events
/// @{
//virtual void onPrepare();
/// Called when the object is added to the sim.
virtual bool onAdd();

View file

@ -0,0 +1,17 @@
#include "refBase.h"
WeakRefBase::~WeakRefBase()
{
if (mControl)
mControl->object = nullptr;
}
WeakControlBlock::WeakControlBlock(WeakRefBase* obj)
: object(obj)
{
}
WeakControlBlock::~WeakControlBlock()
{
}

View file

@ -29,7 +29,17 @@
#ifndef _TYPETRAITS_H_
# include "platform/typetraits.h"
#endif
#include <memory>
class WeakRefBase;
struct WeakControlBlock
{
explicit WeakControlBlock(WeakRefBase* obj);
~WeakControlBlock();
WeakRefBase* object;
};
/// Base class for objects which can be weakly referenced
/// (i.e., reference goes away when object is destroyed).
@ -37,45 +47,56 @@ class WeakRefBase
{
public:
/// Weak reference to WeakRefBase.
class WeakReference
{
public:
[[nodiscard]] constexpr WeakRefBase* get() const { return mObject; }
[[nodiscard]] constexpr U32 getRefCount() const { return mRefCount; }
constexpr void incRefCount() { mRefCount++; }
constexpr void decRefCount() {
AssertFatal( mRefCount > 0, "WeakReference - decrementing count of zero!" );
if (--mRefCount==0)
delete this;
WeakRefBase* get() const
{
auto locked = mWeak.lock();
return locked ? locked->object : NULL;
}
uint32_t getRefCount() const
{
return (uint32_t)mWeak.use_count();
}
void incRefCount() { /* compatibility no-op */ }
void decRefCount() { /* compatibility no-op */ }
private:
friend class WeakRefBase;
constexpr explicit WeakReference(WeakRefBase *object) :mObject(object), mRefCount(0) {}
~WeakReference() { AssertFatal(mObject==NULL, "Deleting weak reference which still points at an object."); }
explicit WeakReference(const std::shared_ptr<WeakControlBlock>& ctrl)
: mWeak(ctrl) {
}
// Object we reference
WeakRefBase *mObject;
// reference count for this structure (not WeakObjectRef itself)
U32 mRefCount;
std::weak_ptr<WeakControlBlock> mWeak;
};
public:
constexpr WeakRefBase() : mReference(NULL) {}
virtual ~WeakRefBase() { clearWeakReferences(); }
constexpr WeakRefBase() {}
virtual ~WeakRefBase();
WeakReference* getWeakReference();
WeakReference* getWeakReference()
{
ensureControl();
return new WeakReference(mControl);
}
protected:
void clearWeakReferences();
void ensureControl()
{
if (!mControl)
mControl = std::shared_ptr<WeakControlBlock>(new WeakControlBlock(this));
}
std::shared_ptr<WeakControlBlock> mControl;
private:
WeakReference * mReference;
};
template< typename T > class SimObjectPtr;
@ -192,7 +213,12 @@ class StrongRefBase : public WeakRefBase
friend class StrongObjectRef;
public:
StrongRefBase() { mRefCount = 0; }
StrongRefBase()
{
mRefCount = 0;
ensureControl();
mStrongControlRef = mControl;
}
U32 getRefCount() const { return mRefCount; }
@ -209,12 +235,13 @@ public:
void decRefCount()
{
AssertFatal(mRefCount, "Decrementing a reference with refcount 0!");
if(!--mRefCount)
if (!--mRefCount)
destroySelf();
}
protected:
U32 mRefCount; ///< reference counter for StrongRefPtr objects
std::shared_ptr<WeakControlBlock> mStrongControlRef;
};
/// Base class for StrongRefBase strong reference pointers.
@ -415,27 +442,25 @@ private:
};
//---------------------------------------------------------------
inline void WeakRefBase::clearWeakReferences()
{
if (mReference)
{
mReference->mObject = NULL;
mReference->decRefCount();
mReference = NULL;
}
}
inline WeakRefBase::WeakReference* WeakRefBase::getWeakReference()
{
if (!mReference)
{
mReference = new WeakReference(this);
mReference->incRefCount();
}
return mReference;
}
//inline void WeakRefBase::clearWeakReferences()
//{
// if (mReference)
// {
// mReference->mObject = NULL;
// mReference->decRefCount();
// mReference = NULL;
// }
//}
//
//inline WeakRefBase::WeakReference* WeakRefBase::getWeakReference()
//{
// if (!mReference)
// {
// mReference = new WeakReference(this);
// mReference->incRefCount();
// }
// return mReference;
//}
//---------------------------------------------------------------
template< typename T >

View file

@ -1651,10 +1651,17 @@ void GuiPopUpMenuCtrlEx::addChildren()
void GuiPopUpMenuCtrlEx::removeChildren()
{
mTl->deleteObject();
mSc->deleteObject();
mSearchEdit->deleteObject();
mBackground->deleteObject();
if (mTl && !mTl->isDeleted())
mTl->deleteObject();
if (mSc && !mSc->isDeleted())
mSc->deleteObject();
if (mSearchEdit && !mSearchEdit->isDeleted())
mSearchEdit->deleteObject();
if (mBackground && !mBackground->isDeleted())
mBackground->deleteObject();
}
//------------------------------------------------------------------------------