summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-02-11 00:39:28 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-02-11 08:49:51 +0100
commit5267d7b5b52fb8112dc4001b3b8f7985521af5ba (patch)
tree32952992edee1144841b1cb8d69965ee981fe870
parentb8c538bcdfdcc7f2739934ea96fe98ae61b565dc (diff)
wip atlas loader
-rw-r--r--loader/anim-traits.cpp13
-rw-r--r--loader/anim-traits.hpp28
-rw-r--r--loader/atlas-loader.inl40
-rw-r--r--loader/ground-traits.cpp38
-rw-r--r--loader/ground-traits.hpp4
-rw-r--r--loader/wall-traits.cpp33
-rw-r--r--loader/wall-traits.hpp2
7 files changed, 95 insertions, 63 deletions
diff --git a/loader/anim-traits.cpp b/loader/anim-traits.cpp
index e69de29b..9741f62e 100644
--- a/loader/anim-traits.cpp
+++ b/loader/anim-traits.cpp
@@ -0,0 +1,13 @@
+#include "anim-traits.hpp"
+#include "compat/exception.hpp"
+#include "loader.hpp"
+#include <cr/StringView.h>
+#include <cr/Optional.h>
+#include <mg/ImageData.h>
+#include <mg/ImageView.h>
+
+namespace floormat::loader_detail {
+
+
+
+} // namespace floormat::loader_detail
diff --git a/loader/anim-traits.hpp b/loader/anim-traits.hpp
index e69de29b..3c4a43af 100644
--- a/loader/anim-traits.hpp
+++ b/loader/anim-traits.hpp
@@ -0,0 +1,28 @@
+#pragma once
+#include "atlas-loader-fwd.hpp"
+#include <memory>
+
+namespace floormat { struct anim_cell; class anim_atlas; }
+
+namespace floormat::loader_detail {
+
+template<> struct atlas_loader_traits<anim_atlas>
+{
+ using Atlas = anim_atlas;
+ using Cell = anim_cell; // convertible to atlas and holding the atlas
+ using Self = atlas_loader_traits<Atlas>;
+ using Storage = atlas_storage<Atlas, Self>;
+
+ static StringView loader_name();
+ static const std::shared_ptr<Atlas>& atlas_of(const Cell& x);
+ 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/atlas-loader.inl b/loader/atlas-loader.inl
index af5d9567..f5cd39ea 100644
--- a/loader/atlas-loader.inl
+++ b/loader/atlas-loader.inl
@@ -25,13 +25,37 @@ atlas_loader(TRAITS&& traits) noexcept -> atlas_loader<TRAITS, typename TRAITS::
template<typename ATLAS, typename TRAITS>
auto atlas_loader<ATLAS, TRAITS>::ensure_atlas_list() -> ArrayView<const Cell>
{
- if (!s.cell_array.empty()) [[likely]]
+ if (!s.name_map.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())
+ {
+ String& name{t.name_of(c)};
+ if (name.isSmall())
name = String{AllocatedInit, name};
+ fm_soft_assert(name != loader.INVALID);
+ fm_soft_assert(loader.check_atlas_name(name));
+ }
+
+ s.name_map.max_load_factor(0.4f);
+ s.name_map.reserve(s.cell_array.size()*3/2 + 1);
+ for (auto i = 0uz; const auto& c : s.cell_array)
+ s.name_map[t.name_of(c)] = i++;
+
+ { const Cell& invalid_atlas{get_invalid_atlas()};
+ size_t sz{s.cell_array.size()};
+ s.cell_array.push_back(invalid_atlas);
+ s.name_map[loader.INVALID] = sz;
+ }
+
+ fm_assert(!s.name_map.empty());
fm_assert(!s.cell_array.empty());
+
+ for (const auto& [name, index] : s.name_map)
+ fm_assert(index < s.cell_array.size() || index == -1uz);
+
return { s.cell_array.data(), s.cell_array.size() };
}
@@ -39,7 +63,7 @@ template<typename ATLAS, typename TRAITS>
const std::shared_ptr<ATLAS>& atlas_loader<ATLAS, TRAITS>::get_atlas(StringView name, loader_policy p)
{
ensure_atlas_list();
- const std::shared_ptr<Atlas>& invalid_atlas = t.atlas_of(t.make_invalid_atlas(s));
+ const std::shared_ptr<Atlas>& invalid_atlas = t.atlas_of(get_invalid_atlas());
fm_debug_assert(invalid_atlas);
switch (p)
@@ -152,9 +176,13 @@ auto atlas_loader<ATLAS, TRAITS>::make_atlas(StringView name, const Cell& c) ->
template<typename ATLAS, typename TRAITS>
auto atlas_loader<ATLAS, TRAITS>::get_invalid_atlas() -> const Cell&
{
- const auto& cell = t.make_invalid_atlas(s);
- fm_assert(t.atlas_of(cell));
- return cell;
+ if (s.invalid_atlas) [[likely]]
+ return *s.invalid_atlas;
+ s.invalid_atlas = t.make_invalid_atlas(s);
+ fm_assert(s.invalid_atlas);
+ fm_assert(t.atlas_of(*s.invalid_atlas));
+ fm_assert(t.name_of(*s.invalid_atlas) == loader.INVALID);
+ return *s.invalid_atlas;
}
} // namespace floormat::loader_detail
diff --git a/loader/ground-traits.cpp b/loader/ground-traits.cpp
index 61df7831..e56f0692 100644
--- a/loader/ground-traits.cpp
+++ b/loader/ground-traits.cpp
@@ -22,39 +22,21 @@ 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)
+void ground_traits::ensure_atlases_loaded(Storage& s)
{
- if (!st.name_map.empty()) [[likely]]
- return;
+ fm_assert(s.name_map.empty());
- st.cell_array = ground_cell::load_atlases_from_json().vec;
- 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)
- {
- 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++;
- }
+ s.cell_array = ground_cell::load_atlases_from_json().vec;
+ s.name_map[loader.INVALID] = -1uz;
}
-auto ground_traits::make_invalid_atlas(Storage& s) -> const Cell& // todo! store it in cell_array
+auto ground_traits::make_invalid_atlas(Storage& s) -> Pointer<Cell>
{
- if (!s.invalid_atlas) [[unlikely]]
- {
- auto atlas = std::make_shared<Atlas>(
- ground_def{loader.INVALID, Vector2ub{1,1}, pass_mode::pass},
- loader.make_error_texture(Vector2ui(tile_size_xy)));
- s.invalid_atlas = Pointer<ground_cell>{ InPlaceInit, atlas, atlas->name(), atlas->num_tiles2(), atlas->pass_mode() };
- }
- return *s.invalid_atlas;
+ fm_assert(!s.invalid_atlas);
+ auto atlas = std::make_shared<Atlas>(
+ ground_def{loader.INVALID, Vector2ub{1,1}, pass_mode::pass},
+ loader.make_error_texture(Vector2ui(tile_size_xy)));
+ return Pointer<ground_cell>{ InPlaceInit, atlas, atlas->name(), atlas->num_tiles2(), atlas->pass_mode() };
}
auto ground_traits::make_atlas(StringView name, const Cell& c) -> std::shared_ptr<Atlas>
diff --git a/loader/ground-traits.hpp b/loader/ground-traits.hpp
index bcd89cb1..6eaf3444 100644
--- a/loader/ground-traits.hpp
+++ b/loader/ground-traits.hpp
@@ -19,8 +19,8 @@ template<> struct atlas_loader_traits<ground_atlas>
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 void ensure_atlases_loaded(Storage& s);
+ static Pointer<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);
};
diff --git a/loader/wall-traits.cpp b/loader/wall-traits.cpp
index d31aba4e..70d729c0 100644
--- a/loader/wall-traits.cpp
+++ b/loader/wall-traits.cpp
@@ -22,35 +22,17 @@ 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)
+void wall_traits::ensure_atlases_loaded(Storage& s)
{
- if (!st.name_map.empty()) [[likely]]
- return;
+ fm_assert(s.name_map.empty());
- st.cell_array = wall_cell::load_atlases_from_json().vec;
- 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)
- {
- fm_soft_assert(c.name != loader.INVALID);
- fm_soft_assert(loader.check_atlas_name(c.name));
- fm_soft_assert(!c.atlas);
- fm_assert(!c.name.isSmall());
- st.name_map[c.name] = i++;
- }
+ s.cell_array = wall_cell::load_atlases_from_json().vec;
+ s.name_map[loader.INVALID] = -1uz;
}
-auto wall_traits::make_invalid_atlas(Storage& st) -> const Cell&
+auto wall_traits::make_invalid_atlas(Storage& s) -> Pointer<Cell>
{
- if (st.invalid_atlas) [[likely]]
- return *st.invalid_atlas;
-
+ fm_assert(!s.invalid_atlas);
constexpr auto name = loader_::INVALID;
constexpr auto frame_size = Vector2ui{tile_size_xy, tile_size_z};
@@ -64,8 +46,7 @@ auto wall_traits::make_invalid_atlas(Storage& st) -> const Cell&
{{ {.val = 0}, {}, }},
{1u},
}, name, loader.make_error_texture(frame_size));
- st.invalid_atlas = Pointer<wall_cell>{InPlaceInit, wall_cell{ .atlas = std::move(a), .name = name, } };
- return *st.invalid_atlas;
+ return Pointer<wall_cell>{InPlaceInit, wall_cell{ .atlas = std::move(a), .name = name, } };
}
auto wall_traits::make_atlas(StringView name, const Cell&) -> std::shared_ptr<Atlas>
diff --git a/loader/wall-traits.hpp b/loader/wall-traits.hpp
index d0497ea4..a3134b22 100644
--- a/loader/wall-traits.hpp
+++ b/loader/wall-traits.hpp
@@ -20,7 +20,7 @@ template<> struct atlas_loader_traits<wall_atlas>
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 Pointer<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);
};