diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-02-13 14:58:17 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-02-13 21:22:32 +0100 |
commit | 8f7b089e246b5e55d1cacb756da4219bb751236f (patch) | |
tree | b302742a6cdc70c393c6020bc8e3b4d1bc08d348 /loader | |
parent | 9b70fb78e70a509ba5bfa1c1d0a839eddd0902dc (diff) |
scenery loader now works
Diffstat (limited to 'loader')
-rw-r--r-- | loader/anim-traits.cpp | 2 | ||||
-rw-r--r-- | loader/atlas-loader-storage.hpp | 4 | ||||
-rw-r--r-- | loader/atlas-loader.inl | 8 | ||||
-rw-r--r-- | loader/impl.cpp | 5 | ||||
-rw-r--r-- | loader/impl.hpp | 11 | ||||
-rw-r--r-- | loader/loader.hpp | 21 | ||||
-rw-r--r-- | loader/scenery-atlas.cpp | 34 | ||||
-rw-r--r-- | loader/scenery-cell.cpp | 1 | ||||
-rw-r--r-- | loader/scenery-cell.hpp | 17 | ||||
-rw-r--r-- | loader/scenery-traits.cpp | 15 | ||||
-rw-r--r-- | loader/scenery-traits.hpp | 6 | ||||
-rw-r--r-- | loader/scenery.cpp | 61 |
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 |