From 43e673d8ead7928ac9f1a2dd0e1790e766d642f7 Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Sun, 22 Feb 2026 23:37:08 +0000 Subject: [PATCH] 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. --- Engine/source/console/simObject.h | 33 +-- Engine/source/core/util/refBase.cpp | 6 +- Engine/source/core/util/refBase.h | 258 +++++++++---------- Engine/source/materials/materialDefinition.h | 33 ++- 4 files changed, 166 insertions(+), 164 deletions(-) diff --git a/Engine/source/console/simObject.h b/Engine/source/console/simObject.h index b056907da..2e35be56b 100644 --- a/Engine/source/console/simObject.h +++ b/Engine/source/console/simObject.h @@ -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& operator=(const SimObjectPtr ref) { - set(ref.mReference); + mReference = ref.mReference; return *this; } SimObjectPtr& 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; } }; diff --git a/Engine/source/core/util/refBase.cpp b/Engine/source/core/util/refBase.cpp index 833c89530..64e3db1b7 100644 --- a/Engine/source/core/util/refBase.cpp +++ b/Engine/source/core/util/refBase.cpp @@ -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() +{ +} diff --git a/Engine/source/core/util/refBase.h b/Engine/source/core/util/refBase.h index bc5149e89..694a4cfa8 100644 --- a/Engine/source/core/util/refBase.h +++ b/Engine/source/core/util/refBase.h @@ -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& ctrl) + : mStrong(ctrl) { + } private: friend class WeakRefBase; - - explicit WeakReference(const std::shared_ptr& ctrl) - : mWeak(ctrl) { - } - - std::weak_ptr mWeak; + std::shared_ptr 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(mControl); + } + + // Copy assignment + WeakRefBase& operator=(const WeakRefBase& other) + { + if (this != &other) + { + mControl = other.mControl; + mReference = std::make_unique(mControl); + } + return *this; + } + + std::shared_ptr getWeakReference() + { + if (!mReference) + mReference = std::make_shared(mControl); + return mReference; } protected: void ensureControl() { - if (!mControl) - mControl = std::shared_ptr(new WeakControlBlock(this)); + if (!mControl) + mControl = std::make_shared(this); } - std::shared_ptr mControl; private: + + std::shared_ptr mReference; - }; template< typename T > class SimObjectPtr; @@ -109,29 +127,24 @@ template< typename T > class SimObjectPtr; template class WeakRefPtr { public: - constexpr WeakRefPtr() : mReference(NULL) {} - WeakRefPtr(T *ptr) : mReference(NULL) { set(ptr); } - WeakRefPtr(const WeakRefPtr & ref) { mReference = NULL; set(ref.mReference); } - - ~WeakRefPtr() { set(static_cast(NULL)); } + WeakRefPtr() = default; + WeakRefPtr(T* obj) { set(obj); } + WeakRefPtr(const WeakRefPtr& other) { mReference = other.mReference; } - WeakRefPtr& operator=(const WeakRefPtr& ref) - { - if (this == &ref) { return *this; } // handle self assignment ( x = x; ) - set(ref.mReference); - return *this; - } - WeakRefPtr& 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 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 mStrongControlRef; + U32 mRefCount; ///< reference counter for StrongRefPtr objects + std::shared_ptr 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 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(mReference->get()) : NULL; } private: - WeakRefBase::WeakReference* mReference; + std::shared_ptr 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(); + } + } }; //--------------------------------------------------------------- diff --git a/Engine/source/materials/materialDefinition.h b/Engine/source/materials/materialDefinition.h index abaec1583..6cf433f0c 100644 --- a/Engine/source/materials/materialDefinition.h +++ b/Engine/source/materials/materialDefinition.h @@ -216,7 +216,38 @@ public: //----------------------------------------------------------------------- // Data //----------------------------------------------------------------------- - DECLARE_IMAGEASSET_ARRAY(Material, DiffuseMap, GFXStaticTextureSRGBProfile, MAX_STAGES) + private: AssetPtr 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 getDiffuseMapAsset(const U32& index) { + return mDiffuseMapAsset[index]; + } static bool _setDiffuseMapData(void* obj, const char* index, const char* data) { + static_cast(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)