#pragma once #include "Utils/UUID.hpp" #include "cplt_fwd.hpp" #include #include #include #include #include /// A structure representing a ready-to-be-loaded asset, locating on the disk. /// Each asset should be identified by a unique uuid within the asset category (i.e. a workflow and a template can share the same uuid), /// generated on insertion to an asset list if not given by the caller. struct SavedAsset { std::string Name; /// UUID of this asset. This field is generated as a random UUID v4 upon insertion into an AssetList, if not already provided by the caller (indicated by !is_nil()). uuids::uuid Uuid; /// Extra data to be used by the AssetList/Asset implementation. uint64_t Payload; template void OperateIOProxy(TProxy& proxy); }; class Asset { public: Asset(); virtual ~Asset() = default; }; enum class NameSelectionError { None, Duplicated, Empty, }; class AssetList { private: class Private; std::unique_ptr mPrivate; public: AssetList(Project& project); virtual ~AssetList(); Project& GetConnectedProject() const; // TODO support file watches void Reload(); int GetCount() const; // TODO convert to custom iterable const tsl::array_map& GetAssets() const; const SavedAsset* FindByName(std::string_view name) const; const SavedAsset& Create(SavedAsset asset); std::unique_ptr CreateAndLoad(SavedAsset asset); /// Load the asset on disk by its name. std::unique_ptr Load(std::string_view name) const; /// Load the asset on disk by a reference to its SavedAsset instance. This function assumes that the given SavedAsset /// is stored in AssetList, otherwise the behavior is undefined. std::unique_ptr Load(const SavedAsset& asset) const; const SavedAsset* Rename(std::string_view oldName, std::string_view newName); bool Remove(std::string_view name); int GetCacheSizeLimit() const; void SetCacheSizeLimit(int limit); struct ListState { const SavedAsset* SelectedAsset = nullptr; }; void DisplayIconsList(ListState& state); void DisplayDetailsList(ListState& state); void DisplayControls(ListState& state); protected: virtual void DiscoverFiles(const std::function& callback) const = 0; // Helper void DiscoverFilesByExtension(const std::function& callback, const std::filesystem::path& containerDir, std::string_view extension) const; void DiscoverFilesByHeader(const std::function& callback, const std::filesystem::path& containerDir, const std::function& validater) const; /// Create an empty/default instance of this asset type on disk, potentially qualified by SavedAsset::Payload. /// Return `true` on success and `false` on failure. virtual bool SaveInstance(const SavedAsset& assetInfo, const Asset* asset) const = 0; /// The returned pointer indicate ownership to the object. virtual Asset* LoadInstance(const SavedAsset& assetInfo) const = 0; /// Create an empty/default instance of this asset type, potentially qualified by SavedAsset::Payload. /// The returned pointer indicate ownership to the object. virtual Asset* CreateInstance(const SavedAsset& assetInfo) const = 0; virtual bool RenameInstanceOnDisk(const SavedAsset& assetInfo, std::string_view oldName) const = 0; virtual std::string RetrieveNameFromFile(const std::filesystem::path& file) const = 0; virtual uuids::uuid RetrieveUuidFromFile(const std::filesystem::path& file) const = 0; virtual std::filesystem::path RetrievePathFromAsset(const SavedAsset& asset) const = 0; virtual void DisplayAssetCreator(ListState& state) = 0; virtual void DisplayDetailsTable(ListState& state) const = 0; }; template class AssetListTyped : public AssetList { public: using AssetList::AssetList; #pragma clang diagnostic push #pragma ide diagnostic ignored "HidingNonVirtualFunction" std::unique_ptr CreateAndLoad(SavedAsset asset) { return std::unique_ptr(static_cast(AssetList::CreateAndLoad(asset).release())); } std::unique_ptr Load(std::string_view name) const { return std::unique_ptr(static_cast(AssetList::Load(name).release())); } std::unique_ptr Load(const SavedAsset& asset) const { return std::unique_ptr(static_cast(AssetList::Load(asset).release())); } #pragma clang diagnostic pop };