diff --git a/Source/Engine/Scripting/SoftObjectReference.h b/Source/Engine/Scripting/SoftObjectReference.h index e5c8cac28..39ef7946c 100644 --- a/Source/Engine/Scripting/SoftObjectReference.h +++ b/Source/Engine/Scripting/SoftObjectReference.h @@ -4,7 +4,6 @@ #include "Engine/Scripting/ScriptingObject.h" -// Don't include Scripting.h but just FindObject method extern FLAXENGINE_API ScriptingObject* FindObject(const Guid& id, MClass* type); /// @@ -12,10 +11,6 @@ extern FLAXENGINE_API ScriptingObject* FindObject(const Guid& id, MClass* type); /// class FLAXENGINE_API SoftObjectReferenceBase { -public: - - typedef Delegate<> EventType; - protected: ScriptingObject* _object = nullptr; @@ -26,7 +21,7 @@ public: /// /// Action fired when reference gets changed. /// - EventType Changed; + Delegate<> Changed; public: @@ -37,15 +32,6 @@ public: { } - /// - /// Initializes a new instance of the class. - /// - /// The object to link. - SoftObjectReferenceBase(ScriptingObject* obj) - { - OnSet(obj); - } - /// /// Finalizes an instance of the class. /// @@ -60,31 +46,43 @@ public: /// /// Gets the object ID. /// - /// The object ID or Guid::Empty if nothing assigned. Guid GetID() const { - return _object ? _object->GetID() : _id; + return _id; } protected: - /// - /// Sets the object. - /// - /// The object. void OnSet(ScriptingObject* object) { - auto e = _object; - if (e != object) - { - if (e) - e->Deleted.Unbind(this); - _object = e = object; - _id = e ? e->GetID() : Guid::Empty; - if (e) - e->Deleted.Bind(this); - Changed(); - } + if (_object == object) + return; + if (_object) + _object->Deleted.Unbind(this); + _object = object; + _id = object ? object->GetID() : Guid::Empty; + if (object) + object->Deleted.Bind(this); + Changed(); + } + + void OnSet(const Guid& id) + { + if (_id == id) + return; + if (_object) + _object->Deleted.Unbind(this); + _object = nullptr; + _id = id; + Changed(); + } + + void OnResolve(MClass* type) + { + ASSERT(!_object); + _object = FindObject(_id, type); + if (_object) + _object->Deleted.Bind(this); } void OnDeleted(ScriptingObject* obj) @@ -92,6 +90,7 @@ protected: ASSERT(_object == obj); _object->Deleted.Unbind(this); _object = nullptr; + _id = Guid::Empty; Changed(); } }; @@ -120,8 +119,8 @@ public: /// /// The object to link. SoftObjectReference(T* obj) - : SoftObjectReferenceBase(obj) { + OnSet((ScriptingObject*)obj); } /// @@ -129,8 +128,18 @@ public: /// /// The other property. SoftObjectReference(const SoftObjectReference& other) - : SoftObjectReferenceBase(other.Get()) { + OnSet(other.GetID()); + } + + /// + /// Initializes a new instance of the class. + /// + /// The other property. + SoftObjectReference(SoftObjectReference&& other) + { + OnSet(other.GetID()); + other.OnSet(nullptr); } /// @@ -142,133 +151,64 @@ public: public: - /// - /// Compares the property value with the given object. - /// - /// The other. - /// True if property object equals the given value. FORCE_INLINE bool operator==(T* other) { return Get() == other; } - - /// - /// Compares the property value with the other property value. - /// - /// The other property. - /// True if properties are equal. FORCE_INLINE bool operator==(const SoftObjectReference& other) { - return _id == other._id; + return GetID() == other.GetID(); } - - /// - /// Compares the property value with the given object. - /// - /// The other. - /// True if property object not equals the given value. FORCE_INLINE bool operator!=(T* other) { return Get() != other; } - - /// - /// Compares the property value with the other property value. - /// - /// The other property. - /// True if properties are not equal. FORCE_INLINE bool operator!=(const SoftObjectReference& other) { - return _id != other._id; + return GetID() != other.GetID(); } - - /// - /// Sets the property to the given property value. - /// - /// The other property. - /// The reference to this property. SoftObjectReference& operator=(const SoftObjectReference& other) { if (this != &other) - OnSet(other.Get()); + OnSet(other.GetID()); + return *this; + } + SoftObjectReference& operator=(SoftObjectReference&& other) + { + if (this != &other) + { + OnSet(other.GetID()); + other.OnSet(nullptr); + } return *this; } - - /// - /// Sets the property to the given value. - /// - /// The object. - /// The reference to this property. FORCE_INLINE SoftObjectReference& operator=(const T& other) { OnSet(&other); return *this; } - - /// - /// Sets the property to the given value. - /// - /// The object. - /// The reference to this property. FORCE_INLINE SoftObjectReference& operator=(T* other) { OnSet(other); return *this; } - - /// - /// Sets the property to the object of the given ID. - /// - /// The object ID. - /// The reference to this property. FORCE_INLINE SoftObjectReference& operator=(const Guid& id) { Set(id); return *this; } - - /// - /// Implicit conversion to the object. - /// - /// The object reference. FORCE_INLINE operator T*() const { return (T*)Get(); } - - /// - /// Implicit conversion to boolean value. - /// - /// True if object has been assigned, otherwise false FORCE_INLINE operator bool() const { - return _object != nullptr || _id.IsValid(); + return Get() != nullptr; } - - /// - /// Object accessor. - /// - /// The object reference. FORCE_INLINE T* operator->() const { return (T*)Get(); } - - /// - /// Gets the object pointer. - /// - /// The object reference. - T* Get() const - { - if (!_object) - const_cast(this)->OnSet(FindObject(_id, T::GetStaticClass())); - return (T*)_object; - } - - /// - /// Gets the object as a given type (static cast). - /// - /// Asset template FORCE_INLINE U* As() const { @@ -276,11 +216,20 @@ public: } public: + + /// + /// Gets the object (or null if unassigned). + /// + T* Get() const + { + if (!_object) + const_cast(this)->OnResolve(T::GetStaticClass()); + return (T*)_object; + } /// /// Gets managed instance object (or null if no object linked). /// - /// The managed object instance. MObject* GetManagedInstance() const { auto object = Get(); @@ -290,7 +239,6 @@ public: /// /// Determines whether object is assigned and managed instance of the object is alive. /// - /// True if managed object has been created and exists, otherwise false. bool HasManagedInstance() const { auto object = Get(); @@ -300,7 +248,6 @@ public: /// /// Gets the managed instance object or creates it if missing or null if not assigned. /// - /// The Mono managed object. MObject* GetOrCreateManagedInstance() const { auto object = Get(); @@ -311,10 +258,9 @@ public: /// Sets the object. /// /// The object ID. Uses Scripting to find the registered object of the given ID. - void Set(const Guid& id) + FORCE_INLINE void Set(const Guid& id) { - _id = id; - _object = nullptr; + OnSet(id); } ///