// Copyright (c) Wojciech Figat. All rights reserved. #pragma once #include "Engine/Scripting/SoftObjectReference.h" #include "Engine/Scripting/ScriptingObjectInterfaceReferenceUtils.h" /// /// The scene object soft interface reference. Objects gets referenced on use (ID reference is resolving it). /// /// The type of the scripting interface. template API_CLASS(InBuild) class SoftObjectInterfaceReference : public SoftObjectReferenceBase { typedef ScriptingObjectInterfaceReferenceHelper Helper; public: typedef SoftObjectInterfaceReference Type; public: /// /// Initializes a new instance of the class. /// SoftObjectInterfaceReference() { } /// /// Initializes a new instance of the class. /// /// The object to link. SoftObjectInterfaceReference(SceneObject* obj) { OnSet(Helper::IsValidObject(obj) ? obj : nullptr); } /// /// Initializes a new instance of the class. /// /// The interface object to link. SoftObjectInterfaceReference(T* interfaceObj) { OnSet(Helper::GetSceneObject(interfaceObj)); } /// /// Initializes a new instance of the class. /// /// The other property. SoftObjectInterfaceReference(const SoftObjectInterfaceReference& other) { OnSet(other.GetID()); } /// /// Initializes a new instance of the class. /// /// The other property. SoftObjectInterfaceReference(SoftObjectInterfaceReference&& other) { OnSet(other.GetID()); other.OnSet(nullptr); } /// /// Finalizes an instance of the class. /// ~SoftObjectInterfaceReference() { } public: FORCE_INLINE bool operator==(SceneObject* other) { return GetObject() == other; } FORCE_INLINE bool operator!=(SceneObject* other) { return GetObject() != other; } FORCE_INLINE bool operator==(T* other) { return Get() == other; } FORCE_INLINE bool operator!=(T* other) { return Get() != other; } FORCE_INLINE bool operator==(const SoftObjectInterfaceReference& other) { return GetID() == other.GetID(); } FORCE_INLINE bool operator!=(const SoftObjectInterfaceReference& other) { return GetID() != other.GetID(); } SoftObjectInterfaceReference& operator=(const SoftObjectInterfaceReference& other) { if (this != &other) OnSet(other.GetID()); return *this; } SoftObjectInterfaceReference& operator=(SoftObjectInterfaceReference&& other) { if (this != &other) { OnSet(other.GetID()); other.OnSet(nullptr); } return *this; } FORCE_INLINE SoftObjectInterfaceReference& operator=(SceneObject* other) { OnSet(Helper::IsValidObject(other) ? other : nullptr); return *this; } FORCE_INLINE SoftObjectInterfaceReference& operator=(T* other) { OnSet(Helper::GetSceneObject(other)); return *this; } FORCE_INLINE SoftObjectInterfaceReference& operator=(const Guid& id) { OnSet(id); return *this; } /// /// Implicit conversion to the interface. /// FORCE_INLINE operator T*() const { return Get(); } /// /// Implicit conversion to boolean value. /// FORCE_INLINE operator bool() const { return Get() != nullptr; } /// /// Interface accessor. /// FORCE_INLINE T* operator->() const { return Get(); } /// /// Gets the object as a given type (static cast). /// template FORCE_INLINE U* As() const { return static_cast(GetObject()); } public: /// /// Gets the interface pointer. /// FORCE_INLINE T* Get() const { return ScriptingObject::ToInterface(GetObject()); } /// /// Gets the referenced object. /// SceneObject* GetObject() const { if (!_object) const_cast(this)->OnResolve(SceneObject::GetStaticClass()); return Helper::IsValidObject(static_cast(_object)) ? static_cast(_object) : nullptr; } /// /// Gets managed instance object (or null if no object linked). /// MObject* GetManagedInstance() const { auto object = GetObject(); return object ? object->GetOrCreateManagedInstance() : nullptr; } /// /// Determines whether object is assigned and managed instance of the object is alive. /// bool HasManagedInstance() const { auto object = GetObject(); return object && object->HasManagedInstance(); } /// /// Gets the managed instance object or creates it if missing or null if not assigned. /// MObject* GetOrCreateManagedInstance() const { auto object = GetObject(); return object ? object->GetOrCreateManagedInstance() : nullptr; } /// /// Copies the object ID into the raw storage. /// FORCE_INLINE void CopyID(uint32 id[4]) const { const Guid value = GetID(); memcpy(id, &value, sizeof(uint32) * 4); } /// /// Sets the object. /// /// The object ID. Uses Scripting to find the registered object of the given ID. FORCE_INLINE void Set(const Guid& id) { OnSet(id); } /// /// Sets the object. /// /// The object. FORCE_INLINE void Set(SceneObject* object) { OnSet(Helper::IsValidObject(object) ? object : nullptr); } /// /// Sets the object. /// /// The interface object. FORCE_INLINE void Set(T* interfaceObj) { OnSet(Helper::GetSceneObject(interfaceObj)); } }; template uint32 GetHash(const SoftObjectInterfaceReference& key) { return GetHash(key.GetID()); }