From 0467053f7f0b01747185b212824cafa48dea6698 Mon Sep 17 00:00:00 2001 From: karnage Date: Tue, 8 Jul 2025 19:42:24 -0700 Subject: [PATCH] `Resources`: persistent asset storage --- src/app.cpp | 4 +-- src/app.hpp | 3 ++- src/game.cpp | 5 ++-- src/game.hpp | 3 +-- src/lighthouse.cpp | 6 ++--- src/lighthouse.hpp | 3 --- src/resources.cpp | 15 +++++++++++ src/resources.hpp | 67 ++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 93 insertions(+), 13 deletions(-) create mode 100644 src/resources.cpp create mode 100644 src/resources.hpp diff --git a/src/app.cpp b/src/app.cpp index a525495..a0f080e 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -14,7 +14,7 @@ constexpr auto context_ci = le::Context::CreateInfo{ }; } // namespace -App::App() : m_context(context_ci), m_data_loader(le::FileDataLoader::upfind("assets")), m_asset_loader(m_context.create_asset_loader(&m_data_loader)) { +App::App() : m_context(context_ci), m_data_loader(le::FileDataLoader::upfind("assets")), m_resources(m_context.create_asset_loader(&m_data_loader)) { bind_services(); } @@ -43,6 +43,6 @@ void App::bind_services() { m_services.bind(&m_data_loader); m_services.bind(&m_data_loader); - m_services.bind(&m_asset_loader); + m_services.bind(&m_resources); } } // namespace miracle diff --git a/src/app.hpp b/src/app.hpp index 1d63270..90a9b92 100644 --- a/src/app.hpp +++ b/src/app.hpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace miracle { class App { @@ -15,7 +16,7 @@ class App { le::Context m_context; le::FileDataLoader m_data_loader{}; - le::AssetLoader m_asset_loader{}; + Resources m_resources; le::ServiceLocator m_services{}; }; diff --git a/src/game.cpp b/src/game.cpp index 3221fdb..c178b32 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -15,8 +16,8 @@ namespace miracle { Game::Game(gsl::not_null services) : m_services(services), m_lighthouse(services), m_light(services) { spawn_wave(); - auto const& asset_loader = services->get(); - m_font = asset_loader.load("fonts/specialElite.ttf"); + auto& resources = services->get(); + m_font = resources.load("fonts/specialElite.ttf"); if (!m_font) { throw std::runtime_error{"Failed to load font"}; } } diff --git a/src/game.hpp b/src/game.hpp index 2b599db..8f0e63e 100644 --- a/src/game.hpp +++ b/src/game.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include "enemy.hpp" #include "le2d/drawable/text.hpp" #include "le2d/resource/font.hpp" @@ -29,7 +28,7 @@ class Game { Lighthouse m_lighthouse; Light m_light; - std::unique_ptr m_font{}; + le::IFont* m_font{}; le::drawable::Text m_score_text{}; le::drawable::Text m_health_text{}; int m_score{}; diff --git a/src/lighthouse.cpp b/src/lighthouse.cpp index 7b3bc8c..10279e4 100644 --- a/src/lighthouse.cpp +++ b/src/lighthouse.cpp @@ -1,13 +1,13 @@ #include #include +#include #include "glm/gtx/norm.hpp" namespace miracle { Lighthouse::Lighthouse(gsl::not_null services) : m_services(services) { m_sprite.create(m_hitbox_diameter); - auto const& asset_loader = services->get(); - m_texture = asset_loader.load("images/lighthouse.png"); - m_sprite.texture = m_texture.get(); + auto& resources = services->get(); + m_sprite.texture = resources.load("images/lighthouse.png"); } void Lighthouse::rotate_towards_cursor(glm::vec2 cursor_pos) { diff --git a/src/lighthouse.hpp b/src/lighthouse.hpp index 7a035b2..711f3f1 100644 --- a/src/lighthouse.hpp +++ b/src/lighthouse.hpp @@ -6,9 +6,7 @@ #include #include #include -#include #include "enemy.hpp" -#include "le2d/resource/texture.hpp" namespace miracle { class Lighthouse { @@ -26,7 +24,6 @@ class Lighthouse { gsl::not_null m_services; float m_hitbox_diameter{150.0f}; float m_visibility_diameter{250.0f}; - std::unique_ptr m_texture; le::drawable::Circle m_sprite{}; float m_health{100}; }; diff --git a/src/resources.cpp b/src/resources.cpp new file mode 100644 index 0000000..514538d --- /dev/null +++ b/src/resources.cpp @@ -0,0 +1,15 @@ +#include + +namespace miracle { +Resources::Resources(le::AssetLoader asset_loader) : m_asset_loader(std::move(asset_loader)) {} + +void Resources::erase(std::string_view const uri) { + if (auto const it = m_map.find(uri); it != m_map.end()) { m_map.erase(it); } +} + +auto Resources::find(std::string_view const uri, std::type_index const type) const -> le::IAsset* { + auto const it = m_map.find(uri); + if (it == m_map.end() || it->second.type != type) { return nullptr; } + return it->second.asset.get(); +} +} // namespace miracle diff --git a/src/resources.hpp b/src/resources.hpp new file mode 100644 index 0000000..510dc80 --- /dev/null +++ b/src/resources.hpp @@ -0,0 +1,67 @@ +#pragma once +#include +#include +#include +#include + +namespace miracle { +class Resources { + public: + explicit Resources(le::AssetLoader asset_loader); + + template AssetTypeT> + [[nodiscard]] auto insert(std::string uri, std::unique_ptr asset) -> AssetTypeT& { + KLIB_ASSERT(asset); + auto& ret = *asset; + m_map.insert_or_assign(std::move(uri), Entry::create(std::move(asset))); + return ret; + } + + void erase(std::string_view uri); + + [[nodiscard]] auto contains(std::string_view const uri) const -> bool { return m_map.contains(uri); } + + template AssetTypeT> + [[nodiscard]] auto peek(std::string_view const uri) const -> AssetTypeT* { + auto const it = m_map.find(uri); + if (it == m_map.end() || it->second.type != typeid(AssetTypeT)) { return nullptr; } + return static_cast(it->second.asset.get()); + } + + template AssetTypeT> + [[nodiscard]] auto at(std::string_view const uri) const -> AssetTypeT& { + auto* ret = peek(uri); + KLIB_ASSERT(ret); + return *ret; + } + + template AssetTypeT> + [[nodiscard]] auto load(std::string_view const uri) -> AssetTypeT* { + if (auto* ret = peek(uri); ret) { return ret; } + std::unique_ptr asset = m_asset_loader.load(uri); + if (!asset) { return nullptr; } + return &insert(std::string{uri}, std::move(asset)); + } + + void clear() { m_map.clear(); } + + [[nodiscard]] auto size() const -> std::size_t { return m_map.size(); } + [[nodiscard]] auto is_empty() const -> bool { return m_map.empty(); } + + private: + struct Entry { + template + [[nodiscard]] static auto create(std::unique_ptr asset) -> Entry { + return Entry{.type = typeid(T), .asset = std::move(asset)}; + } + + std::type_index type; + std::unique_ptr asset{}; + }; + + [[nodiscard]] auto find(std::string_view uri, std::type_index type) const -> le::IAsset*; + + le::AssetLoader m_asset_loader; + dj::StringTable m_map{}; +}; +} // namespace miracle