From ca0c4a5db733af1f70e10035e837f7bef6f161c7 Mon Sep 17 00:00:00 2001 From: SirLynix Date: Sun, 22 Jan 2023 18:00:26 +0100 Subject: [PATCH] Core: Add AppFilesystemComponent --- examples/WidgetDemo/main.cpp | 5 +- include/Nazara/Core.hpp | 1 + .../Nazara/Core/AppFilesystemComponent.hpp | 44 ++++++++++++ .../Nazara/Core/AppFilesystemComponent.inl | 72 +++++++++++++++++++ src/Nazara/Core/AppFilesystemComponent.cpp | 10 +++ 5 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 include/Nazara/Core/AppFilesystemComponent.hpp create mode 100644 include/Nazara/Core/AppFilesystemComponent.inl create mode 100644 src/Nazara/Core/AppFilesystemComponent.cpp diff --git a/examples/WidgetDemo/main.cpp b/examples/WidgetDemo/main.cpp index fd6b87cd9..a2f83c77f 100644 --- a/examples/WidgetDemo/main.cpp +++ b/examples/WidgetDemo/main.cpp @@ -45,6 +45,9 @@ int main() auto& ecs = app.AddComponent(); + auto& fs = app.AddComponent(); + fs.RegisterPath(resourceDir); + Nz::RenderSystem& renderSystem = ecs.AddSystem(); auto& windowSwapchain = renderSystem.CreateSwapchain(mainWindow); @@ -76,7 +79,7 @@ int main() texParams.loadFormat = Nz::PixelFormat::RGBA8_SRGB; std::shared_ptr materialInstance = material->Instantiate(); - materialInstance->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png", texParams)); + materialInstance->SetTextureProperty("BaseColorMap", fs.GetOrLoad("Spaceship/Texture/diffuse.png", texParams)); Nz::ImageWidget* imageWidget = canvas2D.Add(materialInstance); imageWidget->SetPosition(1200.f, 200.f); diff --git a/include/Nazara/Core.hpp b/include/Nazara/Core.hpp index 86bd4fc88..c1279509c 100644 --- a/include/Nazara/Core.hpp +++ b/include/Nazara/Core.hpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/Core/AppFilesystemComponent.hpp b/include/Nazara/Core/AppFilesystemComponent.hpp new file mode 100644 index 000000000..a3c16e163 --- /dev/null +++ b/include/Nazara/Core/AppFilesystemComponent.hpp @@ -0,0 +1,44 @@ +// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com) +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_CORE_APPFILESYSTEMCOMPONENT_HPP +#define NAZARA_CORE_APPFILESYSTEMCOMPONENT_HPP + +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_CORE_API AppFilesystemComponent : public ApplicationComponent + { + public: + using ApplicationComponent::ApplicationComponent; + AppFilesystemComponent(const AppFilesystemComponent&) = delete; + AppFilesystemComponent(AppFilesystemComponent&&) = delete; + ~AppFilesystemComponent() = default; + + template std::shared_ptr GetOrLoad(std::string_view assetPath, Args&&... args); + + inline const VirtualDirectoryPtr& RegisterPath(std::filesystem::path filepath); + inline const VirtualDirectoryPtr& RegisterVirtualDirectory(VirtualDirectoryPtr directory); + + inline void UnregisterVirtualDirectory(const VirtualDirectoryPtr& directory); + + AppFilesystemComponent& operator=(const AppFilesystemComponent&) = delete; + AppFilesystemComponent& operator=(AppFilesystemComponent&&) = delete; + + private: + std::vector m_virtualDirectories; + }; +} + +#include + +#endif // NAZARA_CORE_APPFILESYSTEMCOMPONENT_HPP diff --git a/include/Nazara/Core/AppFilesystemComponent.inl b/include/Nazara/Core/AppFilesystemComponent.inl new file mode 100644 index 000000000..3ca6e7d4c --- /dev/null +++ b/include/Nazara/Core/AppFilesystemComponent.inl @@ -0,0 +1,72 @@ +// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com) +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + template + std::shared_ptr AppFilesystemComponent::GetOrLoad(std::string_view assetPath, Args&&... args) + { + std::shared_ptr resource; + for (const VirtualDirectoryPtr& virtualDir : m_virtualDirectories) + { + auto callback = [&](const VirtualDirectory::Entry& entry) + { + return std::visit([&](auto&& arg) + { + using Param = std::decay_t; + if constexpr (std::is_base_of_v) + { + NazaraError(std::string(assetPath) + " is a directory"); + return false; + } + else if constexpr (std::is_same_v) + { + resource = T::LoadFromMemory(arg.data, arg.size, std::forward(args)...); + return true; + } + else if constexpr (std::is_same_v) + { + resource = T::LoadFromMemory(&arg.data[0], arg.data.size(), std::forward(args)...); + return true; + } + else if constexpr (std::is_same_v) + { + resource = T::LoadFromFile(arg.filePath, std::forward(args)...); + return true; + } + else + static_assert(AlwaysFalse(), "unhandled case"); + }, entry); + }; + + if (virtualDir->GetEntry(assetPath, callback) && resource) + return resource; + } + + return resource; + } + + inline const VirtualDirectoryPtr& AppFilesystemComponent::RegisterPath(std::filesystem::path filepath) + { + return RegisterVirtualDirectory(std::make_shared(std::move(filepath))); + } + + inline const VirtualDirectoryPtr& AppFilesystemComponent::RegisterVirtualDirectory(VirtualDirectoryPtr directory) + { + return m_virtualDirectories.emplace_back(std::move(directory)); + } + + inline void AppFilesystemComponent::UnregisterVirtualDirectory(const VirtualDirectoryPtr& directory) + { + auto it = std::find(m_virtualDirectories.begin(), m_virtualDirectories.end(), directory); + if (it == m_virtualDirectories.end()) + m_virtualDirectories.erase(it); + } +} + +#include diff --git a/src/Nazara/Core/AppFilesystemComponent.cpp b/src/Nazara/Core/AppFilesystemComponent.cpp new file mode 100644 index 000000000..04be6ad1d --- /dev/null +++ b/src/Nazara/Core/AppFilesystemComponent.cpp @@ -0,0 +1,10 @@ +// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com) +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ +}