From 92179df553e986c3cda1107bf39c9e35ff57610e Mon Sep 17 00:00:00 2001 From: SweetId <2630750+SweetId@users.noreply.github.com> Date: Sun, 24 Mar 2024 21:59:50 -0400 Subject: [PATCH] [Assets] Making AssetCatalog an AppComponent --- include/Nazara/Core/Asset.hpp | 4 ++ include/Nazara/Core/Asset.inl | 60 +++++++++++++++++++ include/Nazara/Core/AssetCatalog.hpp | 16 ----- include/Nazara/Core/AssetCatalog.inl | 59 ------------------ .../Nazara/Core/AssetCatalogAppComponent.hpp | 45 ++++++++++++++ .../Nazara/Core/AssetCatalogAppComponent.inl | 19 ++++++ src/Nazara/Core/AssetCatalogAppComponent.cpp | 52 ++++++++++++++++ 7 files changed, 180 insertions(+), 75 deletions(-) delete mode 100644 include/Nazara/Core/AssetCatalog.hpp delete mode 100644 include/Nazara/Core/AssetCatalog.inl create mode 100644 include/Nazara/Core/AssetCatalogAppComponent.hpp create mode 100644 include/Nazara/Core/AssetCatalogAppComponent.inl create mode 100644 src/Nazara/Core/AssetCatalogAppComponent.cpp diff --git a/include/Nazara/Core/Asset.hpp b/include/Nazara/Core/Asset.hpp index 87adbc45f..a1784039f 100644 --- a/include/Nazara/Core/Asset.hpp +++ b/include/Nazara/Core/Asset.hpp @@ -16,6 +16,8 @@ namespace Nz TResource* operator->() { return m_resource.get(); } const TResource* operator->() const { return m_resource.get(); } + static Asset LoadFromFile(const std::filesystem::path& path); + protected: AssetDescriptor m_descriptor; std::shared_ptr m_resource; @@ -23,3 +25,5 @@ namespace Nz friend class AssetCatalog; }; } + +#include diff --git a/include/Nazara/Core/Asset.inl b/include/Nazara/Core/Asset.inl index e69de29bb..f1291dd92 100644 --- a/include/Nazara/Core/Asset.inl +++ b/include/Nazara/Core/Asset.inl @@ -0,0 +1,60 @@ +#include +#include +#include + +namespace Nz +{ + template + concept IsStreamingResource = requires(TResource) + { + { TResource::OpenFromFile({}) } -> std::same_as>; + }; + + template + Asset Asset::LoadFromFile(const std::filesystem::path& path) + { + Asset asset; + + FilesystemAppComponent* fs = ApplicationBase::Instance()->TryGetComponent(); + if (fs) // first try using a FileSystem component to load the asset + { + auto json = fs->Load(std::string_view(path.string())); + if (json) + { + if (!Unserialize(*json, "", &asset.m_descriptor)) + return {}; + + std::string filepath = asset.m_descriptor.path.string(); + if constexpr (IsStreamingResource) + { + asset.m_resource = fs->Open(std::string_view(filepath), asset.m_descriptor.parameters); + } + else + { + asset.m_resource = fs->Load(std::string_view(filepath), asset.m_descriptor.parameters); + } + } + } + + if (!asset) // if it fails, use the default loader + { + JsonSerializationContext json; + if (!json.Load(path)) + return {}; + + if (!Unserialize(json, "", &asset.m_descriptor)) + return {}; + + if constexpr (IsStreamingResource) + { + asset.m_resource = TResource::OpenFromFile(asset.m_descriptor.path, asset.m_descriptor.parameters); + } + else + { + asset.m_resource = TResource::LoadFromFile(asset.m_descriptor.path, asset.m_descriptor.parameters); + } + } + + return asset; + } +} diff --git a/include/Nazara/Core/AssetCatalog.hpp b/include/Nazara/Core/AssetCatalog.hpp deleted file mode 100644 index 6b595d390..000000000 --- a/include/Nazara/Core/AssetCatalog.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include -#include - -namespace Nz -{ - class NAZARA_CORE_API AssetCatalog - { - public: - template - static Asset LoadFromFile(const std::filesystem::path& path); - }; -} - -#include diff --git a/include/Nazara/Core/AssetCatalog.inl b/include/Nazara/Core/AssetCatalog.inl deleted file mode 100644 index 97b07eb97..000000000 --- a/include/Nazara/Core/AssetCatalog.inl +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include - -namespace Nz -{ - template - concept IsStreamingResource = requires(TResource) - { - { TResource::OpenFromFile({}) } -> std::same_as>; - }; - - template - Asset AssetCatalog::LoadFromFile(const std::filesystem::path& path) - { - Asset asset; - - FilesystemAppComponent* fs = ApplicationBase::Instance()->TryGetComponent(); - if (fs) // first try using a FileSystem component to load the asset - { - auto json = fs->Load(std::string_view(path.string())); - - if (!Unserialize(*json, "", &asset.m_descriptor)) - return {}; - - - std::string filepath = asset.m_descriptor.path.string(); - if constexpr (IsStreamingResource) - { - asset.m_resource = fs->Open(std::string_view(filepath), asset.m_descriptor.parameters); - } - else - { - asset.m_resource = fs->Load(std::string_view(filepath), asset.m_descriptor.parameters); - } - } - - if (!asset) // if it fails, use the default loader - { - JsonSerializationContext json; - if (!json.Load(path)) - return {}; - - if (!Unserialize(json, "", &asset.m_descriptor)) - return {}; - - if constexpr (IsStreamingResource) - { - asset.m_resource = TResource::OpenFromFile(asset.m_descriptor.path, asset.m_descriptor.parameters); - } - else - { - asset.m_resource = TResource::LoadFromFile(asset.m_descriptor.path, asset.m_descriptor.parameters); - } - } - - return asset; - } -} diff --git a/include/Nazara/Core/AssetCatalogAppComponent.hpp b/include/Nazara/Core/AssetCatalogAppComponent.hpp new file mode 100644 index 000000000..b7d580962 --- /dev/null +++ b/include/Nazara/Core/AssetCatalogAppComponent.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include + +#include + +namespace Nz +{ + struct AssetHeaderLite + { + std::string name; + std::filesystem::path path; + + friend auto operator<=>(const AssetHeaderLite& A, const AssetHeaderLite& B) + { + return A.name <=> B.name; + } + }; + + NAZARA_CORE_API bool Serialize(struct SerializationContext& context, const AssetHeaderLite& header, TypeTag); + NAZARA_CORE_API bool Unserialize(struct SerializationContext& context, AssetHeaderLite* header, TypeTag); + + + class NAZARA_CORE_API AssetCatalogAppComponent + : public ApplicationComponent + { + public: + inline AssetCatalogAppComponent(ApplicationBase& app); + AssetCatalogAppComponent(const AssetCatalogAppComponent&) = delete; + AssetCatalogAppComponent(AssetCatalogAppComponent&&) = delete; + ~AssetCatalogAppComponent() = default; + + void AddFolder(std::string_view folder); + + template + inline Asset Load(std::string_view name) const; + + protected: + std::set m_assets; + }; +} + +#include diff --git a/include/Nazara/Core/AssetCatalogAppComponent.inl b/include/Nazara/Core/AssetCatalogAppComponent.inl new file mode 100644 index 000000000..fc034be21 --- /dev/null +++ b/include/Nazara/Core/AssetCatalogAppComponent.inl @@ -0,0 +1,19 @@ + +namespace Nz +{ + inline AssetCatalogAppComponent::AssetCatalogAppComponent(ApplicationBase& app) + : ApplicationComponent(app) + { + } + + template + Asset AssetCatalogAppComponent::Load(std::string_view name) const + { + AssetHeaderLite header{ std::string(name), "" }; + auto it = m_assets.find(header); + if (it == m_assets.end()) + return {}; + + return Asset::LoadFromFile(it->path); + } +} diff --git a/src/Nazara/Core/AssetCatalogAppComponent.cpp b/src/Nazara/Core/AssetCatalogAppComponent.cpp new file mode 100644 index 000000000..9a849ad54 --- /dev/null +++ b/src/Nazara/Core/AssetCatalogAppComponent.cpp @@ -0,0 +1,52 @@ + +#include +#include + +namespace Nz +{ + bool Serialize(SerializationContext& context, const AssetHeaderLite& header, TypeTag) + { + Serialize(context, "name", header.name); + Serialize(context, "path", header.path); + return true; + } + + bool Unserialize(SerializationContext& context, AssetHeaderLite* header, TypeTag) + { + Unserialize(context, "name", &header->name); + Unserialize(context, "path", &header->path); + return true; + } + + void AddFile(std::set& container, Nz::Stream& stream) + { + AssetHeaderLite header; + auto json = JsonSerializationContext::LoadFromStream(stream); + if (!json) + return; + + if (!Unserialize(*json, "", &header)) + return; + + header.path = stream.GetPath(); + container.insert(header); + } + + void AssetCatalogAppComponent::AddFolder(std::string_view folder) + { + auto& fs = GetApp().GetComponent(); + auto directory = fs.GetDirectory(folder); + if (!directory) + return; + + directory->Foreach([&](std::string_view, const VirtualDirectory::Entry& entry) { + if (std::holds_alternative(entry)) + { + auto& file = std::get(entry); + + if (file.stream->GetPath().extension() == ".nzasset") + AddFile(m_assets, *file.stream.get()); + } + }, true); + } +}