From 5267d7b5b52fb8112dc4001b3b8f7985521af5ba Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 11 Feb 2024 00:39:28 +0100 Subject: wip atlas loader --- loader/anim-traits.cpp | 13 +++++++++++++ loader/anim-traits.hpp | 28 ++++++++++++++++++++++++++++ loader/atlas-loader.inl | 40 ++++++++++++++++++++++++++++++++++------ loader/ground-traits.cpp | 38 ++++++++++---------------------------- loader/ground-traits.hpp | 4 ++-- loader/wall-traits.cpp | 33 +++++++-------------------------- loader/wall-traits.hpp | 2 +- 7 files changed, 95 insertions(+), 63 deletions(-) diff --git a/loader/anim-traits.cpp b/loader/anim-traits.cpp index e69de29b..9741f62e 100644 --- a/loader/anim-traits.cpp +++ b/loader/anim-traits.cpp @@ -0,0 +1,13 @@ +#include "anim-traits.hpp" +#include "compat/exception.hpp" +#include "loader.hpp" +#include +#include +#include +#include + +namespace floormat::loader_detail { + + + +} // namespace floormat::loader_detail diff --git a/loader/anim-traits.hpp b/loader/anim-traits.hpp index e69de29b..3c4a43af 100644 --- a/loader/anim-traits.hpp +++ b/loader/anim-traits.hpp @@ -0,0 +1,28 @@ +#pragma once +#include "atlas-loader-fwd.hpp" +#include + +namespace floormat { struct anim_cell; class anim_atlas; } + +namespace floormat::loader_detail { + +template<> struct atlas_loader_traits +{ + using Atlas = anim_atlas; + using Cell = anim_cell; // convertible to atlas and holding the atlas + using Self = atlas_loader_traits; + using Storage = atlas_storage; + + static StringView loader_name(); + static const std::shared_ptr& atlas_of(const Cell& x); + static std::shared_ptr& atlas_of(Cell& x); + static StringView name_of(const Cell& x); + static StringView name_of(const Atlas& x); + static String& name_of(Cell& x); + static void ensure_atlases_loaded(Storage& st); + static const Cell& make_invalid_atlas(Storage& st); + static std::shared_ptr make_atlas(StringView name, const Cell& c); + static Optional make_cell(StringView name); +}; + +} // namespace floormat::loader_detail diff --git a/loader/atlas-loader.inl b/loader/atlas-loader.inl index af5d9567..f5cd39ea 100644 --- a/loader/atlas-loader.inl +++ b/loader/atlas-loader.inl @@ -25,13 +25,37 @@ atlas_loader(TRAITS&& traits) noexcept -> atlas_loader auto atlas_loader::ensure_atlas_list() -> ArrayView { - if (!s.cell_array.empty()) [[likely]] + if (!s.name_map.empty()) [[likely]] return { s.cell_array.data(), s.cell_array.size() }; + t.ensure_atlases_loaded(s); + for (Cell& c : s.cell_array) - if (String& name{t.name_of(c)}; name.isSmall()) + { + String& name{t.name_of(c)}; + if (name.isSmall()) name = String{AllocatedInit, name}; + fm_soft_assert(name != loader.INVALID); + fm_soft_assert(loader.check_atlas_name(name)); + } + + s.name_map.max_load_factor(0.4f); + s.name_map.reserve(s.cell_array.size()*3/2 + 1); + for (auto i = 0uz; const auto& c : s.cell_array) + s.name_map[t.name_of(c)] = i++; + + { const Cell& invalid_atlas{get_invalid_atlas()}; + size_t sz{s.cell_array.size()}; + s.cell_array.push_back(invalid_atlas); + s.name_map[loader.INVALID] = sz; + } + + fm_assert(!s.name_map.empty()); fm_assert(!s.cell_array.empty()); + + for (const auto& [name, index] : s.name_map) + fm_assert(index < s.cell_array.size() || index == -1uz); + return { s.cell_array.data(), s.cell_array.size() }; } @@ -39,7 +63,7 @@ template const std::shared_ptr& atlas_loader::get_atlas(StringView name, loader_policy p) { ensure_atlas_list(); - const std::shared_ptr& invalid_atlas = t.atlas_of(t.make_invalid_atlas(s)); + const std::shared_ptr& invalid_atlas = t.atlas_of(get_invalid_atlas()); fm_debug_assert(invalid_atlas); switch (p) @@ -152,9 +176,13 @@ auto atlas_loader::make_atlas(StringView name, const Cell& c) -> template auto atlas_loader::get_invalid_atlas() -> const Cell& { - const auto& cell = t.make_invalid_atlas(s); - fm_assert(t.atlas_of(cell)); - return cell; + if (s.invalid_atlas) [[likely]] + return *s.invalid_atlas; + s.invalid_atlas = t.make_invalid_atlas(s); + fm_assert(s.invalid_atlas); + fm_assert(t.atlas_of(*s.invalid_atlas)); + fm_assert(t.name_of(*s.invalid_atlas) == loader.INVALID); + return *s.invalid_atlas; } } // namespace floormat::loader_detail diff --git a/loader/ground-traits.cpp b/loader/ground-traits.cpp index 61df7831..e56f0692 100644 --- a/loader/ground-traits.cpp +++ b/loader/ground-traits.cpp @@ -22,39 +22,21 @@ StringView ground_traits::name_of(const Cell& x) { return x.name; } StringView ground_traits::name_of(const Atlas& x) { return x.name(); } String& ground_traits::name_of(Cell& x) { return x.name; } -void ground_traits::ensure_atlases_loaded(Storage& st) +void ground_traits::ensure_atlases_loaded(Storage& s) { - if (!st.name_map.empty()) [[likely]] - return; + fm_assert(s.name_map.empty()); - st.cell_array = ground_cell::load_atlases_from_json().vec; - st.name_map.max_load_factor(0.4f); - st.name_map.reserve((st.cell_array.size()+1)*3/2); - st.name_map[loader.INVALID] = -1uz; - - for (auto& c : st.cell_array) - if (c.name.isSmall()) - c.name = String{AllocatedInit, c.name}; - - for (auto i = 0uz; const auto& c : st.cell_array) - { - fm_soft_assert(c.name != loader.INVALID); - fm_soft_assert(loader.check_atlas_name(c.name)); - fm_soft_assert(!c.atlas); - st.name_map[c.name] = i++; - } + s.cell_array = ground_cell::load_atlases_from_json().vec; + s.name_map[loader.INVALID] = -1uz; } -auto ground_traits::make_invalid_atlas(Storage& s) -> const Cell& // todo! store it in cell_array +auto ground_traits::make_invalid_atlas(Storage& s) -> Pointer { - if (!s.invalid_atlas) [[unlikely]] - { - auto atlas = std::make_shared( - ground_def{loader.INVALID, Vector2ub{1,1}, pass_mode::pass}, - loader.make_error_texture(Vector2ui(tile_size_xy))); - s.invalid_atlas = Pointer{ InPlaceInit, atlas, atlas->name(), atlas->num_tiles2(), atlas->pass_mode() }; - } - return *s.invalid_atlas; + fm_assert(!s.invalid_atlas); + auto atlas = std::make_shared( + ground_def{loader.INVALID, Vector2ub{1,1}, pass_mode::pass}, + loader.make_error_texture(Vector2ui(tile_size_xy))); + return Pointer{ InPlaceInit, atlas, atlas->name(), atlas->num_tiles2(), atlas->pass_mode() }; } auto ground_traits::make_atlas(StringView name, const Cell& c) -> std::shared_ptr diff --git a/loader/ground-traits.hpp b/loader/ground-traits.hpp index bcd89cb1..6eaf3444 100644 --- a/loader/ground-traits.hpp +++ b/loader/ground-traits.hpp @@ -19,8 +19,8 @@ template<> struct atlas_loader_traits static StringView name_of(const Cell& x); static StringView name_of(const Atlas& x); static String& name_of(Cell& x); - static void ensure_atlases_loaded(Storage& st); - static const Cell& make_invalid_atlas(Storage& st); + static void ensure_atlases_loaded(Storage& s); + static Pointer make_invalid_atlas(Storage& st); static std::shared_ptr make_atlas(StringView name, const Cell& c); static Optional make_cell(StringView name); }; diff --git a/loader/wall-traits.cpp b/loader/wall-traits.cpp index d31aba4e..70d729c0 100644 --- a/loader/wall-traits.cpp +++ b/loader/wall-traits.cpp @@ -22,35 +22,17 @@ StringView wall_traits::name_of(const Cell& x) { return x.name; } StringView wall_traits::name_of(const Atlas& x) { return x.name(); } String& wall_traits::name_of(Cell& x) { return x.name; } -void wall_traits::ensure_atlases_loaded(Storage& st) +void wall_traits::ensure_atlases_loaded(Storage& s) { - if (!st.name_map.empty()) [[likely]] - return; + fm_assert(s.name_map.empty()); - st.cell_array = wall_cell::load_atlases_from_json().vec; - st.name_map.max_load_factor(0.4f); - st.name_map.reserve((st.cell_array.size()+1)*3/2); - st.name_map[loader.INVALID] = -1uz; - - for (auto& c : st.cell_array) - if (c.name.isSmall()) - c.name = String{AllocatedInit, c.name}; - - for (auto i = 0uz; const auto& c : st.cell_array) - { - fm_soft_assert(c.name != loader.INVALID); - fm_soft_assert(loader.check_atlas_name(c.name)); - fm_soft_assert(!c.atlas); - fm_assert(!c.name.isSmall()); - st.name_map[c.name] = i++; - } + s.cell_array = wall_cell::load_atlases_from_json().vec; + s.name_map[loader.INVALID] = -1uz; } -auto wall_traits::make_invalid_atlas(Storage& st) -> const Cell& +auto wall_traits::make_invalid_atlas(Storage& s) -> Pointer { - if (st.invalid_atlas) [[likely]] - return *st.invalid_atlas; - + fm_assert(!s.invalid_atlas); constexpr auto name = loader_::INVALID; constexpr auto frame_size = Vector2ui{tile_size_xy, tile_size_z}; @@ -64,8 +46,7 @@ auto wall_traits::make_invalid_atlas(Storage& st) -> const Cell& {{ {.val = 0}, {}, }}, {1u}, }, name, loader.make_error_texture(frame_size)); - st.invalid_atlas = Pointer{InPlaceInit, wall_cell{ .atlas = std::move(a), .name = name, } }; - return *st.invalid_atlas; + return Pointer{InPlaceInit, wall_cell{ .atlas = std::move(a), .name = name, } }; } auto wall_traits::make_atlas(StringView name, const Cell&) -> std::shared_ptr diff --git a/loader/wall-traits.hpp b/loader/wall-traits.hpp index d0497ea4..a3134b22 100644 --- a/loader/wall-traits.hpp +++ b/loader/wall-traits.hpp @@ -20,7 +20,7 @@ template<> struct atlas_loader_traits static StringView name_of(const Atlas& x); static String& name_of(Cell& x); static void ensure_atlases_loaded(Storage& st); - static const Cell& make_invalid_atlas(Storage& st); + static Pointer make_invalid_atlas(Storage& st); static std::shared_ptr make_atlas(StringView name, const Cell& c); static Optional make_cell(StringView name); }; -- cgit v1.2.3