mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-14 16:14:38 +00:00
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:
parent
f1f09efbfa
commit
43e673d8ea
4 changed files with 166 additions and 164 deletions
|
|
@ -1053,17 +1053,17 @@ class SimObjectPtr : public WeakRefPtr< T >
|
||||||
|
|
||||||
typedef WeakRefPtr< T > Parent;
|
typedef WeakRefPtr< T > Parent;
|
||||||
|
|
||||||
SimObjectPtr() {}
|
SimObjectPtr() = default;
|
||||||
SimObjectPtr(T *ptr) { this->mReference = NULL; set(ptr); }
|
SimObjectPtr(T *ptr) { set(ptr); }
|
||||||
SimObjectPtr( const SimObjectPtr& ref ) { this->mReference = NULL; set(ref.mReference); }
|
SimObjectPtr( const SimObjectPtr& ref ) { this->mReference = ref.mReference; }
|
||||||
|
|
||||||
T* getObject() const { return Parent::getPointer(); }
|
T* getObject() const { return Parent::getPointer(); }
|
||||||
|
|
||||||
~SimObjectPtr() { set((WeakRefBase::WeakReference*)NULL); }
|
~SimObjectPtr() { mReference = NULL; }
|
||||||
|
|
||||||
SimObjectPtr<T>& operator=(const SimObjectPtr ref)
|
SimObjectPtr<T>& operator=(const SimObjectPtr ref)
|
||||||
{
|
{
|
||||||
set(ref.mReference);
|
mReference = ref.mReference;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
SimObjectPtr<T>& operator=(T *ptr)
|
SimObjectPtr<T>& operator=(T *ptr)
|
||||||
|
|
@ -1073,31 +1073,10 @@ class SimObjectPtr : public WeakRefPtr< T >
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
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)
|
void set(T * obj)
|
||||||
{
|
{
|
||||||
set(obj ? obj->getWeakReference() : (WeakRefBase::WeakReference *)NULL);
|
mReference = obj ? obj->getWeakReference() : nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
WeakRefBase::~WeakRefBase()
|
WeakRefBase::~WeakRefBase()
|
||||||
{
|
{
|
||||||
if (mControl)
|
if (mControl)
|
||||||
mControl->object = nullptr;
|
mControl->object = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
WeakControlBlock::WeakControlBlock(WeakRefBase* obj)
|
WeakControlBlock::WeakControlBlock(WeakRefBase* obj)
|
||||||
|
|
@ -15,3 +15,7 @@ WeakControlBlock::~WeakControlBlock()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WeakRefBase::WeakReference::~WeakReference()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,53 +50,71 @@ public:
|
||||||
class WeakReference
|
class WeakReference
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
~WeakReference();
|
||||||
|
|
||||||
WeakRefBase* get() const
|
WeakRefBase* get() const { return mStrong ? mStrong->object : NULL; }
|
||||||
{
|
|
||||||
auto locked = mWeak.lock();
|
|
||||||
return locked ? locked->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 incRefCount() { /* compatibility no-op */ }
|
||||||
void decRefCount() { /* compatibility no-op */ }
|
void decRefCount() { /* compatibility no-op */ }
|
||||||
|
|
||||||
|
explicit WeakReference(const std::shared_ptr<WeakControlBlock>& ctrl)
|
||||||
|
: mStrong(ctrl) {
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
friend class WeakRefBase;
|
friend class WeakRefBase;
|
||||||
|
std::shared_ptr<WeakControlBlock> mStrong;
|
||||||
explicit WeakReference(const std::shared_ptr<WeakControlBlock>& ctrl)
|
|
||||||
: mWeak(ctrl) {
|
|
||||||
}
|
|
||||||
|
|
||||||
std::weak_ptr<WeakControlBlock> mWeak;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr WeakRefBase() {}
|
WeakRefBase()
|
||||||
virtual ~WeakRefBase();
|
|
||||||
|
|
||||||
WeakReference* getWeakReference()
|
|
||||||
{
|
{
|
||||||
ensureControl();
|
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:
|
protected:
|
||||||
|
|
||||||
void ensureControl()
|
void ensureControl()
|
||||||
{
|
{
|
||||||
if (!mControl)
|
if (!mControl)
|
||||||
mControl = std::shared_ptr<WeakControlBlock>(new WeakControlBlock(this));
|
mControl = std::make_shared<WeakControlBlock>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<WeakControlBlock> mControl;
|
std::shared_ptr<WeakControlBlock> mControl;
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
std::shared_ptr<WeakReference> mReference;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename T > class SimObjectPtr;
|
template< typename T > class SimObjectPtr;
|
||||||
|
|
@ -109,29 +127,24 @@ template< typename T > class SimObjectPtr;
|
||||||
template <class T> class WeakRefPtr
|
template <class T> class WeakRefPtr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
constexpr WeakRefPtr() : mReference(NULL) {}
|
WeakRefPtr() = default;
|
||||||
WeakRefPtr(T *ptr) : mReference(NULL) { set(ptr); }
|
WeakRefPtr(T* obj) { set(obj); }
|
||||||
WeakRefPtr(const WeakRefPtr<T> & ref) { mReference = NULL; set(ref.mReference); }
|
WeakRefPtr(const WeakRefPtr& other) { mReference = other.mReference; }
|
||||||
|
|
||||||
~WeakRefPtr() { set(static_cast<WeakRefBase::WeakReference *>(NULL)); }
|
|
||||||
|
|
||||||
WeakRefPtr<T>& operator=(const WeakRefPtr<T>& ref)
|
WeakRefPtr& operator=(const WeakRefPtr& other)
|
||||||
{
|
{
|
||||||
if (this == &ref) { return *this; } // handle self assignment ( x = x; )
|
mReference = other.mReference;
|
||||||
set(ref.mReference);
|
return *this;
|
||||||
return *this;
|
}
|
||||||
}
|
|
||||||
WeakRefPtr<T>& operator=(T *ptr)
|
|
||||||
{
|
|
||||||
set(ptr);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if the pointer is not set.
|
WeakRefPtr& operator=(T* obj)
|
||||||
[[nodiscard]] constexpr bool isNull() const { return mReference == NULL || mReference->get() == NULL; }
|
{
|
||||||
|
set(obj);
|
||||||
/// Returns true if the pointer is set.
|
return *this;
|
||||||
[[nodiscard]] constexpr bool isValid() const { return mReference && mReference->get(); }
|
}
|
||||||
|
|
||||||
|
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(); }
|
||||||
[[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; }
|
[[nodiscard]] constexpr T* getPointer() const { return mReference ? (T*)mReference->get() : NULL; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void set(WeakRefBase::WeakReference* ref)
|
void set(T* obj)
|
||||||
{
|
{
|
||||||
if (mReference)
|
mReference = obj ? obj->getWeakReference() : NULL;
|
||||||
mReference->decRefCount();
|
}
|
||||||
mReference = NULL;
|
|
||||||
if (ref)
|
|
||||||
{
|
|
||||||
mReference = ref;
|
|
||||||
mReference->incRefCount();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(T* obj) { set(obj ? obj->getWeakReference() : NULL); }
|
|
||||||
private:
|
private:
|
||||||
template< typename > friend class SimObjectPtr;
|
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
|
/// 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).
|
/// when all strong references go away, object is destroyed).
|
||||||
class StrongRefBase : public WeakRefBase
|
class StrongRefBase : public WeakRefBase
|
||||||
{
|
{
|
||||||
friend class StrongObjectRef;
|
friend class StrongObjectRef;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StrongRefBase()
|
StrongRefBase()
|
||||||
{
|
{
|
||||||
mRefCount = 0;
|
mRefCount = 0;
|
||||||
ensureControl();
|
mReference = getWeakReference();
|
||||||
mStrongControlRef = mControl;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
U32 getRefCount() const { return mRefCount; }
|
virtual ~StrongRefBase() = default;
|
||||||
|
|
||||||
/// object destroy self call (from StrongRefPtr). Override if this class has specially allocated memory.
|
U32 getRefCount() const { return mRefCount; }
|
||||||
virtual void destroySelf() { delete this; }
|
|
||||||
|
|
||||||
/// Increments the reference count.
|
/// object destroy self call (from StrongRefPtr). Override if this class has specially allocated memory.
|
||||||
void incRefCount()
|
virtual void destroySelf() { delete this; }
|
||||||
{
|
|
||||||
mRefCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Decrements the reference count.
|
/// Increments the reference count.
|
||||||
void decRefCount()
|
void incRefCount()
|
||||||
{
|
{
|
||||||
AssertFatal(mRefCount, "Decrementing a reference with refcount 0!");
|
mRefCount++;
|
||||||
if (!--mRefCount)
|
}
|
||||||
destroySelf();
|
|
||||||
}
|
/// Decrements the reference count.
|
||||||
|
void decRefCount()
|
||||||
|
{
|
||||||
|
AssertFatal(mRefCount, "Decrementing a reference with refcount 0!");
|
||||||
|
if (!--mRefCount)
|
||||||
|
destroySelf();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
U32 mRefCount; ///< reference counter for StrongRefPtr objects
|
U32 mRefCount; ///< reference counter for StrongRefPtr objects
|
||||||
std::shared_ptr<WeakControlBlock> mStrongControlRef;
|
std::shared_ptr<WeakRefBase::WeakReference> mReference;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// Base class for StrongRefBase strong reference pointers.
|
/// Base class for StrongRefBase strong reference pointers.
|
||||||
class StrongObjectRef
|
class StrongObjectRef
|
||||||
{
|
{
|
||||||
|
|
@ -374,71 +380,53 @@ private:
|
||||||
/// StrongWeakRefs that keep object live as long as the superior entity doesn't
|
/// 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
|
/// step in and kill them (in which case, the client code sees the reference
|
||||||
/// disappear).
|
/// disappear).
|
||||||
template< class T >
|
template<class T>
|
||||||
class StrongWeakRefPtr
|
class StrongWeakRefPtr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
constexpr StrongWeakRefPtr() : mReference( NULL ) {}
|
constexpr StrongWeakRefPtr() = default;
|
||||||
constexpr StrongWeakRefPtr( T* ptr ) : mReference( NULL ) { _set( ptr ); }
|
StrongWeakRefPtr(T* ptr) { set(ptr); }
|
||||||
~StrongWeakRefPtr()
|
StrongWeakRefPtr(const StrongWeakRefPtr& other) { mReference = other.mReference; }
|
||||||
{
|
|
||||||
if( mReference )
|
|
||||||
{
|
|
||||||
T* ptr = _get();
|
|
||||||
if( ptr )
|
|
||||||
ptr->decRefCount();
|
|
||||||
|
|
||||||
mReference->decRefCount();
|
~StrongWeakRefPtr() = default; // no manual decRefCount needed
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] constexpr bool isNull() const { return ( _get() == NULL ); }
|
StrongWeakRefPtr& operator=(T* ptr)
|
||||||
[[nodiscard]] constexpr bool operator ==( T* ptr ) const { return ( _get() == ptr ); }
|
{
|
||||||
[[nodiscard]] constexpr bool operator !=( T* ptr ) const { return ( _get() != ptr ); }
|
set(ptr);
|
||||||
[[nodiscard]] constexpr bool operator !() const { return isNull(); }
|
return *this;
|
||||||
[[nodiscard]] constexpr T* operator ->() const { return _get(); }
|
}
|
||||||
[[nodiscard]] constexpr T& operator *() const { return *( _get() ); }
|
|
||||||
|
|
||||||
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 )
|
[[nodiscard]] T* operator->() const { return getPointer(); }
|
||||||
{
|
[[nodiscard]] T& operator*() const { return *getPointer(); }
|
||||||
_set( ptr );
|
constexpr operator T* () const { return getPointer(); }
|
||||||
return *this;
|
|
||||||
}
|
T* getPointer() const { return mReference ? static_cast<T*>(mReference->get()) : NULL; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WeakRefBase::WeakReference* mReference;
|
std::shared_ptr<typename WeakRefBase::WeakReference> mReference;
|
||||||
|
|
||||||
T* _get() const
|
void set(T* ptr)
|
||||||
{
|
{
|
||||||
if( mReference )
|
if (ptr)
|
||||||
return static_cast< T* >( mReference->get() );
|
{
|
||||||
else
|
mReference = ptr->getWeakReference(); // shared_ptr returned
|
||||||
return NULL;
|
}
|
||||||
}
|
else
|
||||||
void _set( T* ptr )
|
{
|
||||||
{
|
mReference.reset();
|
||||||
if( mReference )
|
}
|
||||||
{
|
}
|
||||||
T* old = _get();
|
|
||||||
if( old )
|
|
||||||
old->decRefCount();
|
|
||||||
|
|
||||||
mReference->decRefCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ptr )
|
|
||||||
{
|
|
||||||
ptr->incRefCount();
|
|
||||||
mReference = ptr->getWeakReference();
|
|
||||||
mReference->incRefCount();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mReference = NULL;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,38 @@ public:
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
// Data
|
// 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, NormalMap, GFXNormalMapProfile, MAX_STAGES)
|
||||||
DECLARE_IMAGEASSET_ARRAY(Material, DetailNormalMap, GFXNormalMapProfile, MAX_STAGES)
|
DECLARE_IMAGEASSET_ARRAY(Material, DetailNormalMap, GFXNormalMapProfile, MAX_STAGES)
|
||||||
DECLARE_IMAGEASSET_ARRAY(Material, OverlayMap, GFXStaticTextureProfile, MAX_STAGES)
|
DECLARE_IMAGEASSET_ARRAY(Material, OverlayMap, GFXStaticTextureProfile, MAX_STAGES)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue