// Copyright (c) Wojciech Figat. All rights reserved. #pragma once #include "ScriptingObjectReference.h" /// /// The scripting object reference with interface. /// /// The type of the scripting interface. template API_CLASS(Template, MarshalAs=ScriptingObject*) class ScriptingObjectInterfaceReference : public ScriptingObjectReferenceBase { public: typedef ScriptingObjectInterfaceReference Type; public: /// /// Initializes a new instance of the class. /// ScriptingObjectInterfaceReference() { } /// /// Initializes a new instance of the class. /// /// The object to link. ScriptingObjectInterfaceReference(ScriptingObject* obj) : ScriptingObjectReferenceBase(IsValid(obj) ? obj : nullptr) { } /// /// Initializes a new instance of the class. /// /// The interface object to link. ScriptingObjectInterfaceReference(T* interfaceObj) : ScriptingObjectReferenceBase(ScriptingObject::FromInterface(interfaceObj)) { } /// /// Initializes a new instance of the class. /// /// The other property. ScriptingObjectInterfaceReference(const ScriptingObjectInterfaceReference& other) : ScriptingObjectReferenceBase(other._object) { } ScriptingObjectInterfaceReference(ScriptingObjectInterfaceReference&& other) noexcept : ScriptingObjectReferenceBase(MoveTemp(other)) { } /// /// Finalizes an instance of the class. /// ~ScriptingObjectInterfaceReference() { } public: FORCE_INLINE bool operator==(ScriptingObject* other) const { return _object == other; } FORCE_INLINE bool operator!=(ScriptingObject* other) const { return _object != other; } FORCE_INLINE bool operator==(T* other) const { return Get() == other; } FORCE_INLINE bool operator!=(T* other) const { return Get() != other; } FORCE_INLINE bool operator==(const ScriptingObjectInterfaceReference& other) const { return _object == other._object; } FORCE_INLINE bool operator!=(const ScriptingObjectInterfaceReference& other) const { return _object != other._object; } FORCE_INLINE ScriptingObjectInterfaceReference& operator=(ScriptingObject* other) { OnSet(IsValid(other) ? other : nullptr); return *this; } FORCE_INLINE ScriptingObjectInterfaceReference& operator=(T* other) { OnSet(ScriptingObject::FromInterface(other)); return *this; } FORCE_INLINE ScriptingObjectInterfaceReference& operator=(const ScriptingObjectInterfaceReference& other) { OnSet(other._object); return *this; } FORCE_INLINE ScriptingObjectInterfaceReference& operator=(ScriptingObjectInterfaceReference&& other) noexcept { ScriptingObjectReferenceBase::operator=(MoveTemp(other)); return *this; } ScriptingObjectInterfaceReference& operator=(const Guid& id) { ScriptingObject* obj = FindObject(id, ScriptingObject::GetStaticClass()); OnSet(IsValid(obj) ? obj : nullptr); return *this; } /// /// Implicit conversion to the interface. /// FORCE_INLINE operator T*() const { return Get(); } /// /// Implicit conversion to the object. /// FORCE_INLINE operator ScriptingObject*() const { return _object; } /// /// Implicit conversion to boolean value. /// FORCE_INLINE operator bool() const { return _object != nullptr; } /// /// Interface accessor. /// FORCE_INLINE T* operator->() const { return Get(); } /// /// Gets the interface pointer. /// FORCE_INLINE T* Get() const { return ScriptingObject::ToInterface(_object); } /// /// Gets the referenced object. /// FORCE_INLINE ScriptingObject* GetObject() const { return _object; } /// /// Gets managed instance object. /// FORCE_INLINE MObject* GetManagedInstance() const { return _object ? _object->GetOrCreateManagedInstance() : nullptr; } private: FORCE_INLINE static bool IsValid(const ScriptingObject* obj) { return !obj || obj->GetType().GetInterface(T::TypeInitializer); } }; template uint32 GetHash(const ScriptingObjectInterfaceReference& key) { return GetHash(key.GetID()); }