// Copyright (c) Wojciech Figat. All rights reserved. #pragma once #include "Engine/Content/Asset.h" /// /// Asset reference utility. Keeps reference to the linked asset object and handles load/unload events. /// class FLAXENGINE_API AssetReferenceBase : public IAssetReference { protected: Asset* _asset = nullptr; IAssetReference* _owner = nullptr; public: /// /// The asset loaded event (fired when asset gets loaded or is already loaded after change). /// Action Loaded; /// /// The asset unloading event (should cleanup refs to it). /// Action Unload; /// /// Action fired when field gets changed (link a new asset or change to the another value). /// Action Changed; public: NON_COPYABLE(AssetReferenceBase); /// /// Initializes a new instance of the class. /// AssetReferenceBase() = default; /// /// Initializes a new instance of the class. /// /// The reference owner to keep notified about asset changes. AssetReferenceBase(IAssetReference* owner); /// /// Finalizes an instance of the class. /// ~AssetReferenceBase(); public: /// /// Gets the asset ID or Guid::Empty if not set. /// FORCE_INLINE Guid GetID() const { return _asset ? _asset->GetID() : Guid::Empty; } /// /// Gets managed instance object (or null if no asset set). /// FORCE_INLINE MObject* GetManagedInstance() const { return _asset ? _asset->GetOrCreateManagedInstance() : nullptr; } /// /// Gets the asset property value as string. /// 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); }; /// /// Asset reference utility. Keeps reference to the linked asset object and handles load/unload events. /// template API_CLASS(InBuild) class AssetReference : public AssetReferenceBase { public: typedef T AssetType; typedef AssetReference Type; public: /// /// Initializes a new instance of the class. /// AssetReference() { } /// /// Initializes a new instance of the class. /// explicit AssetReference(decltype(__nullptr)) { } /// /// Initializes a new instance of the class. /// /// The asset to set. AssetReference(T* asset) { OnSet((Asset*)asset); } /// /// Initializes a new instance of the class. /// /// The reference owner to keep notified about asset changes. explicit AssetReference(IAssetReference* owner) : AssetReferenceBase(owner) { } /// /// Initializes a new instance of the class. /// /// The other. AssetReference(const AssetReference& other) { OnSet(other._asset); } AssetReference(AssetReference&& other) noexcept { OnSet(other._asset); other.OnSet(nullptr); } AssetReference& operator=(AssetReference&& other) { if (&other != this) { OnSet(other._asset); other.OnSet(nullptr); } return *this; } /// /// Finalizes an instance of the class. /// ~AssetReference() { } public: FORCE_INLINE AssetReference& operator=(const AssetReference& other) { OnSet(other._asset); return *this; } FORCE_INLINE AssetReference& operator=(T* other) { OnSet((Asset*)other); return *this; } FORCE_INLINE AssetReference& operator=(const Guid& id) { OnSet(::LoadAsset(id, T::TypeInitializer)); return *this; } FORCE_INLINE bool operator==(T* other) const { return _asset == other; } FORCE_INLINE bool operator==(const AssetReference& other) const { return _asset == other._asset; } FORCE_INLINE bool operator!=(T* other) const { return _asset != other; } FORCE_INLINE bool operator!=(const AssetReference& other) const { return _asset != other._asset; } /// /// Implicit conversion to the bool. /// FORCE_INLINE operator T*() const { return (T*)_asset; } /// /// Implicit conversion to the asset. /// FORCE_INLINE operator bool() const { return _asset != nullptr; } /// /// Implicit conversion to the asset. /// FORCE_INLINE T* operator->() const { return (T*)_asset; } /// /// Gets the asset. /// FORCE_INLINE T* Get() const { return (T*)_asset; } /// /// Gets the asset as a given type (static cast). /// template FORCE_INLINE U* As() const { return (U*)_asset; } public: /// /// Sets the asset reference. /// /// The asset. void Set(T* asset) { OnSet((Asset*)asset); } }; template uint32 GetHash(const AssetReference& key) { return GetHash(key.GetID()); }