summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-01-11 16:40:29 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-01-11 16:40:29 +0100
commitba90ba2ca91c448d80722985811fc6bddc6e9bf2 (patch)
tree2a81ee054bad7f76457be6e91359039fcc9a8780
parentd74df1b763979d281f76f3f30543aee8d8a638b7 (diff)
w
-rw-r--r--editor/imgui.cpp2
-rw-r--r--loader/atlas.cpp32
-rw-r--r--loader/ground-atlas.cpp112
-rw-r--r--loader/ground-info.hpp19
-rw-r--r--loader/impl.cpp2
-rw-r--r--loader/impl.hpp24
-rw-r--r--loader/json.cpp11
-rw-r--r--loader/loader.hpp12
-rw-r--r--loader/texture.cpp8
-rw-r--r--loader/wall-atlas.cpp10
-rw-r--r--serialize/ground-atlas.cpp50
-rw-r--r--serialize/ground-atlas.hpp15
-rw-r--r--serialize/wall-atlas.cpp1
13 files changed, 188 insertions, 110 deletions
diff --git a/editor/imgui.cpp b/editor/imgui.cpp
index e79e5aeb..440c9928 100644
--- a/editor/imgui.cpp
+++ b/editor/imgui.cpp
@@ -70,7 +70,7 @@ float app::draw_main_menu()
ImGui::SeparatorText("Mode");
if (ImGui::MenuItem("Select", "1", m_none))
do_key(key_mode_none);
- if (ImGui::MenuItem("Floor", "2", m_floor))
+ if (ImGui::MenuItem("Floor", "2", m_floor)) // todo rename to 'ground'
do_key(key_mode_floor);
if (ImGui::MenuItem("Walls", "3", m_walls))
do_key(key_mode_walls);
diff --git a/loader/atlas.cpp b/loader/atlas.cpp
index eb368952..6ad91c56 100644
--- a/loader/atlas.cpp
+++ b/loader/atlas.cpp
@@ -2,7 +2,6 @@
#include "compat/assert.hpp"
#include "compat/exception.hpp"
#include "src/emplacer.hpp"
-#include "src/ground-atlas.hpp"
#include "src/anim-atlas.hpp"
#include <cstdio>
#include <algorithm>
@@ -13,6 +12,8 @@
#include <Corrade/Utility/Path.h>
#include <Magnum/Trade/ImageData.h>
+// todo rename file to 'scenery.cpp'
+
namespace floormat {
StringView loader_::make_atlas_path(char(&buf)[FILENAME_MAX], StringView dir, StringView name)
@@ -45,33 +46,6 @@ bool loader_::check_atlas_name(StringView str) noexcept
namespace floormat::loader_detail {
-std::shared_ptr<ground_atlas> loader_impl::ground_atlas(StringView name, Vector2ub size, pass_mode pass) noexcept(false)
-{
- if (auto it = ground_atlas_map.find(name); it != ground_atlas_map.end())
- {
- fm_assert(it->second->pass_mode() == pass);
- return it->second;
- }
-
- fm_soft_assert(check_atlas_name(name));
-
- char buf[FILENAME_MAX];
- auto path = make_atlas_path(buf, GROUND_TILESET_PATH, name);
-
- auto atlas = std::make_shared<class ground_atlas>(path, name, texture(""_s, path, false), size, pass);
- ground_atlas_map[atlas->name()] = atlas;
- return atlas;
-}
-
-std::shared_ptr<class ground_atlas> loader_impl::ground_atlas(StringView filename) noexcept(false)
-{
- fm_assert(!ground_atlas_map.empty());
- auto it = ground_atlas_map.find(filename);
- if (it == ground_atlas_map.end())
- fm_throw("no such tile atlas '{}'"_cf, filename);
- return it->second;
-}
-
ArrayView<const String> loader_impl::anim_atlas_list()
{
if (anim_atlases.empty())
@@ -107,7 +81,7 @@ std::shared_ptr<anim_atlas> loader_impl::anim_atlas(StringView name, StringView
}
}
- auto tex = texture(""_s, path, false);
+ auto tex = texture(""_s, path);
fm_soft_assert(!anim_info.object_name.isEmpty());
fm_soft_assert(anim_info.pixel_size.product() > 0);
diff --git a/loader/ground-atlas.cpp b/loader/ground-atlas.cpp
new file mode 100644
index 00000000..d93313ea
--- /dev/null
+++ b/loader/ground-atlas.cpp
@@ -0,0 +1,112 @@
+#include "impl.hpp"
+#include "ground-info.hpp"
+#include "src/ground-atlas.hpp"
+#include "compat/exception.hpp"
+#include "serialize/json-helper.hpp"
+#include "serialize/corrade-string.hpp"
+#include <Corrade/Containers/ArrayViewStl.h>
+#include <Corrade/Utility/Path.h>
+#include <Magnum/Trade/ImageData.h>
+#include <Magnum/ImageView.h>
+
+namespace floormat {
+
+using nlohmann::json;
+using loader_detail::loader_impl;
+
+[[maybe_unused]] static void from_json(const json& j, ground_info& val)
+{
+}
+
+[[maybe_unused]] static void to_json(json& j, const ground_info& val)
+{
+}
+
+} // namespace floormat
+
+namespace floormat::loader_detail {
+
+std::shared_ptr<ground_atlas> loader_impl::get_ground_atlas(StringView name, StringView dir, Vector2ub size, pass_mode pass)
+{
+ fm_assert(name != "<invalid>"_s);
+
+ char buf[FILENAME_MAX];
+ auto filename = make_atlas_path(buf, dir, name);
+ auto tex = texture(""_s, filename);
+
+ auto atlas = std::make_shared<class ground_atlas>(filename, name, tex, size, pass);
+ return atlas;
+}
+
+// todo copypasta from wall-atlas.cpp
+std::shared_ptr<class ground_atlas> loader_impl::ground_atlas(StringView name, bool fail_ok) noexcept(false)
+{
+ fm_soft_assert(check_atlas_name(name));
+ auto it = ground_atlas_map.find(name);
+
+ if (it != ground_atlas_map.end()) [[likely]]
+ {
+ if (it->second == (ground_info*)-1) [[unlikely]]
+ {
+ if (fail_ok) [[likely]]
+ goto missing_ok;
+ else
+ goto error;
+ }
+ else if (!it->second->atlas)
+ return it->second->atlas = get_ground_atlas(name, loader.GROUND_TILESET_PATH, it->second->size, it->second->pass);
+ else
+ return it->second->atlas;
+ }
+ else
+ {
+ if (fail_ok) [[likely]]
+ goto missing;
+ else
+ goto error;
+ }
+
+missing:
+ {
+ missing_ground_atlases.push_back(String { AllocatedInit, name });
+ auto string_view = StringView{missing_ground_atlases.back()};
+ ground_atlas_map[string_view] = (ground_info*)-1;
+ }
+
+ if (name != "<invalid>")
+ DBG_nospace << "ground_atlas '" << name << "' doesn't exist";
+
+missing_ok:
+ return make_invalid_ground_atlas().atlas;
+
+error:
+ fm_throw("no such ground atlas '{}'"_cf, name);
+}
+
+ArrayView<const ground_info> loader_impl::ground_atlas_list() noexcept(false)
+{
+ if (ground_atlas_map.empty()) [[unlikely]]
+ get_ground_atlas_list();
+ fm_assert(!ground_atlas_map.empty());
+ return ground_atlas_array;
+}
+
+void loader_impl::get_ground_atlas_list()
+{
+ fm_assert(ground_atlas_map.empty());
+
+ ground_atlas_array = json_helper::from_json<std::vector<ground_info>>(
+ Path::join(loader_::GROUND_TILESET_PATH, "ground.json"_s));
+ ground_atlas_array.shrink_to_fit();
+ ground_atlas_map.clear();
+ ground_atlas_map.reserve(ground_atlas_array.size()*2);
+
+ for (auto& x : ground_atlas_array)
+ {
+
+ }
+
+ fm_assert(!ground_atlas_map.empty());
+}
+
+} // namespace floormat::loader_detail
diff --git a/loader/ground-info.hpp b/loader/ground-info.hpp
new file mode 100644
index 00000000..3b96428e
--- /dev/null
+++ b/loader/ground-info.hpp
@@ -0,0 +1,19 @@
+#pragma once
+#include "src/pass-mode.hpp"
+#include <memory>
+#include <Corrade/Containers/String.h>
+#include <Magnum/Math/Vector2.h>
+
+namespace floormat {
+
+class ground_atlas;
+
+struct ground_info
+{
+ String name; // todo add descr?
+ std::shared_ptr<ground_atlas> atlas;
+ Vector2ub size;
+ pass_mode pass;
+};
+
+} // namespace floormat
diff --git a/loader/impl.cpp b/loader/impl.cpp
index 0b8a05e9..1ea7b7b6 100644
--- a/loader/impl.cpp
+++ b/loader/impl.cpp
@@ -2,6 +2,7 @@
#include "compat/assert.hpp"
#include "loader/scenery.hpp"
#include "loader/vobj-info.hpp"
+#include "loader/ground-info.hpp"
#include "loader/wall-info.hpp"
#include <Corrade/Containers/Pair.h>
#include <Magnum/Trade/ImageData.h>
@@ -24,6 +25,7 @@ StringView loader_impl::shader(StringView filename) noexcept
loader_impl::loader_impl()
{
+ missing_ground_atlases.reserve(32);
missing_wall_atlases.reserve(32);
system_init();
set_application_working_directory();
diff --git a/loader/impl.hpp b/loader/impl.hpp
index ad82e46d..0b718527 100644
--- a/loader/impl.hpp
+++ b/loader/impl.hpp
@@ -13,6 +13,7 @@
namespace floormat {
struct anim_def;
struct wall_info;
+struct ground_info;
}
namespace floormat::loader_detail {
@@ -45,31 +46,30 @@ struct loader_impl final : loader_
Trade::ImageData2D texture(StringView prefix, StringView filename) noexcept(false) override;
// >-----> walls >----->
- 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;
-
std::shared_ptr<class wall_atlas> wall_atlas(StringView name, bool fail_ok = true) override;
ArrayView<const wall_info> wall_atlas_list() override;
void get_wall_atlas_list();
- const wall_info& make_invalid_wall_atlas() noexcept override;
- std::shared_ptr<class wall_atlas> get_wall_atlas(StringView name, StringView path);
+ const wall_info& make_invalid_wall_atlas();
+ std::shared_ptr<class wall_atlas> get_wall_atlas(StringView name, StringView dir);
// >-----> tile >----->
- tsl::robin_map<StringView, std::shared_ptr<class ground_atlas>> ground_atlas_map;
- std::vector<std::shared_ptr<class ground_atlas>> ground_atlas_array;
-
- ArrayView<const std::shared_ptr<class ground_atlas>> ground_atlases(StringView filename) noexcept(false) override;
- std::shared_ptr<class ground_atlas> ground_atlas(StringView filename, Vector2ub size, pass_mode pass) noexcept(false) override;
+ tsl::robin_map<StringView, ground_info*> ground_atlas_map;
+ std::vector<ground_info> ground_atlas_array;
+ std::vector<String> missing_ground_atlases;
+ Pointer<ground_info> invalid_ground_atlas;
std::shared_ptr<class ground_atlas> ground_atlas(StringView filename, bool fail_ok) noexcept(false) override;
+ ArrayView<const ground_info> ground_atlas_list() noexcept(false) override;
+ void get_ground_atlas_list();
+ const ground_info& make_invalid_ground_atlas();
+ std::shared_ptr<class ground_atlas> get_ground_atlas(StringView name, StringView path, Vector2ub size, pass_mode pass) noexcept(false) override;
// >-----> anim >----->
tsl::robin_map<StringView, std::shared_ptr<class anim_atlas>> anim_atlas_map;
std::vector<String> anim_atlases;
-
ArrayView<const String> anim_atlas_list() override;
std::shared_ptr<class anim_atlas> anim_atlas(StringView name, StringView dir) noexcept(false) override;
static anim_def deserialize_anim(StringView filename);
@@ -78,7 +78,6 @@ struct loader_impl final : loader_
// >-----> scenery >----->
std::vector<serialized_scenery> sceneries_array;
tsl::robin_map<StringView, const serialized_scenery*> sceneries_map;
-
ArrayView<const serialized_scenery> sceneries() override;
const scenery_proto& scenery(StringView name) noexcept(false) override;
void get_scenery_list();
@@ -86,7 +85,6 @@ struct loader_impl final : loader_
// >-----> vobjs >----->
tsl::robin_map<StringView, const struct vobj_info*> vobj_atlas_map;
std::vector<struct vobj_info> vobjs;
-
std::shared_ptr<class anim_atlas> make_vobj_anim_atlas(StringView name, StringView image_filename);
const struct vobj_info& vobj(StringView name) override;
ArrayView<const struct vobj_info> vobj_list() override;
diff --git a/loader/json.cpp b/loader/json.cpp
index ed15edbc..31777aa2 100644
--- a/loader/json.cpp
+++ b/loader/json.cpp
@@ -4,7 +4,6 @@
#include "src/ground-atlas.hpp"
#include "serialize/json-helper.hpp"
#include "serialize/anim.hpp"
-#include "serialize/ground-atlas.hpp"
#include "serialize/scenery.hpp"
#include "loader/scenery.hpp"
#include <Corrade/Containers/ArrayViewStl.h>
@@ -53,14 +52,4 @@ const scenery_proto& loader_impl::scenery(StringView name) noexcept(false)
return it->second->proto;
}
-ArrayView<const std::shared_ptr<class ground_atlas>> loader_impl::ground_atlases(StringView filename) noexcept(false)
-{
- if (!ground_atlas_array.empty()) [[likely]]
- return ground_atlas_array;
- ground_atlas_array = json_helper::from_json<std::vector<std::shared_ptr<class ground_atlas>>>(
- Path::join(loader_::GROUND_TILESET_PATH, filename));
- fm_assert(!ground_atlas_array.empty());
- return ground_atlas_array;
-}
-
} // namespace floormat::loader_detail
diff --git a/loader/loader.hpp b/loader/loader.hpp
index fc58e61a..499a1f30 100644
--- a/loader/loader.hpp
+++ b/loader/loader.hpp
@@ -13,27 +13,27 @@ using ImageData2D = ImageData<2>;
namespace floormat {
-class ground_atlas;
class anim_atlas;
-class wall_atlas;
struct scenery_proto;
struct vobj_info;
+class ground_atlas;
+struct ground_info;
struct wall_info;
+class wall_atlas;
struct loader_
{
virtual StringView shader(StringView filename) noexcept = 0;
virtual Trade::ImageData2D texture(StringView prefix, StringView filename) noexcept(false) = 0;
- virtual std::shared_ptr<class ground_atlas> ground_atlas(StringView filename, Vector2ub size, pass_mode pass) noexcept(false) = 0;
+ virtual std::shared_ptr<class ground_atlas> get_ground_atlas(StringView name, StringView path, Vector2ub size, pass_mode pass) noexcept(false) = 0;
virtual std::shared_ptr<class ground_atlas> ground_atlas(StringView filename, bool fail_ok = false) noexcept(false) = 0;
virtual ArrayView<const String> anim_atlas_list() = 0;
virtual std::shared_ptr<class anim_atlas> anim_atlas(StringView name, StringView dir = ANIM_PATH) noexcept(false) = 0;
- virtual const wall_info& make_invalid_wall_atlas() noexcept = 0;
- virtual std::shared_ptr<class wall_atlas> wall_atlas(StringView name, bool fail_ok = true) noexcept(false) = 0;
+ virtual std::shared_ptr<class wall_atlas> wall_atlas(StringView name, bool fail_ok = false) noexcept(false) = 0;
virtual ArrayView<const wall_info> wall_atlas_list() = 0;
static void destroy();
static loader_& default_loader() noexcept;
- virtual ArrayView<const std::shared_ptr<class ground_atlas>> ground_atlases(StringView filename) noexcept(false) = 0;
+ virtual ArrayView<const ground_info> ground_atlas_list() noexcept(false) = 0;
virtual ArrayView<const serialized_scenery> sceneries() = 0;
virtual const scenery_proto& scenery(StringView name) noexcept(false) = 0;
virtual StringView startup_directory() noexcept = 0;
diff --git a/loader/texture.cpp b/loader/texture.cpp
index 60372d00..59e8f25a 100644
--- a/loader/texture.cpp
+++ b/loader/texture.cpp
@@ -12,7 +12,7 @@
namespace floormat::loader_detail {
fm_noinline
-Trade::ImageData2D loader_impl::texture(StringView prefix, StringView filename_, bool fail_ok) noexcept(false)
+Trade::ImageData2D loader_impl::texture(StringView prefix, StringView filename_) noexcept(false)
{
ensure_plugins();
@@ -45,13 +45,11 @@ Trade::ImageData2D loader_impl::texture(StringView prefix, StringView filename_,
return ret;
}
}
+
const auto path = Path::currentDirectory();
buf[len] = '\0';
char errbuf[128];
- if (!fail_ok)
- fm_throw("can't open image '{}' (cwd '{}'): {}"_cf, buf, path ? StringView{*path} : "(null)"_s, get_error_string(errbuf));
- else
- return make_error_texture({1,1});
+ fm_throw("can't open image '{}' (cwd '{}'): {}"_cf, buf, path ? StringView{*path} : "(null)"_s, get_error_string(errbuf));
}
} // namespace floormat::loader_detail
diff --git a/loader/wall-atlas.cpp b/loader/wall-atlas.cpp
index 7d423b26..69666e8c 100644
--- a/loader/wall-atlas.cpp
+++ b/loader/wall-atlas.cpp
@@ -40,21 +40,21 @@ using loader_detail::loader_impl;
namespace floormat::loader_detail {
-std::shared_ptr<wall_atlas> loader_impl::get_wall_atlas(StringView name, StringView path)
+std::shared_ptr<wall_atlas> loader_impl::get_wall_atlas(StringView name, StringView dir)
{
fm_assert(name != "<invalid>"_s);
char buf[FILENAME_MAX];
- auto filename = make_atlas_path(buf, path, name);
+ auto filename = make_atlas_path(buf, dir, name);
auto def = wall_atlas_def::deserialize(""_s.join({filename, ".json"_s}));
auto tex = texture(""_s, filename);
fm_soft_assert(name == def.header.name);
fm_soft_assert(!def.frames.empty());
- auto atlas = std::make_shared<class wall_atlas>(std::move(def), path, tex);
+ auto atlas = std::make_shared<class wall_atlas>(std::move(def), dir, tex);
return atlas;
}
-const wall_info& loader_impl::make_invalid_wall_atlas() noexcept
+const wall_info& loader_impl::make_invalid_wall_atlas()
{
if (invalid_wall_atlas) [[likely]]
return *invalid_wall_atlas;
@@ -121,6 +121,8 @@ error:
void loader_impl::get_wall_atlas_list()
{
+ fm_assert(wall_atlas_map.empty());
+
wall_atlas_array = json_helper::from_json<std::vector<wall_info>>(Path::join(WALL_TILESET_PATH, "walls.json"_s));
wall_atlas_array.shrink_to_fit();
wall_atlas_map.clear();
diff --git a/serialize/ground-atlas.cpp b/serialize/ground-atlas.cpp
index 76c8686e..8703881d 100644
--- a/serialize/ground-atlas.cpp
+++ b/serialize/ground-atlas.cpp
@@ -1,58 +1,38 @@
+#include "ground-atlas.hpp"
#include "src/ground-atlas.hpp"
-#include "serialize/ground-atlas.hpp"
#include "serialize/corrade-string.hpp"
#include "serialize/magnum-vector.hpp"
#include "loader/loader.hpp"
#include "serialize/pass-mode.hpp"
#include "compat/exception.hpp"
+#include <tuple>
#include <Corrade/Containers/Optional.h>
#include <Corrade/Containers/String.h>
#include <nlohmann/json.hpp>
-using namespace floormat;
-
-namespace {
+namespace floormat {
-struct proxy {
- StringView name;
- Vector2ub size;
- pass_mode passability;
-};
+} // namespace floormat
-NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(proxy, name, size)
-
-} // namespace
+using namespace floormat;
namespace nlohmann {
-void adl_serializer<std::shared_ptr<ground_atlas>>::to_json(json& j, const std::shared_ptr<const ground_atlas>& x)
+#if 0
+void adl_serializer<ground_info>::to_json(json& j, const ground_info& x)
{
using nlohmann::to_json;
- if (!x)
- j = nullptr;
- else
- to_json(j, proxy{x->name(), x->num_tiles2(), x->pass_mode()});
+ j = std::tuple<StringView, Vector2ub, pass_mode>{x.name, x.size, x.pass};
}
+#endif
-void adl_serializer<std::shared_ptr<ground_atlas>>::from_json(const json& j, std::shared_ptr<ground_atlas>& val)
+void adl_serializer<ground_info>::from_json(const json& j, ground_info& val)
{
- if (j.is_null())
- val = nullptr;
- else
- {
- using nlohmann::from_json;
- proxy x;
- from_json(j, x);
- pass_mode p = ground_atlas::default_pass_mode;
- if (j.contains("pass-mode"))
- p = j["pass-mode"];
- val = loader.ground_atlas(x.name, x.size, p);
- if (auto p2 = val->pass_mode(); p2 != p)
- {
- const auto name = val->name();
- fm_throw("atlas {} wrong pass mode {} should be {}"_cf, name, uint8_t(p2), uint8_t(p));
- }
- }
+ using nlohmann::from_json;
+ val.name = j["name"];
+ val.size = j["size"];
+ if (j.contains("pass-mode"))
+ val.pass = j["pass-mode"];
}
} // namespace nlohmann
diff --git a/serialize/ground-atlas.hpp b/serialize/ground-atlas.hpp
index 344e8714..7ca57ede 100644
--- a/serialize/ground-atlas.hpp
+++ b/serialize/ground-atlas.hpp
@@ -1,14 +1,19 @@
#pragma once
-#include "src/ground-atlas.hpp"
-#include <memory>
+#include "loader/ground-info.hpp"
#include <nlohmann/json_fwd.hpp>
+namespace floormat {
+
+struct ground_info;
+
+} // namespace floormat
+
namespace nlohmann {
template<>
-struct adl_serializer<std::shared_ptr<floormat::ground_atlas>> final {
- static void to_json(json& j, const std::shared_ptr<const floormat::ground_atlas>& x);
- static void from_json(const json& j, std::shared_ptr<floormat::ground_atlas>& x);
+struct adl_serializer<floormat::ground_info> final {
+ static void to_json(json& j, const floormat::ground_info& x) = delete;
+ static void from_json(const json& j, floormat::ground_info& x);
};
} // namespace nlohmann
diff --git a/serialize/wall-atlas.cpp b/serialize/wall-atlas.cpp
index dc0c42cc..85de29ec 100644
--- a/serialize/wall-atlas.cpp
+++ b/serialize/wall-atlas.cpp
@@ -9,7 +9,6 @@
#include <string_view>
#include <Corrade/Containers/ArrayViewStl.h>
#include <Corrade/Containers/StringStl.h>
-#include <Corrade/Containers/TripleStl.h>
#include <Magnum/ImageView.h>
#include <Magnum/Trade/ImageData.h>
#include <nlohmann/json.hpp>