summaryrefslogtreecommitdiffhomepage
path: root/loader
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-02-13 14:58:17 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-02-13 21:22:32 +0100
commit8f7b089e246b5e55d1cacb756da4219bb751236f (patch)
treeb302742a6cdc70c393c6020bc8e3b4d1bc08d348 /loader
parent9b70fb78e70a509ba5bfa1c1d0a839eddd0902dc (diff)
scenery loader now works
Diffstat (limited to 'loader')
-rw-r--r--loader/anim-traits.cpp2
-rw-r--r--loader/atlas-loader-storage.hpp4
-rw-r--r--loader/atlas-loader.inl8
-rw-r--r--loader/impl.cpp5
-rw-r--r--loader/impl.hpp11
-rw-r--r--loader/loader.hpp21
-rw-r--r--loader/scenery-atlas.cpp34
-rw-r--r--loader/scenery-cell.cpp1
-rw-r--r--loader/scenery-cell.hpp17
-rw-r--r--loader/scenery-traits.cpp15
-rw-r--r--loader/scenery-traits.hpp6
-rw-r--r--loader/scenery.cpp61
12 files changed, 88 insertions, 97 deletions
diff --git a/loader/anim-traits.cpp b/loader/anim-traits.cpp
index fca5be4d..c4139381 100644
--- a/loader/anim-traits.cpp
+++ b/loader/anim-traits.cpp
@@ -102,7 +102,7 @@ auto anim_traits::make_atlas(StringView name, const Cell&) -> std::shared_ptr<At
auto anim_traits::make_cell(StringView name) -> Optional<Cell>
{
- return { InPlace, Cell{ .atlas = {}, .name = name, } };
+ return { InPlace, Cell { .atlas = {}, .name = name } };
}
} // namespace floormat::loader_detail
diff --git a/loader/atlas-loader-storage.hpp b/loader/atlas-loader-storage.hpp
index f18b7756..fc540a6e 100644
--- a/loader/atlas-loader-storage.hpp
+++ b/loader/atlas-loader-storage.hpp
@@ -11,13 +11,15 @@ namespace floormat::loader_detail {
template<typename ATLAS, typename TRAITS>
struct atlas_storage
{
+ struct string_equals { bool operator()(StringView a, StringView b) const { return a == b; } };
+
static_assert(std::is_same_v<typename TRAITS::Atlas, ATLAS>);
using Traits = TRAITS;
using Atlas = typename Traits::Atlas;
using Cell = typename Traits::Cell;
- tsl::robin_map<StringView, size_t, hash_string_view> name_map;
+ tsl::robin_map<String, size_t, hash_string_view, string_equals> name_map;
std::vector<Cell> cell_array;
std::vector<String> missing_atlas_names;
Optional<Cell> invalid_atlas;
diff --git a/loader/atlas-loader.inl b/loader/atlas-loader.inl
index c280ac33..d307a021 100644
--- a/loader/atlas-loader.inl
+++ b/loader/atlas-loader.inl
@@ -34,8 +34,6 @@ auto atlas_loader<ATLAS, TRAITS>::atlas_list() -> ArrayView<const Cell>
for (Cell& c : s.cell_array)
{
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));
}
@@ -136,8 +134,6 @@ auto atlas_loader<ATLAS, TRAITS>::get_atlas(StringView name, const loader_policy
fm_assert(!t.atlas_of(*c_));
fm_assert(t.name_of(*c_) == name);
const size_t index{s.cell_array.size()};
- if (t.name_of(*c_).isSmall())
- t.name_of(*c_) = String{ AllocatedInit, t.name_of(*c_) };
s.cell_array.emplace_back(Utility::move(*c_));
Cell& c{s.cell_array.back()};
t.atlas_of(c) = make_atlas(name, c);
@@ -166,7 +162,7 @@ error:
fm_throw("no such atlas '{}'"_cf, name);
missing_warn:
- s.missing_atlas_names.push_back(String { AllocatedInit, name });
+ s.missing_atlas_names.push_back(name);
s.name_map[ s.missing_atlas_names.back() ] = -1uz;
if (name != loader.INVALID)
@@ -214,8 +210,6 @@ template<typename ATLAS, typename TRAITS>
void atlas_loader<ATLAS, TRAITS>::register_cell(Cell&& c)
{
String& name{t.name_of(c)};
- if (name.isSmall())
- name = String{AllocatedInit, name};
fm_assert(!s.name_map.contains(name));
fm_soft_assert(loader.check_atlas_name(name));
const size_t index{s.cell_array.size()};
diff --git a/loader/impl.cpp b/loader/impl.cpp
index 704d6de2..969688ea 100644
--- a/loader/impl.cpp
+++ b/loader/impl.cpp
@@ -6,6 +6,7 @@
#include "wall-cell.hpp"
#include "anim-traits.hpp"
#include "anim-cell.hpp"
+#include "scenery-traits.hpp"
#include "scenery-cell.hpp"
// todo scenery_traits
#include "vobj-cell.hpp"
@@ -54,9 +55,7 @@ void loader_impl::destroy()
_ground_loader = {InPlace};
_wall_loader = {InPlace};
_anim_loader = {InPlace};
- sceneries_map.clear();
- sceneries_array.clear();
-
+ _scenery_loader = {InPlace};
vobj_atlas_map.clear();
vobjs.clear();
}
diff --git a/loader/impl.hpp b/loader/impl.hpp
index b4c8b316..007392fe 100644
--- a/loader/impl.hpp
+++ b/loader/impl.hpp
@@ -66,11 +66,12 @@ struct loader_impl final : loader_
std::shared_ptr<class anim_atlas> get_anim_atlas(StringView path) noexcept(false) override;
// >-----> scenery >----->
- std::vector<scenery_cell> sceneries_array;
- tsl::robin_map<StringView, const scenery_cell*> sceneries_map;
- ArrayView<const scenery_cell> sceneries() override;
- const scenery_proto& scenery(StringView name) noexcept(false) override;
- void get_scenery_list();
+ [[nodiscard]] static atlas_loader<struct scenery_proto>* make_scenery_atlas_loader();
+ safe_ptr<atlas_loader<struct scenery_proto>> _scenery_loader{ make_scenery_atlas_loader() };
+ ArrayView<const scenery_cell> scenery_list() override;
+ const struct scenery_proto& scenery(StringView name, loader_policy policy) override;
+ const scenery_cell& invalid_scenery_atlas() override;
+ struct scenery_proto get_scenery(StringView filename, const scenery_cell& c) noexcept(false) override;
// >-----> vobjs >----->
tsl::robin_map<StringView, const struct vobj_cell*> vobj_atlas_map;
diff --git a/loader/loader.hpp b/loader/loader.hpp
index eca525ab..3f945614 100644
--- a/loader/loader.hpp
+++ b/loader/loader.hpp
@@ -24,22 +24,26 @@ struct ground_cell;
struct wall_cell;
class wall_atlas;
struct scenery_proto;
+struct json_wrapper;
struct loader_
{
+ virtual void destroy() = 0;
+ static loader_& default_loader() noexcept;
virtual StringView shader(StringView filename) noexcept = 0;
virtual Trade::ImageData2D make_error_texture(Vector2ui size) = 0;
virtual Trade::ImageData2D texture(StringView prefix, StringView filename) noexcept(false) = 0;
+
virtual const std::shared_ptr<class ground_atlas>& ground_atlas(StringView filename, loader_policy policy = loader_policy::DEFAULT) noexcept(false) = 0;
- virtual ArrayView<const anim_cell> anim_atlas_list() = 0;
- virtual std::shared_ptr<class anim_atlas> anim_atlas(StringView name, StringView dir, loader_policy policy = loader_policy::DEFAULT) noexcept(false) = 0;
virtual const std::shared_ptr<class wall_atlas>& wall_atlas(StringView name, loader_policy policy = loader_policy::DEFAULT) noexcept(false) = 0;
+ virtual std::shared_ptr<class anim_atlas> anim_atlas(StringView name, StringView dir, loader_policy policy = loader_policy::DEFAULT) noexcept(false) = 0;
+ virtual const struct scenery_proto& scenery(StringView name, loader_policy policy = loader_policy::DEFAULT) = 0;
+
+ virtual ArrayView<const ground_cell> ground_atlas_list() noexcept(false) = 0;
virtual ArrayView<const wall_cell> wall_atlas_list() = 0;
- virtual void destroy() = 0;
- static loader_& default_loader() noexcept;
- virtual ArrayView<const ground_cell> ground_atlas_list() noexcept(false) = 0; // todo maybe try returning
- virtual ArrayView<const scenery_cell> sceneries() = 0;
- virtual const scenery_proto& scenery(StringView name) noexcept(false) = 0;
+ virtual ArrayView<const anim_cell> anim_atlas_list() = 0;
+ virtual ArrayView<const scenery_cell> scenery_list() = 0;
+
virtual StringView startup_directory() noexcept = 0;
static StringView strip_prefix(StringView name);
virtual const vobj_cell& vobj(StringView name) = 0;
@@ -50,6 +54,7 @@ struct loader_
virtual const wall_cell& invalid_wall_atlas() = 0;
virtual const ground_cell& invalid_ground_atlas() = 0;
virtual const anim_cell& invalid_anim_atlas() = 0;
+ virtual const scenery_cell& invalid_scenery_atlas() = 0;
/** \deprecated{internal use only}*/ [[nodiscard]]
virtual std::shared_ptr<class ground_atlas> get_ground_atlas(StringView name, Vector2ub size, pass_mode pass) noexcept(false) = 0;
@@ -57,6 +62,8 @@ struct loader_
virtual std::shared_ptr<class wall_atlas> get_wall_atlas(StringView name) noexcept(false) = 0;
/** \deprecated{internal use only}*/ [[nodiscard]]
virtual std::shared_ptr<class anim_atlas> get_anim_atlas(StringView path) noexcept(false) = 0;
+ /** \deprecated{internal use only}*/ [[nodiscard]]
+ virtual struct scenery_proto get_scenery(StringView filename, const scenery_cell& c) noexcept(false) = 0;
virtual ~loader_() noexcept;
fm_DECLARE_DELETED_COPY_ASSIGNMENT(loader_);
diff --git a/loader/scenery-atlas.cpp b/loader/scenery-atlas.cpp
index 5471e69c..a11049ae 100644
--- a/loader/scenery-atlas.cpp
+++ b/loader/scenery-atlas.cpp
@@ -1,11 +1,12 @@
#include "impl.hpp"
-#include "impl.hpp"
#include "atlas-loader.inl"
#include "scenery-traits.hpp"
#include "scenery-cell.hpp"
#include "src/anim.hpp"
#include "serialize/json-helper.hpp"
#include "serialize/anim.hpp"
+#include "serialize/scenery.hpp"
+#include "serialize/json-wrapper.hpp"
namespace floormat {
@@ -15,3 +16,34 @@ anim_def loader_::deserialize_anim_def(StringView filename) noexcept(false)
}
} // namespace floormat
+
+namespace floormat::loader_detail {
+
+template class atlas_loader<struct scenery_proto>;
+
+atlas_loader<struct scenery_proto>* loader_impl::make_scenery_atlas_loader()
+{
+ return new atlas_loader<struct scenery_proto>;
+}
+
+ArrayView<const scenery_cell> loader_impl::scenery_list()
+{
+ return _scenery_loader->atlas_list();
+}
+
+const struct scenery_proto& loader_impl::scenery(StringView name, loader_policy policy)
+{
+ return *_scenery_loader->get_atlas(name, policy);
+}
+
+const scenery_cell& loader_impl::invalid_scenery_atlas()
+{
+ return _scenery_loader->get_invalid_atlas();
+}
+
+struct scenery_proto loader_impl::get_scenery(StringView filename, const scenery_cell& c) noexcept(false)
+{
+ return *_scenery_loader->make_atlas(filename, c);
+}
+
+} // namespace floormat::loader_detail
diff --git a/loader/scenery-cell.cpp b/loader/scenery-cell.cpp
index 9a4a28d4..96b256cb 100644
--- a/loader/scenery-cell.cpp
+++ b/loader/scenery-cell.cpp
@@ -4,6 +4,7 @@
#include "loader/loader.hpp"
#include "serialize/json-helper.hpp"
#include "serialize/scenery.hpp"
+#include "serialize/json-wrapper.hpp"
namespace floormat {
diff --git a/loader/scenery-cell.hpp b/loader/scenery-cell.hpp
index 28f35368..2b74cfef 100644
--- a/loader/scenery-cell.hpp
+++ b/loader/scenery-cell.hpp
@@ -1,19 +1,34 @@
#pragma once
#include "compat/vector-wrapper-fwd.hpp"
+#include "compat/safe-ptr.hpp"
#include "src/scenery.hpp"
#include <memory>
#include <cr/String.h>
+#include <cr/Optional.h>
namespace floormat {
+struct json_wrapper;
struct scenery_proto;
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-dtor"
+#endif
+
struct scenery_cell final
{
String name;
- scenery_proto proto;
+ safe_ptr<json_wrapper> data{make_json_wrapper()};
+ Optional<scenery_proto> proto;
+ ~scenery_cell() noexcept;
static vector_wrapper<const scenery_cell> load_atlases_from_json();
+ [[nodiscard]] static json_wrapper* make_json_wrapper();
};
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
} // namespace floormat
diff --git a/loader/scenery-traits.cpp b/loader/scenery-traits.cpp
index 84cc42d9..d8add93b 100644
--- a/loader/scenery-traits.cpp
+++ b/loader/scenery-traits.cpp
@@ -11,6 +11,7 @@
#include "serialize/json-helper.hpp"
#include "serialize/anim.hpp"
#include "serialize/scenery.hpp"
+#include "serialize/json-wrapper.hpp"
#include <cr/Optional.h>
#include <Corrade/Containers/StringView.h>
@@ -18,8 +19,8 @@ namespace floormat::loader_detail {
using scenery_traits = atlas_loader_traits<scenery_proto>;
StringView scenery_traits::loader_name() { return "scenery_proto"_s; }
-auto scenery_traits::atlas_of(const Cell& x) -> const scenery_proto& { return x.proto; }
-auto scenery_traits::atlas_of(Cell& x) -> scenery_proto& { return x.proto; }
+auto scenery_traits::atlas_of(const Cell& x) -> const Optional<Atlas>& { return x.proto; }
+auto scenery_traits::atlas_of(Cell& x) -> Optional<Atlas>& { return x.proto; }
StringView scenery_traits::name_of(const Cell& x) { return x.name; }
String& scenery_traits::name_of(Cell& x) { return x.name; }
@@ -27,6 +28,7 @@ void scenery_traits::atlas_list(Storage& s)
{
fm_debug_assert(s.name_map.empty());
s.cell_array = scenery_cell::load_atlases_from_json().vec;
+ s.name_map[loader.INVALID] = -1uz;
}
auto scenery_traits::make_invalid_atlas(Storage& s) -> Cell
@@ -39,17 +41,16 @@ auto scenery_traits::make_invalid_atlas(Storage& s) -> Cell
return { .name = loader.INVALID, .proto = proto, };
}
-auto scenery_traits::make_atlas(StringView name, const Cell& c) -> scenery_proto
+auto scenery_traits::make_atlas(StringView, const Cell& c) -> Optional<scenery_proto>
{
- auto p = c.proto;
- p.atlas = loader.anim_atlas(name, loader.SCENERY_PATH);
+ scenery_proto p = c.data->j;
fm_debug_assert(p.atlas);
return p;
}
-auto scenery_traits::make_cell(StringView name) -> Optional<Cell>
+auto scenery_traits::make_cell(StringView) -> Optional<Cell>
{
- return { InPlace, Cell { .name = name, .proto = {}, } };
+ return {};
}
} // namespace floormat::loader_detail
diff --git a/loader/scenery-traits.hpp b/loader/scenery-traits.hpp
index 13d52708..37aaa199 100644
--- a/loader/scenery-traits.hpp
+++ b/loader/scenery-traits.hpp
@@ -14,13 +14,13 @@ template<> struct atlas_loader_traits<scenery_proto>
using Storage = atlas_storage<Atlas, Self>;
static StringView loader_name();
- static const scenery_proto& atlas_of(const Cell& x);
- static scenery_proto& atlas_of(Cell& x);
+ static const Optional<Atlas>& atlas_of(const Cell& x);
+ static Optional<Atlas>& atlas_of(Cell& x);
static StringView name_of(const Cell& x);
static String& name_of(Cell& x);
static void atlas_list(Storage& st);
static Cell make_invalid_atlas(Storage& st);
- static scenery_proto make_atlas(StringView name, const Cell& c);
+ static Optional<scenery_proto> make_atlas(StringView name, const Cell& c);
static Optional<Cell> make_cell(StringView name);
};
diff --git a/loader/scenery.cpp b/loader/scenery.cpp
deleted file mode 100644
index 6fbaba45..00000000
--- a/loader/scenery.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "impl.hpp"
-#include "compat/assert.hpp"
-#include "compat/exception.hpp"
-#include "src/ground-atlas.hpp"
-#include "serialize/scenery.hpp"
-#include "scenery-cell.hpp"
-#include "serialize/json-helper.hpp"
-#include "loader/anim-cell.hpp"
-#include <Corrade/Containers/ArrayViewStl.h>
-#include <Corrade/Utility/Path.h>
-
-namespace floormat::loader_detail {
-
-void loader_impl::get_scenery_list()
-{
- sceneries_array.clear();
- sceneries_array = json_helper::from_json<std::vector<scenery_cell>>(Path::join(SCENERY_PATH, "scenery.json"));
-
- if constexpr(true) // todo!
- {
- auto proto = scenery_proto{};
- proto.atlas = invalid_anim_atlas().atlas;
- proto.bbox_size = Vector2ub{20};
- proto.subtype = generic_scenery_proto{false, true};
- sceneries_array.push_back({ .name = INVALID, .proto = proto });
- }
-
- sceneries_map.clear();
- sceneries_map.reserve(sceneries_array.size() * 2);
-
- for (scenery_cell& s : sceneries_array)
- {
- if (sceneries_map.contains(s.name))
- fm_abort("duplicate scenery name '%s'", s.name.data());
- sceneries_map[s.name] = &s;
- }
-
- fm_assert(!sceneries_map.empty());
-}
-
-ArrayView<const scenery_cell> loader_impl::sceneries()
-{
- if (sceneries_array.empty()) [[likely]]
- get_scenery_list();
- fm_assert(!sceneries_array.empty());
- return sceneries_array;
-}
-
-const scenery_proto& loader_impl::scenery(StringView name) noexcept(false)
-{
- fm_soft_assert(check_atlas_name(name));
- if (sceneries_array.empty())
- get_scenery_list();
- fm_assert(!sceneries_array.empty());
- auto it = sceneries_map.find(name);
- if (it == sceneries_map.end())
- fm_throw("no such scenery: '{}'"_cf, name);
- return it->second->proto;
-}
-
-} // namespace floormat::loader_detail