diff options
-rw-r--r-- | loader/atlas-loader-storage.hpp | 3 | ||||
-rw-r--r-- | loader/atlas-loader.inl | 21 | ||||
-rw-r--r-- | loader/ground-traits.cpp | 12 | ||||
-rw-r--r-- | loader/ground-traits.hpp | 2 | ||||
-rw-r--r-- | loader/wall-traits.cpp | 20 | ||||
-rw-r--r-- | loader/wall-traits.hpp | 3 | ||||
-rw-r--r-- | src/wall-atlas.hpp | 2 |
7 files changed, 45 insertions, 18 deletions
diff --git a/loader/atlas-loader-storage.hpp b/loader/atlas-loader-storage.hpp index f428be0a..a1f2e20d 100644 --- a/loader/atlas-loader-storage.hpp +++ b/loader/atlas-loader-storage.hpp @@ -14,10 +14,11 @@ struct atlas_storage tsl::robin_map<StringView, Cell*, hash_string_view> name_map; std::vector<Cell> cell_array; + std::vector<Pointer<Cell>> free_cells; std::vector<String> missing_atlas_names; Pointer<Cell> invalid_atlas; - bool is_empty() const { return cell_array.empty(); } + ~atlas_storage() noexcept = default; }; } // namespace floormat::loader_detail diff --git a/loader/atlas-loader.inl b/loader/atlas-loader.inl index 5488cad1..0a50821f 100644 --- a/loader/atlas-loader.inl +++ b/loader/atlas-loader.inl @@ -1,11 +1,13 @@ #pragma once #include "compat/assert.hpp" #include "compat/exception.hpp" +#include "compat/os-file.hpp" #include "atlas-loader.hpp" #include "atlas-loader-storage.hpp" #include "loader/loader.hpp" #include <memory> -#include <Corrade/Containers/ArrayView.h> +#include <cr/ArrayView.h> +#include <cr/Optional.h> namespace floormat::loader_detail { @@ -81,7 +83,23 @@ const std::shared_ptr<ATLAS>& atlas_loader<ATLAS, TRAITS>::get_atlas(StringView else return t.atlas_of(*it->second) = t.make_atlas(name, *it->second); } + else if (Optional<Cell> c_{t.make_cell(name)}) + { + s.free_cells.reserve(16); + Pointer<Cell> cptr{InPlace, std::move(*c_)}; + { Cell& c{*cptr}; + fm_assert(!t.name_of(c)); fm_assert(!t.atlas_of(c)); + t.atlas_of(c) = t.make_atlas(name, c); + fm_assert(!t.name_of(c)); fm_assert(t.atlas_of(c)); + t.name_of(c) = name; + fm_assert(t.name_of(*t.atlas_of(c)) == name); + } + s.free_cells.push_back(Utility::move(cptr)); + Cell& back{*s.free_cells.back()}; + s.name_map[StringView{t.name_of(back)}] = &back; + } else + { switch (p) { using enum loader_policy; @@ -92,6 +110,7 @@ const std::shared_ptr<ATLAS>& atlas_loader<ATLAS, TRAITS>::get_atlas(StringView case ignore: return t.atlas_of(*invalid_atlas); } + } std::unreachable(); fm_assert(false); diff --git a/loader/ground-traits.cpp b/loader/ground-traits.cpp index e9a82b24..f1ed3090 100644 --- a/loader/ground-traits.cpp +++ b/loader/ground-traits.cpp @@ -7,6 +7,7 @@ #include "loader.hpp" #include "src/tile-defs.hpp" #include "src/ground-atlas.hpp" +#include <cr/Optional.h> #include <Corrade/Containers/StringView.h> #include <Corrade/Containers/Pointer.h> #include <Magnum/ImageView.h> @@ -21,17 +22,19 @@ auto ground_traits::atlas_of(const Cell& x) -> const std::shared_ptr<Atlas>& { r auto ground_traits::atlas_of(Cell& x) -> std::shared_ptr<Atlas>& { return x.atlas; } 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) { - if (!st.is_empty()) [[likely]] + if (!st.name_map.empty()) [[likely]] return; + st.name_map.max_load_factor(0.4f); fm_assert(st.cell_array.empty()); fm_assert(st.name_map.empty()); st.cell_array = ground_cell::load_atlases_from_json().vec; - st.name_map.reserve(st.cell_array.size()); + st.name_map.reserve(st.cell_array.size()*2); fm_assert(!st.cell_array.empty()); fm_assert(st.name_map.empty()); @@ -44,8 +47,6 @@ void ground_traits::ensure_atlases_loaded(Storage& st) st.cell_array.push_back(make_invalid_atlas(st)); } - st.name_map.reserve(st.cell_array.size()); - for (auto& x : st.cell_array) { if constexpr(!add_invalid) @@ -56,7 +57,6 @@ void ground_traits::ensure_atlases_loaded(Storage& st) fm_assert(!st.cell_array.empty()); fm_assert(!st.name_map.empty()); - fm_debug_assert(!st.is_empty()); } auto ground_traits::make_invalid_atlas(Storage& s) -> const Cell& @@ -79,4 +79,6 @@ auto ground_traits::make_atlas(StringView name, const Cell& c) -> std::shared_pt return atlas; } +auto ground_traits::make_cell(StringView) -> Optional<Cell> { return {}; } + } // namespace floormat::loader_detail diff --git a/loader/ground-traits.hpp b/loader/ground-traits.hpp index df661e26..bcd89cb1 100644 --- a/loader/ground-traits.hpp +++ b/loader/ground-traits.hpp @@ -18,9 +18,11 @@ template<> struct atlas_loader_traits<ground_atlas> 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/wall-traits.cpp b/loader/wall-traits.cpp index f51974bc..b5a4245c 100644 --- a/loader/wall-traits.cpp +++ b/loader/wall-traits.cpp @@ -7,6 +7,7 @@ #include "src/tile-defs.hpp" #include "src/wall-atlas.hpp" #include <cr/StringView.h> +#include <cr/Optional.h> #include <cr/Pointer.h> #include <mg/ImageData.h> #include <mg/ImageView.h> @@ -15,22 +16,23 @@ namespace floormat::loader_detail { namespace { const auto placeholder_cell = wall_cell{}; } using wall_traits = atlas_loader_traits<wall_atlas>; -StringView atlas_loader_traits<wall_atlas>::loader_name() { return "wall_atlas"_s; } -auto atlas_loader_traits<wall_atlas>::atlas_of(const Cell& x) -> const std::shared_ptr<Atlas>& { return x.atlas; } -auto atlas_loader_traits<wall_atlas>::atlas_of(Cell& x) -> std::shared_ptr<Atlas>& { return x.atlas; } -StringView atlas_loader_traits<wall_atlas>::name_of(const Cell& x) { return x.name; } -StringView atlas_loader_traits<wall_atlas>::name_of(const Atlas& x) { return x.name(); } +StringView wall_traits::loader_name() { return "wall_atlas"_s; } +auto wall_traits::atlas_of(const Cell& x) -> const std::shared_ptr<Atlas>& { return x.atlas; } +auto wall_traits::atlas_of(Cell& x) -> std::shared_ptr<Atlas>& { return x.atlas; } +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) { - if (!st.cell_array.empty()) [[likely]] + if (!st.name_map.empty()) [[likely]] return; - fm_assert(st.name_map.empty()); + st.name_map.max_load_factor(0.4f); constexpr bool add_invalid = true; st.cell_array = wall_cell::load_atlases_from_json().vec; - st.name_map.reserve(st.cell_array.size()); + st.name_map.reserve(st.cell_array.size()*2); fm_assert(!st.cell_array.empty()); fm_assert(st.name_map.empty()); @@ -90,4 +92,6 @@ auto wall_traits::make_atlas(StringView name, const Cell&) -> std::shared_ptr<At return atlas; } +auto wall_traits::make_cell(StringView) -> Optional<Cell> { return {}; } + } // namespace floormat::loader_detail diff --git a/loader/wall-traits.hpp b/loader/wall-traits.hpp index 72492d98..d0497ea4 100644 --- a/loader/wall-traits.hpp +++ b/loader/wall-traits.hpp @@ -18,10 +18,11 @@ template<> struct atlas_loader_traits<wall_atlas> 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/src/wall-atlas.hpp b/src/wall-atlas.hpp index df5c7deb..278f3bbe 100644 --- a/src/wall-atlas.hpp +++ b/src/wall-atlas.hpp @@ -35,8 +35,6 @@ struct Group default_tint : 1 = true, is_defined : 1 = false; - //bool is_empty() const noexcept { return count == 0; } - bool operator==(const Group&) const noexcept; }; |