Add SoftAssetReference type
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Asset.h"
|
||||
#include "Content.h"
|
||||
#include "SoftAssetReference.h"
|
||||
#include "Cache/AssetsCache.h"
|
||||
#include "Loading/ContentLoadingManager.h"
|
||||
#include "Loading/Tasks/LoadAssetTask.h"
|
||||
@@ -102,6 +103,65 @@ void WeakAssetReferenceBase::OnUnloaded(Asset* asset)
|
||||
_asset = nullptr;
|
||||
}
|
||||
|
||||
String SoftAssetReferenceBase::ToString() const
|
||||
{
|
||||
return _asset ? _asset->ToString() : (_id.IsValid() ? _id.ToString() : TEXT("<null>"));
|
||||
}
|
||||
|
||||
void SoftAssetReferenceBase::OnSet(Asset* asset)
|
||||
{
|
||||
if (_asset == asset)
|
||||
return;
|
||||
if (_asset)
|
||||
{
|
||||
_asset->OnUnloaded.Unbind<SoftAssetReferenceBase, &SoftAssetReferenceBase::OnUnloaded>(this);
|
||||
_asset->RemoveReference();
|
||||
}
|
||||
_asset = asset;
|
||||
_id = asset ? asset->GetID() : Guid::Empty;
|
||||
if (asset)
|
||||
{
|
||||
asset->AddReference();
|
||||
asset->OnUnloaded.Bind<SoftAssetReferenceBase, &SoftAssetReferenceBase::OnUnloaded>(this);
|
||||
}
|
||||
Changed();
|
||||
}
|
||||
|
||||
void SoftAssetReferenceBase::OnSet(const Guid& id)
|
||||
{
|
||||
if (_id == id)
|
||||
return;
|
||||
if (_asset)
|
||||
{
|
||||
_asset->OnUnloaded.Unbind<SoftAssetReferenceBase, &SoftAssetReferenceBase::OnUnloaded>(this);
|
||||
_asset->RemoveReference();
|
||||
}
|
||||
_asset = nullptr;
|
||||
_id = id;
|
||||
Changed();
|
||||
}
|
||||
|
||||
void SoftAssetReferenceBase::OnResolve(const ScriptingTypeHandle& type)
|
||||
{
|
||||
ASSERT(!_asset);
|
||||
_asset = ::LoadAsset(_id, type);
|
||||
if (_asset)
|
||||
{
|
||||
_asset->OnUnloaded.Bind<SoftAssetReferenceBase, &SoftAssetReferenceBase::OnUnloaded>(this);
|
||||
_asset->AddReference();
|
||||
}
|
||||
}
|
||||
|
||||
void SoftAssetReferenceBase::OnUnloaded(Asset* asset)
|
||||
{
|
||||
ASSERT(_asset == asset);
|
||||
_asset->RemoveReference();
|
||||
_asset->OnUnloaded.Unbind<SoftAssetReferenceBase, &SoftAssetReferenceBase::OnUnloaded>(this);
|
||||
_asset = nullptr;
|
||||
_id = Guid::Empty;
|
||||
Changed();
|
||||
}
|
||||
|
||||
Asset::Asset(const SpawnParams& params, const AssetInfo* info)
|
||||
: ManagedScriptingObject(params)
|
||||
, _refCount(0)
|
||||
|
||||
234
Source/Engine/Content/SoftAssetReference.h
Normal file
234
Source/Engine/Content/SoftAssetReference.h
Normal file
@@ -0,0 +1,234 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Content/Asset.h"
|
||||
|
||||
/// <summary>
|
||||
/// The asset soft reference. Asset gets referenced (loaded) on actual use (ID reference is resolving it).
|
||||
/// </summary>
|
||||
class FLAXENGINE_API SoftAssetReferenceBase
|
||||
{
|
||||
protected:
|
||||
Asset* _asset = nullptr;
|
||||
Guid _id = Guid::Empty;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Action fired when field gets changed (link a new asset or change to the another value).
|
||||
/// </summary>
|
||||
Delegate<> Changed;
|
||||
|
||||
public:
|
||||
NON_COPYABLE(SoftAssetReferenceBase);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SoftAssetReferenceBase"/> class.
|
||||
/// </summary>
|
||||
SoftAssetReferenceBase() = default;
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="SoftAssetReferenceBase"/> class.
|
||||
/// </summary>
|
||||
~SoftAssetReferenceBase()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets the asset ID or Guid::Empty if not set.
|
||||
/// </summary>
|
||||
FORCE_INLINE Guid GetID() const
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the asset property value as string.
|
||||
/// </summary>
|
||||
String ToString() const;
|
||||
|
||||
protected:
|
||||
void OnSet(Asset* asset);
|
||||
void OnSet(const Guid& id);
|
||||
void OnResolve(const ScriptingTypeHandle& type);
|
||||
void OnUnloaded(Asset* asset);
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The asset soft reference. Asset gets referenced (loaded) on actual use (ID reference is resolving it).
|
||||
/// </summary>
|
||||
template<typename T>
|
||||
API_CLASS(InBuild) class SoftAssetReference : public SoftAssetReferenceBase
|
||||
{
|
||||
public:
|
||||
typedef T AssetType;
|
||||
typedef SoftAssetReference<T> Type;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SoftAssetReference"/> class.
|
||||
/// </summary>
|
||||
SoftAssetReference()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SoftAssetReference"/> class.
|
||||
/// </summary>
|
||||
/// <param name="asset">The asset to set.</param>
|
||||
SoftAssetReference(T* asset)
|
||||
{
|
||||
OnSet(asset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SoftAssetReference"/> class.
|
||||
/// </summary>
|
||||
/// <param name="other">The other.</param>
|
||||
SoftAssetReference(const SoftAssetReference& other)
|
||||
{
|
||||
OnSet(other.Get());
|
||||
}
|
||||
|
||||
SoftAssetReference(SoftAssetReference&& other)
|
||||
{
|
||||
OnSet(other.Get());
|
||||
other.OnSet(nullptr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="SoftAssetReference"/> class.
|
||||
/// </summary>
|
||||
~SoftAssetReference()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
FORCE_INLINE bool operator==(T* other)
|
||||
{
|
||||
return Get() == other;
|
||||
}
|
||||
FORCE_INLINE bool operator==(const SoftAssetReference& other)
|
||||
{
|
||||
return GetID() == other.GetID();
|
||||
}
|
||||
FORCE_INLINE bool operator!=(T* other)
|
||||
{
|
||||
return Get() != other;
|
||||
}
|
||||
FORCE_INLINE bool operator!=(const SoftAssetReference& other)
|
||||
{
|
||||
return GetID() != other.GetID();
|
||||
}
|
||||
SoftAssetReference& operator=(const SoftAssetReference& other)
|
||||
{
|
||||
if (this != &other)
|
||||
OnSet(other.GetID());
|
||||
return *this;
|
||||
}
|
||||
SoftAssetReference& operator=(SoftAssetReference&& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
OnSet(other.GetID());
|
||||
other.OnSet(nullptr);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
FORCE_INLINE SoftAssetReference& operator=(const T& other)
|
||||
{
|
||||
OnSet(&other);
|
||||
return *this;
|
||||
}
|
||||
FORCE_INLINE SoftAssetReference& operator=(T* other)
|
||||
{
|
||||
OnSet(other);
|
||||
return *this;
|
||||
}
|
||||
FORCE_INLINE SoftAssetReference& operator=(const Guid& id)
|
||||
{
|
||||
OnSet(id);
|
||||
return *this;
|
||||
}
|
||||
FORCE_INLINE operator T*() const
|
||||
{
|
||||
return (T*)Get();
|
||||
}
|
||||
FORCE_INLINE operator bool() const
|
||||
{
|
||||
return Get() != nullptr;
|
||||
}
|
||||
FORCE_INLINE T* operator->() const
|
||||
{
|
||||
return (T*)Get();
|
||||
}
|
||||
template<typename U>
|
||||
FORCE_INLINE U* As() const
|
||||
{
|
||||
return static_cast<U*>(Get());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets the asset (or null if unassigned).
|
||||
/// </summary>
|
||||
T* Get() const
|
||||
{
|
||||
if (!_asset)
|
||||
const_cast<SoftAssetReference*>(this)->OnResolve(T::TypeInitializer);
|
||||
return (T*)_asset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets managed instance object (or null if no asset linked).
|
||||
/// </summary>
|
||||
MObject* GetManagedInstance() const
|
||||
{
|
||||
auto asset = Get();
|
||||
return asset ? asset->GetOrCreateManagedInstance() : nullptr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether asset is assigned and managed instance of the asset is alive.
|
||||
/// </summary>
|
||||
bool HasManagedInstance() const
|
||||
{
|
||||
auto asset = Get();
|
||||
return asset && asset->HasManagedInstance();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the managed instance object or creates it if missing or null if not assigned.
|
||||
/// </summary>
|
||||
MObject* GetOrCreateManagedInstance() const
|
||||
{
|
||||
auto asset = Get();
|
||||
return asset ? asset->GetOrCreateManagedInstance() : nullptr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the asset.
|
||||
/// </summary>
|
||||
/// <param name="id">The object ID. Uses Scripting to find the registered asset of the given ID.</param>
|
||||
FORCE_INLINE void Set(const Guid& id)
|
||||
{
|
||||
OnSet(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the asset.
|
||||
/// </summary>
|
||||
/// <param name="asset">The asset.</param>
|
||||
FORCE_INLINE void Set(T* asset)
|
||||
{
|
||||
OnSet(asset);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
uint32 GetHash(const SoftAssetReference<T>& key)
|
||||
{
|
||||
return GetHash(key.GetID());
|
||||
}
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
struct Version;
|
||||
struct VariantType;
|
||||
template<typename T>
|
||||
class SoftAssetReference;
|
||||
|
||||
// @formatter:off
|
||||
|
||||
@@ -513,6 +515,26 @@ namespace Serialization
|
||||
v = id;
|
||||
}
|
||||
|
||||
// Soft Asset Reference
|
||||
|
||||
template<typename T>
|
||||
inline bool ShouldSerialize(const SoftAssetReference<T>& v, const void* otherObj)
|
||||
{
|
||||
return !otherObj || v.Get() != ((SoftAssetReference<T>*)otherObj)->Get();
|
||||
}
|
||||
template<typename T>
|
||||
inline void Serialize(ISerializable::SerializeStream& stream, const SoftAssetReference<T>& v, const void* otherObj)
|
||||
{
|
||||
stream.Guid(v.GetID());
|
||||
}
|
||||
template<typename T>
|
||||
inline void Deserialize(ISerializable::DeserializeStream& stream, SoftAssetReference<T>& v, ISerializeModifier* modifier)
|
||||
{
|
||||
Guid id;
|
||||
Deserialize(stream, id, modifier);
|
||||
v = id;
|
||||
}
|
||||
|
||||
// Array
|
||||
|
||||
template<typename T, typename AllocationType = HeapAllocation>
|
||||
|
||||
Reference in New Issue
Block a user