mirror of
https://github.com/barkeser2002/flower.git
synced 2026-09-25 14:16:14 +03:00
163 lines
4.6 KiB
C++
163 lines
4.6 KiB
C++
#pragma once
|
|
#include "../utils/utils.h"
|
|
#include "asset_common.h"
|
|
|
|
namespace engine
|
|
{
|
|
struct ProjectConfig
|
|
{
|
|
// Project stem name, not include period and suffix.
|
|
std::u16string projectName;
|
|
|
|
// Project file absolute path file in this computer, this is runtime generate value.
|
|
std::u16string projectFilePath;
|
|
|
|
// Misc project folder path.
|
|
std::u16string rootPath;
|
|
std::u16string assetPath;
|
|
std::u16string configPath;
|
|
std::u16string logPath;
|
|
std::u16string cachePath;
|
|
};
|
|
|
|
class AssetManager : public IRuntimeModule
|
|
{
|
|
friend AssetInterface;
|
|
|
|
public:
|
|
explicit AssetManager(Engine* engine) : IRuntimeModule(engine) { }
|
|
virtual ~AssetManager() = default;
|
|
|
|
virtual void registerCheck(Engine* engine) override;
|
|
virtual bool init() override;
|
|
virtual bool tick(const RuntimeModuleTickData& tickData) override;
|
|
virtual bool beforeRelease() override;
|
|
virtual bool release() override;
|
|
|
|
const ProjectConfig& getProjectConfig() const { return m_projectConfig; }
|
|
void setupProject(const std::filesystem::path& inProjectPath);
|
|
|
|
void setupProjectRecursive(const std::filesystem::path& path);
|
|
|
|
bool isProjectSetup() const { return m_bProjectSetup; }
|
|
|
|
template<typename T>
|
|
std::vector<std::weak_ptr<T>> getDirtyAsset() const
|
|
{
|
|
std::lock_guard<std::recursive_mutex> lock(m_assetManagerMutex);
|
|
|
|
std::vector<std::weak_ptr<T>> result { };
|
|
for (const auto& id : m_dirtyAssetIds)
|
|
{
|
|
if (auto sp = std::dynamic_pointer_cast<T>(m_assets.at(id)))
|
|
{
|
|
result.push_back(sp);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool existDirtyAsset() const
|
|
{
|
|
std::lock_guard<std::recursive_mutex> lock(m_assetManagerMutex);
|
|
|
|
return !m_dirtyAssetIds.empty();
|
|
}
|
|
|
|
bool isAssetSavePathExist(const AssetSaveInfo& info) const
|
|
{
|
|
std::lock_guard<std::recursive_mutex> lock(m_assetManagerMutex);
|
|
|
|
return m_assets.contains(info.getUUID());
|
|
}
|
|
|
|
template<typename T>
|
|
std::weak_ptr<T> createAsset(const AssetSaveInfo& saveInfo = {})
|
|
{
|
|
std::lock_guard<std::recursive_mutex> lock(m_assetManagerMutex);
|
|
const UUID& uuid = saveInfo.getUUID();
|
|
|
|
static_assert(std::is_constructible_v<T, const AssetSaveInfo&>);
|
|
static_assert(std::is_base_of_v<AssetInterface, T>);
|
|
|
|
// Ensure save info is valid.
|
|
if (!saveInfo.isTemp())
|
|
{
|
|
CHECK(saveInfo.canUseForCreateNewAsset());
|
|
}
|
|
|
|
|
|
// Create a new asset and mark it dirty.
|
|
auto newAsset = std::make_shared<T>(saveInfo);
|
|
insertAsset(uuid, newAsset, false);
|
|
|
|
// Callback function after construct.
|
|
newAsset->onPostAssetConstruct();
|
|
return std::dynamic_pointer_cast<T>(newAsset);
|
|
}
|
|
|
|
template<typename T>
|
|
std::weak_ptr<T> getOrLoadAsset(const std::filesystem::path& savePath)
|
|
{
|
|
auto asset = tryLoadAsset(savePath);
|
|
std::shared_ptr<T> result = std::dynamic_pointer_cast<T>(asset);
|
|
return result;
|
|
}
|
|
|
|
// A new asset save to disk file.
|
|
MulticastDelegate<std::shared_ptr<AssetInterface>> onAssetNewlySavedToDisk;
|
|
|
|
const auto& getAssetTypeMap(const std::string& type) { return m_assetTypeMap[type]; }
|
|
std::shared_ptr<AssetInterface> getAsset(const UUID& id) const { return m_assets.at(id); }
|
|
private:
|
|
std::shared_ptr<AssetInterface> tryLoadAsset(const std::filesystem::path& savePath)
|
|
{
|
|
std::lock_guard<std::recursive_mutex> lock(m_assetManagerMutex);
|
|
|
|
const AssetSaveInfo saveInfo = AssetSaveInfo::buildRelativeProject(savePath);
|
|
const UUID& uuid = saveInfo.getUUID();
|
|
CHECK(saveInfo.alreadyInDisk());
|
|
|
|
if (!m_assets[uuid])
|
|
{
|
|
std::shared_ptr<AssetInterface> asset;
|
|
CHECK(loadAsset(asset, savePath));
|
|
|
|
insertAsset(uuid, asset, false);
|
|
}
|
|
|
|
return m_assets[uuid];
|
|
}
|
|
|
|
// Discard asset edited or created state.
|
|
void onDiscardChanged(std::shared_ptr<AssetInterface> asset);
|
|
|
|
void onAssetDirty(std::shared_ptr<AssetInterface> asset);
|
|
|
|
void onAssetChangeSaveInfo(
|
|
std::shared_ptr<AssetInterface> asset, const AssetSaveInfo& newInfo);
|
|
|
|
void onAssetSaved(std::shared_ptr<AssetInterface> asset);
|
|
void onAssetUnload(std::shared_ptr<AssetInterface> asset);
|
|
|
|
std::shared_ptr<AssetInterface> removeAsset(const UUID& id, bool bClearDirty);
|
|
void insertAsset(const UUID& uuid, std::shared_ptr<AssetInterface> asset, bool bCareDirtyState);
|
|
|
|
|
|
protected:
|
|
bool m_bProjectSetup = false;
|
|
|
|
ProjectConfig m_projectConfig;
|
|
|
|
mutable std::recursive_mutex m_assetManagerMutex;
|
|
|
|
// Map store dirty asset ids.
|
|
std::unordered_set<UUID> m_dirtyAssetIds;
|
|
|
|
// Map store all engine assetes.
|
|
std::unordered_map<UUID, std::shared_ptr<AssetInterface>> m_assets;
|
|
std::unordered_map<std::string, std::unordered_set<UUID>> m_assetTypeMap;
|
|
};
|
|
|
|
extern AssetManager* getAssetManager();
|
|
} |