diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-11 16:40:29 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-11 16:40:29 +0100 |
commit | ba90ba2ca91c448d80722985811fc6bddc6e9bf2 (patch) | |
tree | 2a81ee054bad7f76457be6e91359039fcc9a8780 | |
parent | d74df1b763979d281f76f3f30543aee8d8a638b7 (diff) |
w
-rw-r--r-- | editor/imgui.cpp | 2 | ||||
-rw-r--r-- | loader/atlas.cpp | 32 | ||||
-rw-r--r-- | loader/ground-atlas.cpp | 112 | ||||
-rw-r--r-- | loader/ground-info.hpp | 19 | ||||
-rw-r--r-- | loader/impl.cpp | 2 | ||||
-rw-r--r-- | loader/impl.hpp | 24 | ||||
-rw-r--r-- | loader/json.cpp | 11 | ||||
-rw-r--r-- | loader/loader.hpp | 12 | ||||
-rw-r--r-- | loader/texture.cpp | 8 | ||||
-rw-r--r-- | loader/wall-atlas.cpp | 10 | ||||
-rw-r--r-- | serialize/ground-atlas.cpp | 50 | ||||
-rw-r--r-- | serialize/ground-atlas.hpp | 15 | ||||
-rw-r--r-- | serialize/wall-atlas.cpp | 1 |
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> |