ref pointers

TODO: Cleanup

WeakRefBase lifetime is now controlled by a shared_ptr and a control block
objects now act like shared and weakptrs so they free themselves without any outside involvement, last of an objects reference goes out of scope object deletes.
This commit is contained in:
marauder2k7 2026-02-22 23:37:08 +00:00
parent f1f09efbfa
commit 43e673d8ea
4 changed files with 166 additions and 164 deletions

View file

@ -1053,17 +1053,17 @@ class SimObjectPtr : public WeakRefPtr< T >
typedef WeakRefPtr< T > Parent;
SimObjectPtr() {}
SimObjectPtr(T *ptr) { this->mReference = NULL; set(ptr); }
SimObjectPtr( const SimObjectPtr& ref ) { this->mReference = NULL; set(ref.mReference); }
SimObjectPtr() = default;
SimObjectPtr(T *ptr) { set(ptr); }
SimObjectPtr( const SimObjectPtr& ref ) { this->mReference = ref.mReference; }
T* getObject() const { return Parent::getPointer(); }
~SimObjectPtr() { set((WeakRefBase::WeakReference*)NULL); }
~SimObjectPtr() { mReference = NULL; }
SimObjectPtr<T>& operator=(const SimObjectPtr ref)
{
set(ref.mReference);
mReference = ref.mReference;
return *this;
}
SimObjectPtr<T>& operator=(T *ptr)
@ -1073,31 +1073,10 @@ class SimObjectPtr : public WeakRefPtr< T >
}
protected:
void set(WeakRefBase::WeakReference * ref)
{
if( ref == this->mReference )
return;
if( this->mReference )
{
// Auto-delete
T* obj = this->getPointer();
if ( this->mReference->getRefCount() == 2 && obj && obj->isAutoDeleted() )
obj->deleteObject();
this->mReference->decRefCount();
}
this->mReference = NULL;
if( ref )
{
this->mReference = ref;
this->mReference->incRefCount();
}
}
void set(T * obj)
{
set(obj ? obj->getWeakReference() : (WeakRefBase::WeakReference *)NULL);
mReference = obj ? obj->getWeakReference() : nullptr;
}
};

View file

@ -3,7 +3,7 @@
WeakRefBase::~WeakRefBase()
{
if (mControl)
mControl->object = nullptr;
mControl->object = NULL;
}
WeakControlBlock::WeakControlBlock(WeakRefBase* obj)
@ -15,3 +15,7 @@ WeakControlBlock::~WeakControlBlock()
{
}
WeakRefBase::WeakReference::~WeakReference()
{
}

View file

