From 017cb08bf33608f1ceb8d59800a8d1d2f9d5d455 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 11 Feb 2024 08:32:10 +0100 Subject: loader: allow adding atlases to the list without parsing them --- loader/anim-atlas.cpp | 4 ---- loader/anim-traits.cpp | 2 +- loader/anim-traits.hpp | 2 +- loader/atlas-loader-storage.hpp | 4 ++-- loader/atlas-loader.hpp | 4 ++++ loader/atlas-loader.inl | 32 ++++++++++++++++++++++++- loader/ground-atlas.cpp | 8 ++++--- loader/ground-traits.cpp | 2 +- loader/ground-traits.hpp | 2 +- loader/wall-traits.cpp | 2 +- loader/wall-traits.hpp | 2 +- test/anim-atlas.cpp | 16 ------------- test/app.cpp | 9 +++---- test/app.hpp | 4 ++-- test/loader.cpp | 52 +++++++++++++++++++++++++++++++++-------- test/serializer.cpp | 2 +- 16 files changed, 98 insertions(+), 49 deletions(-) delete mode 100644 test/anim-atlas.cpp diff --git a/loader/anim-atlas.cpp b/loader/anim-atlas.cpp index be7cc688..1c1a7ec0 100644 --- a/loader/anim-atlas.cpp +++ b/loader/anim-atlas.cpp @@ -3,7 +3,6 @@ #include "anim-cell.hpp" #include "anim-traits.hpp" #include "compat/exception.hpp" -//#include "src/anim-atlas.hpp" namespace floormat::loader_detail { @@ -26,11 +25,8 @@ ArrayView loader_impl::anim_atlas_list() std::shared_ptr loader_impl::anim_atlas(StringView name, StringView dir, loader_policy p) noexcept(false) { - fm_soft_assert(check_atlas_name(name)); - char buf[fm_FILENAME_MAX]; auto path = make_atlas_path(buf, dir, name); - return _anim_loader->get_atlas(path, p); } diff --git a/loader/anim-traits.cpp b/loader/anim-traits.cpp index e15956e9..dafed985 100644 --- a/loader/anim-traits.cpp +++ b/loader/anim-traits.cpp @@ -26,7 +26,7 @@ StringView anim_traits::name_of(const Cell& x) { return x.name; } StringView anim_traits::name_of(const Atlas& x) { return x.name(); } String& anim_traits::name_of(Cell& x) { return x.name; } -void anim_traits::ensure_atlases_loaded(Storage& s) +void anim_traits::load_atlas_list(Storage& s) { fm_debug_assert(s.name_map.empty()); s.cell_array = {}; diff --git a/loader/anim-traits.hpp b/loader/anim-traits.hpp index 8eef8b89..70ddcd89 100644 --- a/loader/anim-traits.hpp +++ b/loader/anim-traits.hpp @@ -19,7 +19,7 @@ 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 void load_atlas_list(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); diff --git a/loader/atlas-loader-storage.hpp b/loader/atlas-loader-storage.hpp index ca3ccbab..aea94e48 100644 --- a/loader/atlas-loader-storage.hpp +++ b/loader/atlas-loader-storage.hpp @@ -13,8 +13,8 @@ struct atlas_storage static_assert(std::is_same_v); using Traits = TRAITS; - using Atlas = typename TRAITS::Atlas; - using Cell = typename TRAITS::Cell; + using Atlas = typename Traits::Atlas; + using Cell = typename Traits::Cell; tsl::robin_map name_map; std::vector cell_array; diff --git a/loader/atlas-loader.hpp b/loader/atlas-loader.hpp index 3dc1707a..919e4c90 100644 --- a/loader/atlas-loader.hpp +++ b/loader/atlas-loader.hpp @@ -28,6 +28,10 @@ public: const std::shared_ptr& get_atlas(StringView name, loader_policy p); std::shared_ptr make_atlas(StringView name, const Cell& cell); + bool cell_exists(StringView name); + const Cell& get_cell(StringView name); + void register_cell(Cell&& c); + const Cell& get_invalid_atlas(); }; diff --git a/loader/atlas-loader.inl b/loader/atlas-loader.inl index 08667d63..78bafaac 100644 --- a/loader/atlas-loader.inl +++ b/loader/atlas-loader.inl @@ -8,6 +8,7 @@ #include #include #include +#include namespace floormat::loader_detail { @@ -28,7 +29,7 @@ auto atlas_loader::ensure_atlas_list() -> ArrayView if (!s.name_map.empty()) [[likely]] return { s.cell_array.data(), s.cell_array.size() }; - t.ensure_atlases_loaded(s); + t.load_atlas_list(s); for (Cell& c : s.cell_array) { @@ -190,4 +191,33 @@ auto atlas_loader::get_invalid_atlas() -> const Cell& return *s.invalid_atlas; } +template +bool atlas_loader::cell_exists(Corrade::Containers::StringView name) +{ + return s.name_map.contains(name); +} + +template +auto atlas_loader::get_cell(StringView name) -> const Cell& +{ + auto it = s.name_map.find(name); + fm_assert(it != s.name_map.end()); + return s.cell_array[ it->second ]; +} + +template +void atlas_loader::register_cell(Cell&& c) +{ + String& name{t.name_of(c)}; + if (name.isSmall()) + name = String{AllocatedInit, name}; + const std::shared_ptr& atlas{t.atlas_of(c)}; + fm_assert(!s.name_map.contains(name)); + fm_soft_assert(loader.check_atlas_name(name)); + fm_assert(!atlas || t.name_of(*atlas) == name); + const size_t index{s.cell_array.size()}; + s.cell_array.push_back(Utility::move(c)); + s.name_map[ t.name_of(s.cell_array.back()) ] = index; +} + } // namespace floormat::loader_detail diff --git a/loader/ground-atlas.cpp b/loader/ground-atlas.cpp index 9ca9cb9b..6e829b13 100644 --- a/loader/ground-atlas.cpp +++ b/loader/ground-atlas.cpp @@ -11,10 +11,9 @@ template class atlas_loader; std::shared_ptr loader_impl::get_ground_atlas(StringView name, Vector2ub size, pass_mode pass) noexcept(false) { - auto atlas = _ground_loader->make_atlas(name, { + return _ground_loader->make_atlas(name, { .atlas = {}, .name = {}, .size = size, .pass = pass, }); - return atlas; } atlas_loader* loader_impl::make_ground_atlas_loader() @@ -22,7 +21,10 @@ atlas_loader* loader_impl::make_ground_atlas_loader() return new atlas_loader; } -auto loader_impl::ground_atlas_list() noexcept(false) -> ArrayView { return _ground_loader->ensure_atlas_list(); } +auto loader_impl::ground_atlas_list() noexcept(false) -> ArrayView +{ + return _ground_loader->ensure_atlas_list(); +} const ground_cell& loader_impl::make_invalid_ground_atlas() { diff --git a/loader/ground-traits.cpp b/loader/ground-traits.cpp index ae6e17bc..e913d385 100644 --- a/loader/ground-traits.cpp +++ b/loader/ground-traits.cpp @@ -22,7 +22,7 @@ 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& s) +void ground_traits::load_atlas_list(Storage& s) { fm_debug_assert(s.name_map.empty()); s.cell_array = ground_cell::load_atlases_from_json().vec; diff --git a/loader/ground-traits.hpp b/loader/ground-traits.hpp index 6eaf3444..91f6c3aa 100644 --- a/loader/ground-traits.hpp +++ b/loader/ground-traits.hpp @@ -19,7 +19,7 @@ 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& s); + static void load_atlas_list(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 182d30b2..634659cd 100644 --- a/loader/wall-traits.cpp +++ b/loader/wall-traits.cpp @@ -22,7 +22,7 @@ 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& s) +void wall_traits::load_atlas_list(Storage& s) { fm_debug_assert(s.name_map.empty()); s.cell_array = wall_cell::load_atlases_from_json().vec; diff --git a/loader/wall-traits.hpp b/loader/wall-traits.hpp index a3134b22..e773ef58 100644 --- a/loader/wall-traits.hpp +++ b/loader/wall-traits.hpp @@ -19,7 +19,7 @@ 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 void load_atlas_list(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); diff --git a/test/anim-atlas.cpp b/test/anim-atlas.cpp deleted file mode 100644 index 9f84a6ff..00000000 --- a/test/anim-atlas.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "app.hpp" - -namespace { - - - -} // namespace - -namespace floormat { - -void test_app::test_anim_atlas() -{ - -} - -} // namespace floormat diff --git a/test/app.cpp b/test/app.cpp index 99326c29..e896196d 100644 --- a/test/app.cpp +++ b/test/app.cpp @@ -60,12 +60,12 @@ int test_app::exec() FM_TEST(test_bitmask), FM_TEST(test_loader), FM_TEST(test_serializer1), - FM_TEST(test_anim_atlas), + FM_TEST(test_loader2), FM_TEST(test_scenery), FM_TEST(test_astar_pool), FM_TEST(test_astar), - FM_TEST(test_dijkstra), // todo add dummy atlases to avoid expensive loading - FM_TEST(test_load_all), + FM_TEST(test_dijkstra), + FM_TEST(test_saves), FM_TEST(test_zzz_misc), }; @@ -102,7 +102,8 @@ int test_app::exec() std::fwrite(name.data(), name.size(), 1, s); if constexpr(!sep.isEmpty()) std::fwrite(sep.data(), sep.size(), 1, s); - auto num_tabs = max_tabs - get_tabs(name); + auto num_tabs = max_tabs - get_tabs(name) - 1; + std::fputc('\t', s); std::fflush(stdout); auto ms = get_time(fun); fm_assert(num_tabs <= tab_limit); diff --git a/test/app.hpp b/test/app.hpp index 41f01507..e8669aed 100644 --- a/test/app.hpp +++ b/test/app.hpp @@ -21,7 +21,6 @@ struct test_app final : private FM_APPLICATION int exec() override; - static void test_anim_atlas(); static void test_astar(); static void test_astar_pool(); static void test_bitmask(); @@ -33,8 +32,9 @@ struct test_app final : private FM_APPLICATION static void test_json(); static void test_json2(); static void test_json3(); - static void test_load_all(); + static void test_saves(); static void test_loader(); + static void test_loader2(); static void test_magnum_math(); static void test_math(); static void test_raycast(); diff --git a/test/loader.cpp b/test/loader.cpp index e3e6921d..01792bd6 100644 --- a/test/loader.cpp +++ b/test/loader.cpp @@ -2,8 +2,10 @@ #include "compat/assert.hpp" #include "loader/loader.hpp" #include "loader/wall-cell.hpp" +#include "loader/anim-cell.hpp" #include "src/ground-atlas.hpp" #include "src/wall-atlas.hpp" +#include "src/anim-atlas.hpp" #include namespace floormat { @@ -62,24 +64,54 @@ void test_app::test_loader() fm_assert(!A.raw_frame_array().isEmpty()); fm_assert(A.texture().id()); } + fm_assert(loader.ground_atlas("texel")->pass_mode() == pass_mode::blocked); + fm_assert(loader.ground_atlas("metal1")->pass_mode() == pass_mode::pass); + loader.sceneries(); +} +void test_app::test_loader2() +{ for (const auto& x : loader.ground_atlas_list()) { - if (x.name != loader.INVALID) + fm_assert(x.name); + if (x.name == loader.INVALID) + continue; + if (!x.atlas) { - (void)loader.ground_atlas(x.name); - fm_assert(x.atlas); - fm_assert(x.atlas == loader.ground_atlas(x.name)); + auto atlas = loader.ground_atlas(x.name, loader_policy::error); + fm_assert(atlas->name() == x.name); + fm_assert(atlas->texture().id()); + fm_assert(!atlas->pixel_size().isZero()); + fm_assert(Vector2ui{atlas->num_tiles2()}.product()); } - else + } + for (const auto& x : loader.wall_atlas_list()) + { + fm_assert(x.name); + if (x.name == loader.INVALID) + continue; + if (!x.atlas) { - fm_assert(x.atlas); - fm_assert(x.atlas == loader.make_invalid_ground_atlas().atlas); + auto atlas = loader.wall_atlas(x.name, loader_policy::error); + fm_assert(atlas->name() == x.name); + fm_assert(atlas->texture().id()); + fm_assert(!atlas->raw_frame_array().isEmpty()); + fm_assert(atlas->calc_direction(Wall::Direction_::N).wall.count); } } - fm_assert(loader.ground_atlas("texel")->pass_mode() == pass_mode::blocked); - fm_assert(loader.ground_atlas("metal1")->pass_mode() == pass_mode::pass); - loader.sceneries(); + for (const auto& x : loader.anim_atlas_list()) + { + fm_assert(x.name); + if (x.name == loader.INVALID) + continue; + auto atlas_ = loader.anim_atlas(x.name, {}, loader_policy::error); + fm_assert(atlas_); + auto& atlas = *atlas_; + fm_assert(atlas.name() == x.name); + fm_assert(atlas.texture().id()); + fm_assert(atlas.info().nframes > 0); + } + // todo scenery_cell } } // namespace floormat diff --git a/test/serializer.cpp b/test/serializer.cpp index d4f08d48..44746449 100644 --- a/test/serializer.cpp +++ b/test/serializer.cpp @@ -145,7 +145,7 @@ void test_app::test_serializer1() test_serializer({}, tmp_filename); } -void test_app::test_load_all() +void test_app::test_saves() { fm_assert(Path::exists(Path::join(loader.TEMP_PATH, "CMakeCache.txt"))); const auto tmp_filename = Path::join(loader.TEMP_PATH, "test/test-serializer2.dat"_s); -- cgit v1.2.3