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