diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-08 05:10:44 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-08 05:10:44 +0100 |
commit | 7f42651fdd5a7d575ffdde89c369fe28cad2ced5 (patch) | |
tree | 433354042a0d32a21c8168fa155079b7718fe077 | |
parent | 3370445a2e22ee00687ecef2e9dc88f47bb2b4c6 (diff) |
a
-rw-r--r-- | compat/map.hpp | 4 | ||||
-rw-r--r-- | loader/impl.cpp | 1 | ||||
-rw-r--r-- | loader/impl.hpp | 1 | ||||
-rw-r--r-- | loader/wall-atlas.cpp | 58 |
4 files changed, 45 insertions, 19 deletions
diff --git a/compat/map.hpp b/compat/map.hpp index def97d0e..9bcceadb 100644 --- a/compat/map.hpp +++ b/compat/map.hpp @@ -17,9 +17,9 @@ constexpr auto map0(const std::array<T, N>& array, const F& fun, std::index_sequ template<typename T, typename F> [[deprecated("zero-length array!")]] CORRADE_ALWAYS_INLINE -constexpr auto map0(const std::array<T, 0>&, const F& fun, std::index_sequence<>) +constexpr auto map0(const std::array<T, 0>&, const F&, std::index_sequence<>) { - return std::array<std::decay_t<decltype( fun(std::declval<const T&>()) )> , 0>{}; + return std::array<std::decay_t<std::invoke_result_t<std::decay_t<F>, const std::remove_cvref_t<T>&>>, 0>{}; } } // namespace floormat::detail::map diff --git a/loader/impl.cpp b/loader/impl.cpp index 029f96a6..0b8a05e9 100644 --- a/loader/impl.cpp +++ b/loader/impl.cpp @@ -24,6 +24,7 @@ StringView loader_impl::shader(StringView filename) noexcept loader_impl::loader_impl() { + missing_wall_atlases.reserve(32); system_init(); set_application_working_directory(); } diff --git a/loader/impl.hpp b/loader/impl.hpp index 4cb9236b..37a00304 100644 --- a/loader/impl.hpp +++ b/loader/impl.hpp @@ -48,6 +48,7 @@ struct loader_impl final : loader_ struct wall_index { uint32_t val = (uint32_t)-1; }; tsl::robin_map<StringView, wall_info*> wall_atlas_map; std::vector<wall_info> wall_atlas_array; + std::vector<String> missing_wall_atlases; Pointer<wall_info> invalid_wall_atlas; diff --git a/loader/wall-atlas.cpp b/loader/wall-atlas.cpp index a79c68d4..c28f71a1 100644 --- a/loader/wall-atlas.cpp +++ b/loader/wall-atlas.cpp @@ -3,8 +3,6 @@ #include "compat/assert.hpp" #include "compat/exception.hpp" #include "src/wall-atlas.hpp" -#include "serialize/wall-atlas.hpp" -#include "wall-info.hpp" #include "serialize/json-helper.hpp" #include "serialize/corrade-string.hpp" #include "src/tile-defs.hpp" @@ -14,7 +12,6 @@ #include <Corrade/Utility/Path.h> #include <Magnum/Trade/ImageData.h> #include <Magnum/ImageView.h> -#include <vector> namespace floormat { @@ -43,6 +40,7 @@ namespace floormat::loader_detail { std::shared_ptr<wall_atlas> loader_impl::get_wall_atlas(StringView name, StringView path) { + fm_assert(name != "<invalid>"_s); auto filename = Path::join(path, name); auto def = wall_atlas_def::deserialize(""_s.join({filename, ".json"_s})); auto tex = texture(""_s, filename, false); @@ -76,25 +74,50 @@ const wall_info& loader_impl::make_invalid_wall_atlas() std::shared_ptr<class wall_atlas> loader_impl::wall_atlas(StringView name, bool fail_ok) noexcept(false) { fm_soft_assert(check_atlas_name(name)); - char buf[FILENAME_MAX]; - auto path = make_atlas_path(buf, loader.WALL_TILESET_PATH, name); auto it = wall_atlas_map.find(name); - if (it == wall_atlas_map.end()) + + if (it != wall_atlas_map.end()) [[likely]] { - if (!fail_ok) - fm_throw("no such wall atlas '{}'"_cf, name); - else + if (it->second == (wall_info*)-1) [[unlikely]] { - if (name != "<invalid>"_s) - DBG_nospace << "wall_atlas '" << name << "' doesn't exist"; - return make_invalid_wall_atlas().atlas; + if (fail_ok) [[likely]] + goto missing_ok; + else + goto error; } + else if (!it->second->atlas) + return it->second->atlas = get_wall_atlas(name, loader.WALL_TILESET_PATH); + else + return it->second->atlas; + } + else + { + if (fail_ok) [[likely]] + goto missing; + else + goto error; } - fm_assert(it->second != nullptr); - if (!it->second->atlas) [[unlikely]] - it->second->atlas = get_wall_atlas(it->second->name, path); - return it->second->atlas; + + std::unreachable(); + fm_assert(false); + +missing: + { + // todo allocate wall_info instead + missing_wall_atlases.push_back(String { AllocatedInit, name }); + auto string_view = StringView{missing_wall_atlases.back()}; + wall_atlas_map[string_view] = (wall_info*)-1; + } + + if (name != "<invalid>") + DBG_nospace << "wall_atlas '" << name << "' doesn't exist"; + +missing_ok: + return make_invalid_wall_atlas().atlas; + +error: + fm_throw("no such wall atlas '{}'"_cf, name); } void loader_impl::get_wall_atlas_list() @@ -106,8 +129,9 @@ void loader_impl::get_wall_atlas_list() for (auto& x : wall_atlas_array) { + fm_soft_assert(x.name != "<invalid>"_s); fm_soft_assert(check_atlas_name(x.name)); - x.atlas = get_wall_atlas(x.name, WALL_TILESET_PATH); + //x.atlas = get_wall_atlas(x.name, WALL_TILESET_PATH); StringView name = x.name; wall_atlas_map[name] = &x; fm_debug_assert(name.data() == wall_atlas_map[name]->name.data()); |