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; gNameDictionary = new SimManagerNameDictionary;
sgStreamingInstance = new SceneStreaming; sgStreamingInstance = new SceneStreaming;
sgStreamingInstance->smStreaming = false; sgStreamingInstance->smStreaming = false;
gRootGroup = new SimGroup(); gRootGroup = new SimGroup();
gRootGroup->incRefCount(); gRootGroup->incRefCount();
@ -631,20 +632,28 @@ void SimDataBlockGroup::sort()
void SceneStreaming::processTick() 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()) if (!obj->onAdd())
obj->unregisterObject(); obj->unregisterObject();
}
U32 now = Platform::getRealMilliseconds();
if ((now - start) >= 2)
break;
} }
} }

View file

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

View file

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

View file

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