@ -50,53 +50,71 @@ public:
class WeakReference
{
public:
~WeakReference();
WeakRefBase* get() const
{
auto locked = mWeak.lock();
return locked ? locked->object : NULL;
}
WeakRefBase* get() const { return mStrong ? mStrong->object : NULL; }
uint32_t getRefCount() const
U32 getRefCount() const
{
return (uint32_t)mWeak.use_count();
return (U32)mStrong.use_count();
}
void incRefCount() { /* compatibility no-op */ }
void decRefCount() { /* compatibility no-op */ }
explicit WeakReference(const std::shared_ptr<WeakControlBlock>& ctrl)
: mStrong(ctrl) {
}
private:
friend class WeakRefBase;
explicit WeakReference(const std::shared_ptr<WeakControlBlock>& ctrl)
: mWeak(ctrl) {
}
std::weak_ptr<WeakControlBlock> mWeak;
std::shared_ptr<WeakControlBlock> mStrong;
};
public:
constexpr WeakRefBase() {}
virtual ~WeakRefBase();
WeakReference* getWeakReference()
WeakRefBase()
{
ensureControl();
return new WeakReference(mControl);
}
virtual ~WeakRefBase();
// Copy constructor
WeakRefBase(const WeakRefBase& other)
{
mControl = other.mControl;
mReference = std::make_unique<WeakReference>(mControl);
}
// Copy assignment
WeakRefBase& operator=(const WeakRefBase& other)
{
if (this != &other)
{
mControl = other.mControl;
mReference = std::make_unique<WeakReference>(mControl);
}
return *this;
}
std::shared_ptr<WeakReference> getWeakReference()
{
if (!mReference)
mReference = std::make_shared<WeakReference>(mControl);
return mReference;
}
protected:
void ensureControl()
{
if (!mControl)
mControl = std::shared_ptr<WeakControlBlock>(new WeakControlBlock(this));
if (!mControl)
mControl = std::make_shared<WeakControlBlock>(this);
}
std::shared_ptr<WeakControlBlock> mControl;
private:
std::shared_ptr<WeakReference> mReference;
};
template< typename T > class SimObjectPtr;
@ -109,29 +127,24 @@ template< typename T > class SimObjectPtr;
template <class T> class WeakRefPtr
{
public:
constexpr WeakRefPtr() : mReference(NULL) {}
WeakRefPtr(T *ptr) : mReference(NULL) { set(ptr); }
WeakRefPtr(const WeakRefPtr<T> & ref) { mReference = NULL; set(ref.mReference); }
~WeakRefPtr() { set(static_cast<WeakRefBase::WeakReference *>(NULL)); }
WeakRefPtr() = default;
WeakRefPtr(T* obj) { set(obj); }
WeakRefPtr(const WeakRefPtr& other) { mReference = other.mReference; }
WeakRefPtr<T>& operator=(const WeakRefPtr<T>& ref)
{
if (this == &ref) { return *this; } // handle self assignment ( x = x; )
set(ref.mReference);
return *this;
}
WeakRefPtr<T>& operator=(T *ptr)
{
set(ptr);
return *this;
}
WeakRefPtr& operator=(const WeakRefPtr& other)
{
mReference = other.mReference;
return *this;
}
/// Returns true if the pointer is not set.
[[nodiscard]] constexpr bool isNull() const { return mReference == NULL || mReference->get() == NULL; }
/// Returns true if the pointer is set.
[[nodiscard]] constexpr bool isValid() const { return mReference && mReference->get(); }
WeakRefPtr& operator=(T* obj)
{
set(obj);
return *this;
}
bool isValid() const { return mReference && mReference->get(); }
bool isNull() const { return !isValid(); }
[[nodiscard]] constexpr T* operator->() const { return getPointer(); }
[[nodiscard]] constexpr T& operator*() const { return *getPointer(); }
@ -141,22 +154,13 @@ public:
[[nodiscard]] constexpr T* getPointer() const { return mReference ? (T*)mReference->get() : NULL; }
protected:
void set(WeakRefBase::WeakReference* ref)
{
if (mReference)
mReference->decRefCount();
mReference = NULL;
if (ref)
{
mReference = ref;
mReference->incRefCount();
}
}
void set(T* obj) { set(obj ? obj->getWeakReference() : NULL); }
void set(T* obj)
{
mReference = obj ? obj->getWeakReference() : NULL;
}
private:
template< typename > friend class SimObjectPtr;
WeakRefBase::WeakReference * mReference {NULL};
std::shared_ptr<WeakRefBase::WeakReference> mReference;
};
/// Union of an arbitrary type with a WeakRefBase. The exposed type will
@ -210,40 +214,42 @@ private:
/// when all strong references go away, object is destroyed).
class StrongRefBase : public WeakRefBase
{
friend class StrongObjectRef;
friend class StrongObjectRef;
public:
StrongRefBase()
{
mRefCount = 0;
ensureControl();
mStrongControlRef = mControl;
}
StrongRefBase()
{
mRefCount = 0;
mReference = getWeakReference();
}
U32 getRefCount() const { return mRefCount; }
virtual ~StrongRefBase() = default;
/// object destroy self call (from StrongRefPtr). Override if this class has specially allocated memory.
virtual void destroySelf() { delete this; }
U32 getRefCount() const { return mRefCount; }
/// Increments the reference count.
void incRefCount()
{
mRefCount++;
}
/// object destroy self call (from StrongRefPtr). Override if this class has specially allocated memory.
virtual void destroySelf() { delete this; }
/// Decrements the reference count.
void decRefCount()
{
AssertFatal(mRefCount, "Decrementing a reference with refcount 0!");
if (!--mRefCount)
destroySelf();
}
/// Increments the reference count.
void incRefCount()
{
mRefCount++;
}
/// Decrements the reference count.
void decRefCount()
{
AssertFatal(mRefCount, "Decrementing a reference with refcount 0!");
if (!--mRefCount)
destroySelf();
}
protected:
U32 mRefCount; ///< reference counter for StrongRefPtr objects
std::shared_ptr<WeakControlBlock> mStrongControlRef;
U32 mRefCount; ///< reference counter for StrongRefPtr objects
std::shared_ptr<WeakRefBase::WeakReference> mReference;
};
/// Base class for StrongRefBase strong reference pointers.
class StrongObjectRef
{
@ -374,71 +380,53 @@ private:
/// StrongWeakRefs that keep object live as long as the superior entity doesn't
/// step in and kill them (in which case, the client code sees the reference
/// disappear).
template< class T >
template<class T>
class StrongWeakRefPtr
{
public:
constexpr StrongWeakRefPtr() : mReference( NULL ) {}
constexpr StrongWeakRefPtr( T* ptr ) : mReference( NULL ) { _set( ptr ); }
~StrongWeakRefPtr()
{
if( mReference )
{
T* ptr = _get();
if( ptr )
ptr->decRefCount();
constexpr StrongWeakRefPtr() = default;
StrongWeakRefPtr(T* ptr) { set(ptr); }
StrongWeakRefPtr(const StrongWeakRefPtr& other) { mReference = other.mReference; }
mReference->decRefCount();
}
}
~StrongWeakRefPtr() = default; // no manual decRefCount needed
[[nodiscard]] constexpr bool isNull() const { return ( _get() == NULL ); }
[[nodiscard]] constexpr bool operator ==( T* ptr ) const { return ( _get() == ptr ); }
[[nodiscard]] constexpr bool operator !=( T* ptr ) const { return ( _get() != ptr ); }
[[nodiscard]] constexpr bool operator !() const { return isNull(); }
[[nodiscard]] constexpr T* operator ->() const { return _get(); }
[[nodiscard]] constexpr T& operator *() const { return *( _get() ); }
StrongWeakRefPtr& operator=(T* ptr)
{
set(ptr);
return *this;
}
constexpr operator T*() const { return _get(); } // consider making this explicit
StrongWeakRefPtr& operator=(const StrongWeakRefPtr& other)
{
mReference = other.mReference;
return *this;
}
T* getPointer() const { return _get(); }
[[nodiscard]] bool isNull() const { return !mReference || !mReference->get(); }
[[nodiscard]] bool operator==(T* ptr) const { return getPointer() == ptr; }
[[nodiscard]] bool operator!=(T* ptr) const { return getPointer() != ptr; }
[[nodiscard]] bool operator!() const { return isNull(); }
StrongWeakRefPtr& operator =( T* ptr )
{
_set( ptr );
return *this;
}
[[nodiscard]] T* operator->() const { return getPointer(); }
[[nodiscard]] T& operator*() const { return *getPointer(); }
constexpr operator T* () const { return getPointer(); }
T* getPointer() const { return mReference ? static_cast<T*>(mReference->get()) : NULL; }
private:
WeakRefBase::WeakReference* mReference;
std::shared_ptr<typename WeakRefBase::WeakReference> mReference;
T* _get() const
{
if( mReference )
return static_cast< T* >( mReference->get() );
else
return NULL;
}
void _set( T* ptr )
{
if( mReference )
{
T* old = _get();
if( old )
old->decRefCount();
mReference->decRefCount();
}
if( ptr )
{
ptr->incRefCount();
mReference = ptr->getWeakReference();
mReference->incRefCount();
}
else
mReference = NULL;
}
void set(T* ptr)
{
if (ptr)
{
mReference = ptr->getWeakReference(); // shared_ptr returned
}
else
{
mReference.reset();
}
}
};
//---------------------------------------------------------------

View file

@ -216,7 +216,38 @@ public:
//-----------------------------------------------------------------------
// Data
//-----------------------------------------------------------------------
DECLARE_IMAGEASSET_ARRAY(Material, DiffuseMap, GFXStaticTextureSRGBProfile, MAX_STAGES)
private: AssetPtr<ImageAsset> mDiffuseMapAsset[MAX_STAGES]; StringTableEntry mDiffuseMapFile[MAX_STAGES] = { _getStringTable()->EmptyString() }; public: void _setDiffuseMap(StringTableEntry _in, const U32& index) {
if (mDiffuseMapAsset[index].getAssetId() == _in) return; if (getDiffuseMapFile(index) == _in) return; if (_in == 0 || !String::compare(_in, _getStringTable()->EmptyString())) {
mDiffuseMapAsset[index] = 0; mDiffuseMapFile[index] = ""; return;
} if (!AssetDatabase.isDeclaredAsset(_in)) {
StringTableEntry imageAssetId = _getStringTable()->EmptyString(); AssetQuery query; S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, _in); if (foundAssetcount != 0) {
imageAssetId = query.mAssetList[0];
}
else if (Torque::FS::IsFile(_in) || (_in[0] == '$' || _in[0] == '#')) {
imageAssetId = ImageAsset::getAssetIdByFilename(_in); if (imageAssetId == ImageAsset::smNoImageAssetFallback) {
ImageAsset* privateImage = new ImageAsset(); privateImage->setImageFile(_in); imageAssetId = AssetDatabase.addPrivateAsset(privateImage);
}
}
else {
Con::warnf("%s::%s: Could not find asset for: %s using fallback", "Material", "DiffuseMap", _in); imageAssetId = ImageAsset::smNoImageAssetFallback;
} mDiffuseMapAsset[index] = imageAssetId; mDiffuseMapFile[index] = _in;
}
else {
mDiffuseMapAsset[index] = _in; mDiffuseMapFile[index] = getDiffuseMapFile(index);
}
}; inline StringTableEntry _getDiffuseMap(const U32& index) const {
return mDiffuseMapAsset[index].getAssetId();
} GFXTexHandle getDiffuseMap(const U32& index) {
return getDiffuseMap(&GFXStaticTextureSRGBProfile, index);
} GFXTexHandle getDiffuseMap(GFXTextureProfile* requestedProfile, const U32& index) {
return mDiffuseMapAsset[index].notNull() ? mDiffuseMapAsset[index]->getTexture(requestedProfile) : 0;
} AssetPtr<ImageAsset> getDiffuseMapAsset(const U32& index) {
return mDiffuseMapAsset[index];
} static bool _setDiffuseMapData(void* obj, const char* index, const char* data) {
static_cast<Material*>(obj)->_setDiffuseMap(_getStringTable()->insert(data), dAtoi(index)); return false;
} StringTableEntry getDiffuseMapFile(const U32& idx) {
return mDiffuseMapAsset[idx].notNull() ? mDiffuseMapAsset[idx]->getImageFile() : "";
}
DECLARE_IMAGEASSET_ARRAY(Material, NormalMap, GFXNormalMapProfile, MAX_STAGES)
DECLARE_IMAGEASSET_ARRAY(Material, DetailNormalMap, GFXNormalMapProfile, MAX_STAGES)
DECLARE_IMAGEASSET_ARRAY(Material, OverlayMap, GFXStaticTextureProfile, MAX_STAGES)