summaryrefslogtreecommitdiffhomepage
path: root/loader
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-02-10 02:02:13 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-02-10 02:25:37 +0100
commitd83927d06f3dd848c995a26fde582b78c704f80c (patch)
treef0898e9fbf973fe4ad986fc976c3e0a6ca14ee9d /loader
parentbc6349ce09ced9978384cd90df020a3350888c38 (diff)
wip scenery loader
Diffstat (limited to 'loader')
-rw-r--r--loader/atlas-loader-storage.hpp3
-rw-r--r--loader/atlas-loader.inl21
-rw-r--r--loader/ground-traits.cpp12
-rw-r--r--loader/ground-traits.hpp2
-rw-r--r--loader/wall-traits.cpp20
-rw-r--r--loader/wall-traits.hpp3
6 files changed, 45 insertions, 16 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