diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-02-11 00:39:28 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-02-11 08:49:51 +0100 |
commit | 5267d7b5b52fb8112dc4001b3b8f7985521af5ba (patch) | |
tree | 32952992edee1144841b1cb8d69965ee981fe870 | |
parent | b8c538bcdfdcc7f2739934ea96fe98ae61b565dc (diff) |
wip atlas loader
-rw-r--r-- | loader/anim-traits.cpp | 13 | ||||
-rw-r--r-- | loader/anim-traits.hpp | 28 | ||||
-rw-r--r-- | loader/atlas-loader.inl | 40 | ||||
-rw-r--r-- | loader/ground-traits.cpp | 38 | ||||
-rw-r--r-- | loader/ground-traits.hpp | 4 | ||||
-rw-r--r-- | loader/wall-traits.cpp | 33 | ||||
-rw-r--r-- | 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 <cr/StringView.h> +#include <cr/Optional.h> +#include <mg/ImageData.h> +#include <mg/ImageView.h> + +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 <memory> + +namespace floormat { struct anim_cell; class anim_atlas; } + +namespace floormat::loader_detail { + +template<> struct atlas_loader_traits<anim_atlas> +{ + using Atlas = anim_atlas; + using Cell = anim_cell; // convertible to atlas and holding the atlas + using Self = atlas_loader_traits<Atlas>; + using Storage = atlas_storage<Atlas, Self>; + + static StringView loader_name(); + static const std::shared_ptr<Atlas>& atlas_of(const Cell& x); + static std::shared_ptr<Atlas>& 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<Atlas> make_atlas(StringView name, const Cell& c); + static Optional<Cell> 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<TRAITS, typename TRAITS:: template<typename ATLAS, typename TRAITS> auto atlas_loader<ATLAS, TRAITS>::ensure_atlas_list() -> ArrayView<const Cell> { - 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<typename ATLAS, typename TRAITS> const std::shared_ptr<ATLAS>& atlas_loader<ATLAS, TRAITS>::get_atlas(StringView name, loader_policy p) { ensure_atlas_list(); - const std::shared_ptr<Atlas>& invalid_atlas = t.atlas_of(t.make_invalid_atlas(s)); + const std::shared_ptr<Atlas>& invalid_atlas = t.atlas_of(get_invalid_atlas()); fm_debug_assert(invalid_atlas); switch (p) @@ -152,9 +176,13 @@ auto atlas_loader<ATLAS, TRAITS>::make_atlas(StringView name, const Cell& c) -> template<typename ATLAS, typename TRAITS> auto atlas_loader<ATLAS, TRAITS>::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<Cell> { - if (!s.invalid_atlas) [[unlikely]] - { - auto atlas = std::make_shared<Atlas>( - ground_def{loader.INVALID, Vector2ub{1,1}, pass_mode::pass}, - loader.make_error_texture(Vector2ui(tile_size_xy))); - s.invalid_atlas = Pointer<ground_cell>{ InPlaceInit, atlas, atlas->name(), atlas->num_tiles2(), atlas->pass_mode() }; - } - return *s.invalid_atlas; + fm_assert(!s.invalid_atlas); + auto atlas = std::make_shared<Atlas>( + ground_def{loader.INVALID, Vector2ub{1,1}, pass_mode::pass}, + loader.make_error_texture(Vector2ui(tile_size_xy))); + return Pointer<ground_cell>{ InPlaceInit, atlas, atlas->name(), atlas->num_tiles2(), atlas->pass_mode() }; } auto ground_traits::make_atlas(StringView name, const Cell& c) -> std::shared_ptr<Atlas> 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<ground_atlas> 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<Cell> make_invalid_atlas(Storage& st); static std::shared_ptr<Atlas> make_atlas(StringView name, const Cell& c); static Optional<Cell> 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<Cell> { - 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<wall_cell>{InPlaceInit, wall_cell{ .atlas = std::move(a), .name = name, } }; - return *st.invalid_atlas; + return Pointer<wall_cell>{InPlaceInit, wall_cell{ .atlas = std::move(a), .name = name, } }; } auto wall_traits::make_atlas(StringView name, const Cell&) -> std::shared_ptr<Atlas> 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<wall_atlas> 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<Cell> make_invalid_atlas(Storage& st); static std::shared_ptr<Atlas> make_atlas(StringView name, const Cell& c); static Optional<Cell> make_cell(StringView name); }; |