Files
FlaxEngine/Source/Engine/Content/WeakAssetReference.h

217 lines
4.9 KiB
C++

// Copyright (c) Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Content/Asset.h"
/// <summary>
/// Asset reference utility that doesn't add reference to that asset. Handles asset unload event.
/// </summary>
API_CLASS(InBuild) class WeakAssetReferenceBase : public IAssetReference
{
public:
typedef Delegate<> EventType;
protected:
Asset* _asset = nullptr;
public:
/// <summary>
/// The asset unloading event (should cleanup refs to it).
/// </summary>
EventType Unload;
public:
NON_COPYABLE(WeakAssetReferenceBase);
/// <summary>
/// Initializes a new instance of the <see cref="WeakAssetReferenceBase"/> class.
/// </summary>
WeakAssetReferenceBase() = default;
/// <summary>
/// Finalizes an instance of the <see cref="WeakAssetReferenceBase"/> class.
/// </summary>
~WeakAssetReferenceBase();
public:
/// <summary>
/// Gets the asset ID or Guid::Empty if not set.
/// </summary>
FORCE_INLINE Guid GetID() const
{
return _asset ? _asset->GetID() : Guid::Empty;
}
/// <summary>
/// Gets managed instance object (or null if no asset set).
/// </summary>
FORCE_INLINE MObject* GetManagedInstance() const
{
return _asset ? _asset->GetOrCreateManagedInstance() : nullptr;
}
/// <summary>
/// Gets the asset property value as string.
/// </summary>
String ToString() const;
public:
// [IAssetReference]
void OnAssetChanged(Asset* asset, void* caller) override;
void OnAssetLoaded(Asset* asset, void* caller) override;
void OnAssetUnloaded(Asset* asset, void* caller) override;
protected:
void OnSet(Asset* asset);
};
/// <summary>
/// Asset reference utility that doesn't add reference to that asset. Handles asset unload event.
/// </summary>
template<typename T>
API_CLASS(InBuild) class WeakAssetReference : public WeakAssetReferenceBase
{
public:
/// <summary>
/// Initializes a new instance of the <see cref="WeakAssetReference"/> class.
/// </summary>
WeakAssetReference()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="WeakAssetReference"/> class.
/// </summary>
explicit WeakAssetReference(decltype(__nullptr))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="WeakAssetReference"/> class.
/// </summary>
/// <param name="asset">The asset to set.</param>
WeakAssetReference(T* asset)
{
OnSet(asset);
}
/// <summary>
/// Initializes a new instance of the <see cref="WeakAssetReference"/> class.
/// </summary>
/// <param name="other">The other.</param>
WeakAssetReference(const WeakAssetReference& other)
{
OnSet(other.Get());
}
WeakAssetReference(WeakAssetReference&& other)
{
OnSet(other.Get());
other.OnSet(nullptr);
}
WeakAssetReference& operator=(WeakAssetReference&& other)
{
if (&other != this)
{
OnSet(other.Get());
other.OnSet(nullptr);
}
return *this;
}
/// <summary>
/// Finalizes an instance of the <see cref="WeakAssetReference"/> class.
/// </summary>
~WeakAssetReference()
{
}
public:
FORCE_INLINE WeakAssetReference& operator=(const WeakAssetReference& other)
{
OnSet(other.Get());
return *this;
}
FORCE_INLINE WeakAssetReference& operator=(T* other)
{
OnSet((Asset*)other);
return *this;
}
FORCE_INLINE WeakAssetReference& operator=(const Guid& id)
{
OnSet((Asset*)::LoadAsset(id, T::TypeInitializer));
return *this;
}
FORCE_INLINE bool operator==(T* other) const
{
return _asset == other;
}
FORCE_INLINE bool operator==(const WeakAssetReference& other) const
{
return _asset == other._asset;
}
/// <summary>
/// Implicit conversion to the bool.
/// </summary>
FORCE_INLINE operator T*() const
{
return (T*)_asset;
}
/// <summary>
/// Implicit conversion to the asset.
/// </summary>
FORCE_INLINE operator bool() const
{
return _asset != nullptr;
}
/// <summary>
/// Implicit conversion to the asset.
/// </summary>
FORCE_INLINE T* operator->() const
{
return (T*)_asset;
}
/// <summary>
/// Gets the asset.
/// </summary>
FORCE_INLINE T* Get() const
{
return (T*)_asset;
}
/// <summary>
/// Gets the asset as a given type (static cast).
/// </summary>
template<typename U>
FORCE_INLINE U* As() const
{
return (U*)_asset;
}
public:
/// <summary>
/// Sets the asset reference.
/// </summary>
/// <param name="asset">The asset.</param>
void Set(T* asset)
{
OnSet(asset);
}
};
template<typename T>
uint32 GetHash(const WeakAssetReference<T>& key)
{
return GetHash(key.GetID());
}