// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Scripting/ScriptingObject.h" // Don't include Scripting.h but just FindObject method extern FLAXENGINE_API ScriptingObject* FindObject(const Guid& id, MClass* type); /// /// The scripting object reference. /// /// The type of the scripting object. class FLAXENGINE_API ScriptingObjectReferenceBase { public: typedef Delegate<> EventType; protected: ScriptingObject* _object = nullptr; public: /// /// Action fired when reference gets changed. /// EventType Changed; public: /// /// Initializes a new instance of the class. /// ScriptingObjectReferenceBase() { } /// /// Initializes a new instance of the class. /// /// The object to link. ScriptingObjectReferenceBase(ScriptingObject* obj) { OnSet(obj); } /// /// Finalizes an instance of the class. /// ~ScriptingObjectReferenceBase() { if (_object) _object->Deleted.Unbind(this); } public: /// /// Gets the object ID. /// FORCE_INLINE Guid GetID() const { return _object ? _object->GetID() : Guid::Empty; } /// /// Gets managed instance object (or null if no object linked). /// FORCE_INLINE MObject* GetManagedInstance() const { return _object ? _object->GetOrCreateManagedInstance() : nullptr; } /// /// Determines whether object is assigned and managed instance of the object is alive. /// FORCE_INLINE bool HasManagedInstance() const { return _object && _object->HasManagedInstance(); } /// /// Gets the managed instance object or creates it if missing or null if not assigned. /// FORCE_INLINE MObject* GetOrCreateManagedInstance() const { return _object ? _object->GetOrCreateManagedInstance() : nullptr; } protected: /// /// Sets the object. /// /// The object. void OnSet(ScriptingObject* object); void OnDeleted(ScriptingObject* obj); }; /// /// The scripting object reference. /// template API_CLASS(InBuild) class ScriptingObjectReference : public ScriptingObjectReferenceBase { public: typedef ScriptingObjectReference Type; public: /// /// Initializes a new instance of the class. /// ScriptingObjectReference() { } /// /// Initializes a new instance of the class. /// /// The object to link. ScriptingObjectReference(T* obj) : ScriptingObjectReferenceBase(obj) { } /// /// Initializes a new instance of the class. /// /// The other property. ScriptingObjectReference(const ScriptingObjectReference& other) : ScriptingObjectReferenceBase(other._object) { } /// /// Finalizes an instance of the class. /// ~ScriptingObjectReference() { } public: FORCE_INLINE bool operator==(T* other) const { return _object == other; } FORCE_INLINE bool operator!=(T* other) const { return _object != other; } FORCE_INLINE bool operator==(const ScriptingObjectReference& other) const { return _object == other._object; } FORCE_INLINE bool operator!=(const ScriptingObjectReference& other) const { return _object != other._object; } FORCE_INLINE ScriptingObjectReference& operator=(T* other) { OnSet(other); return *this; } ScriptingObjectReference& operator=(const ScriptingObjectReference& other) { OnSet(other._object); return *this; } FORCE_INLINE ScriptingObjectReference& operator=(const Guid& id) { OnSet(static_cast(FindObject(id, T::GetStaticClass()))); return *this; } /// /// Implicit conversion to the object. /// FORCE_INLINE operator T*() const { return (T*)_object; } /// /// Implicit conversion to boolean value. /// FORCE_INLINE operator bool() const { return _object != nullptr; } /// /// Object accessor. /// FORCE_INLINE T* operator->() const { return (T*)_object; } /// /// Gets the object pointer. /// FORCE_INLINE T* Get() const { return (T*)_object; } /// /// Gets the object as a given type (static cast). /// template FORCE_INLINE U* As() const { return static_cast(_object); } }; template uint32 GetHash(const ScriptingObjectReference& key) { return GetHash(key.GetID()); }