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);
}
///