diff options
-rw-r--r-- | loader/atlas-loader-storage.hpp | 3 | ||||
-rw-r--r-- | loader/atlas-loader.inl | 60 | ||||
-rw-r--r-- | loader/ground-cell.cpp | 3 | ||||
-rw-r--r-- | loader/ground-traits.cpp | 36 | ||||
-rw-r--r-- | loader/wall-cell.cpp | 2 | ||||
-rw-r--r-- | loader/wall-traits.cpp | 30 | ||||
-rw-r--r-- | src/ground-atlas.cpp | 1 | ||||
-rw-r--r-- | src/wall-atlas.cpp | 1 |
8 files changed, 64 insertions, 72 deletions
diff --git a/loader/atlas-loader-storage.hpp b/loader/atlas-loader-storage.hpp index a1f2e20d..c8bd3261 100644 --- a/loader/atlas-loader-storage.hpp +++ b/loader/atlas-loader-storage.hpp @@ -12,9 +12,8 @@ struct atlas_storage using Traits = TRAITS; using Cell = typename TRAITS::Cell; - tsl::robin_map<StringView, Cell*, hash_string_view> name_map; + tsl::robin_map<StringView, size_t, 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; diff --git a/loader/atlas-loader.inl b/loader/atlas-loader.inl index 0a50821f..af5d9567 100644 --- a/loader/atlas-loader.inl +++ b/loader/atlas-loader.inl @@ -28,6 +28,9 @@ auto atlas_loader<ATLAS, TRAITS>::ensure_atlas_list() -> ArrayView<const Cell> if (!s.cell_array.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()) + name = String{AllocatedInit, name}; fm_assert(!s.cell_array.empty()); return { s.cell_array.data(), s.cell_array.size() }; } @@ -36,9 +39,8 @@ template<typename ATLAS, typename TRAITS> const std::shared_ptr<ATLAS>& atlas_loader<ATLAS, TRAITS>::get_atlas(StringView name, loader_policy p) { ensure_atlas_list(); - auto* const invalid_atlas = const_cast<Cell*>(&t.make_invalid_atlas(s)); + const std::shared_ptr<Atlas>& invalid_atlas = t.atlas_of(t.make_invalid_atlas(s)); fm_debug_assert(invalid_atlas); - fm_debug_assert(t.atlas_of(*invalid_atlas)); switch (p) { @@ -59,14 +61,14 @@ const std::shared_ptr<ATLAS>& atlas_loader<ATLAS, TRAITS>::get_atlas(StringView goto error; case ignore: case warn: - return t.atlas_of(*invalid_atlas); + return invalid_atlas; } fm_soft_assert(loader.check_atlas_name(name)); if (auto it = s.name_map.find(name); it != s.name_map.end()) [[likely]] { - if (it->second == invalid_atlas) + if (it->second == -1uz) [[unlikely]] { switch (p) { @@ -75,28 +77,38 @@ const std::shared_ptr<ATLAS>& atlas_loader<ATLAS, TRAITS>::get_atlas(StringView goto error; case warn: case ignore: - return t.atlas_of(*invalid_atlas); + return invalid_atlas; } } - else if (const auto& atlas = t.atlas_of(*it->second)) - return t.atlas_of(*it->second); else - return t.atlas_of(*it->second) = t.make_atlas(name, *it->second); + { + Cell& c = s.cell_array[it->second]; + fm_assert(t.name_of(c)); + std::shared_ptr<ATLAS>& atlas = t.atlas_of(c); + if (!atlas) [[unlikely]] + { + atlas = make_atlas(name, c); + fm_debug_assert(atlas); + return atlas; + } + else + { + fm_assert(t.name_of(c) == name); + return atlas; + } + } } - else if (Optional<Cell> c_{t.make_cell(name)}) + else if (Optional<Cell> c_{t.make_cell(name)}) // todo! { - 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; + size_t index = s.cell_array.size(); + s.cell_array.emplace_back(Utility::move(*c_)); + Cell& c = s.cell_array.back(); + fm_debug_assert(!t.name_of(c)); fm_debug_assert(!t.atlas_of(c)); + t.atlas_of(c) = make_atlas(name, c); + t.name_of(c) = String{AllocatedInit, name}; + fm_debug_assert(t.name_of(c)); fm_debug_assert(t.atlas_of(c)); + s.name_map[t.name_of(c)] = index; + return t.atlas_of(c); } else { @@ -108,7 +120,7 @@ const std::shared_ptr<ATLAS>& atlas_loader<ATLAS, TRAITS>::get_atlas(StringView case warn: goto missing_warn; case ignore: - return t.atlas_of(*invalid_atlas); + return invalid_atlas; } } @@ -120,12 +132,12 @@ error: missing_warn: s.missing_atlas_names.push_back(String { AllocatedInit, name }); - s.name_map[ s.missing_atlas_names.back() ] = invalid_atlas; + s.name_map[ s.missing_atlas_names.back() ] = -1uz; if (name != loader.INVALID) DBG_nospace << t.loader_name() << " '" << name << "' doesn't exist"; - return t.atlas_of(*invalid_atlas); + return invalid_atlas; } template<typename ATLAS, typename TRAITS> diff --git a/loader/ground-cell.cpp b/loader/ground-cell.cpp index 8cc1e31d..f8373d76 100644 --- a/loader/ground-cell.cpp +++ b/loader/ground-cell.cpp @@ -11,8 +11,7 @@ vector_wrapper<const ground_cell> ground_cell::load_atlases_from_json() { char buf[fm_FILENAME_MAX]; auto s = loader.make_atlas_path(buf, loader.GROUND_TILESET_PATH, "ground.json"_s); - auto cells = json_helper::from_json<std::vector<ground_cell>>(s); - return {cells}; + return {json_helper::from_json<std::vector<ground_cell>>(s)}; } } // namespace floormat diff --git a/loader/ground-traits.cpp b/loader/ground-traits.cpp index f1ed3090..14f30623 100644 --- a/loader/ground-traits.cpp +++ b/loader/ground-traits.cpp @@ -28,38 +28,26 @@ void ground_traits::ensure_atlases_loaded(Storage& st) { 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()*2); - fm_assert(!st.cell_array.empty()); - fm_assert(st.name_map.empty()); + 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; - constexpr bool add_invalid = true; + for (auto& c : st.cell_array) + if (c.name.isSmall()) + c.name = String{AllocatedInit, c.name}; - if constexpr(add_invalid) + for (auto i = 0uz; const auto& c : st.cell_array) { - for (auto& x : st.cell_array) - fm_soft_assert(x.name != loader.INVALID); - st.cell_array.push_back(make_invalid_atlas(st)); + 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++; } - - for (auto& x : st.cell_array) - { - if constexpr(!add_invalid) - fm_soft_assert(x.name != loader.INVALID); - fm_soft_assert(loader.check_atlas_name(x.name)); - st.name_map[x.name] = &x; - } - - fm_assert(!st.cell_array.empty()); - fm_assert(!st.name_map.empty()); } -auto ground_traits::make_invalid_atlas(Storage& s) -> const Cell& +auto ground_traits::make_invalid_atlas(Storage& s) -> const Cell& // todo! store it in cell_array { if (!s.invalid_atlas) [[unlikely]] { diff --git a/loader/wall-cell.cpp b/loader/wall-cell.cpp index 92034659..4e12f0be 100644 --- a/loader/wall-cell.cpp +++ b/loader/wall-cell.cpp @@ -24,7 +24,7 @@ vector_wrapper<const wall_cell> wall_cell::load_atlases_from_json() { char buf[fm_FILENAME_MAX]; auto s = loader.make_atlas_path(buf, loader.WALL_TILESET_PATH, "walls.json"_s); - return { json_helper::from_json<std::vector<wall_cell>>(s) }; + return {json_helper::from_json<std::vector<wall_cell>>(s)}; } } // namespace floormat diff --git a/loader/wall-traits.cpp b/loader/wall-traits.cpp index b5a4245c..ac9f1a7a 100644 --- a/loader/wall-traits.cpp +++ b/loader/wall-traits.cpp @@ -27,32 +27,24 @@ void wall_traits::ensure_atlases_loaded(Storage& st) { if (!st.name_map.empty()) [[likely]] return; - 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()*2); - fm_assert(!st.cell_array.empty()); - fm_assert(st.name_map.empty()); - - if constexpr(add_invalid) - { - for (auto& x : st.cell_array) - fm_soft_assert(x.name != loader.INVALID); - st.cell_array.push_back(make_invalid_atlas(st)); - } + 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) { - if constexpr(!add_invalid) - fm_soft_assert(c.name != "<invalid>"_s); + fm_soft_assert(c.name != loader.INVALID); fm_soft_assert(loader.check_atlas_name(c.name)); - StringView name = c.name; - st.name_map[name] = &c; + fm_soft_assert(!c.atlas); + fm_assert(!c.name.isSmall()); + st.name_map[c.name] = i++; } - - fm_assert(!st.cell_array.empty()); } auto wall_traits::make_invalid_atlas(Storage& st) -> const Cell& diff --git a/src/ground-atlas.cpp b/src/ground-atlas.cpp index ea513d44..d39ecadc 100644 --- a/src/ground-atlas.cpp +++ b/src/ground-atlas.cpp @@ -18,6 +18,7 @@ ground_atlas::ground_atlas(ground_def info, const ImageView2D& image) : _texcoords{make_texcoords_array(Vector2ui(image.size()), _def.size)}, _pixel_size{image.size()} { + //Debug{} << "make ground_atlas" << _def.name; constexpr auto variant_max = std::numeric_limits<variant_t>::max(); fm_soft_assert(num_tiles() <= variant_max); fm_soft_assert(_def.size.x() > 0 && _def.size.y() > 0); diff --git a/src/wall-atlas.cpp b/src/wall-atlas.cpp index b7ff68d9..9ea81fe5 100644 --- a/src/wall-atlas.cpp +++ b/src/wall-atlas.cpp @@ -108,6 +108,7 @@ wall_atlas::wall_atlas(wall_atlas_def def, String path, const ImageView2D& img) _image_size{get_image_size(img)}, _direction_map{def.direction_map} { + //Debug{} << "make wall_atlas" << _info.name; { const auto frame_count = _frame_array.size(); fm_soft_assert(frame_count > 0); |