summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-01-08 05:10:44 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-01-08 05:10:44 +0100
commit7f42651fdd5a7d575ffdde89c369fe28cad2ced5 (patch)
tree433354042a0d32a21c8168fa155079b7718fe077
parent3370445a2e22ee00687ecef2e9dc88f47bb2b4c6 (diff)
a
-rw-r--r--compat/map.hpp4
-rw-r--r--loader/impl.cpp1
-rw-r--r--loader/impl.hpp1
-rw-r--r--loader/wall-atlas.cpp58
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());