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