diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2023-11-22 00:52:56 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2023-11-22 00:54:27 +0100 |
commit | c91cc537121ce7d1c4722b5c9ea88f7e7301fa15 (patch) | |
tree | 241cf08f19762520f4f66a52e720fddbd2c1345e | |
parent | 7eb5e07707e62154a8aa5412ddb1da69e2a316e4 (diff) |
aaaa
-rw-r--r-- | serialize/anim.cpp | 108 | ||||
-rw-r--r-- | serialize/scenery.cpp | 33 | ||||
-rw-r--r-- | serialize/tile-atlas.cpp | 9 | ||||
-rw-r--r-- | serialize/wall-atlas.cpp | 106 | ||||
-rw-r--r-- | src/wall-atlas.cpp | 24 | ||||
-rw-r--r-- | test/wall-atlas.cpp | 51 |
6 files changed, 186 insertions, 145 deletions
diff --git a/serialize/anim.cpp b/serialize/anim.cpp index aad40f33..8d8bc2bb 100644 --- a/serialize/anim.cpp +++ b/serialize/anim.cpp @@ -7,8 +7,6 @@ namespace floormat { -using namespace std::string_view_literals; - //NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(anim_frame, ground, offset, size) //NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(anim_group, name, frames, ground, offset) //NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(anim_def, object_name, anim_name, pixel_size, nframes, actionframe, fps, groups, scale) @@ -18,106 +16,106 @@ static void to_json(nlohmann::json& j, const anim_frame& val) constexpr anim_frame def; if (val.ground != def.ground) - j["ground"sv] = val.ground; + j["ground"] = val.ground; if (val.offset != def.offset) - j["offset"sv] = val.offset; + j["offset"] = val.offset; if (val.size != def.size) - j["size"sv] = val.size; + j["size"] = val.size; } static void from_json(const nlohmann::json& j, anim_frame& val) { val = {}; - if (j.contains("ground"sv)) - val.ground = j["ground"sv]; - if (j.contains("offset"sv)) - val.offset = j["offset"sv]; - if (j.contains("size"sv)) - val.size = j["size"sv]; + if (j.contains("ground")) + val.ground = j["ground"]; + if (j.contains("offset")) + val.offset = j["offset"]; + if (j.contains("size")) + val.size = j["size"]; } static void to_json(nlohmann::json& j, const anim_group& val) { const anim_group def{}; - j["name"sv] = val.name; + j["name"] = val.name; if (val.mirror_from) - j["mirror-from"sv] = val.mirror_from; + j["mirror-from"] = val.mirror_from; else - j["frames"sv] = val.frames; + j["frames"] = val.frames; if (val.ground != def.ground) - j["ground"sv] = val.ground; + j["ground"] = val.ground; if (val.offset != def.offset) - j["offset"sv] = val.offset; + j["offset"] = val.offset; if (val.z_offset != def.z_offset) - j["z-offset"sv] = val.z_offset; + j["z-offset"] = val.z_offset; if (val.depth_offset != def.depth_offset) - j["depth-offset"sv] = val.depth_offset; + j["depth-offset"] = val.depth_offset; } static void from_json(const nlohmann::json& j, anim_group& val) { val = {}; - val.name = j["name"sv]; + val.name = j["name"]; fm_soft_assert(!val.name.isEmpty()); - if (j.contains("mirror-from"sv)) + if (j.contains("mirror-from")) { - fm_soft_assert(!j.contains("frames"sv)); - val.mirror_from = j["mirror-from"sv]; + fm_soft_assert(!j.contains("frames")); + val.mirror_from = j["mirror-from"]; } else - val.frames = j["frames"sv]; - if (j.contains("ground"sv)) - val.ground = j["ground"sv]; - if (j.contains("offset"sv)) - val.offset = j["offset"sv]; - if (j.contains("z-offset"sv)) - val.z_offset = j["z-offset"sv]; - if (j.contains("depth-offset"sv)) - val.depth_offset = j["depth-offset"sv]; + val.frames = j["frames"]; + if (j.contains("ground")) + val.ground = j["ground"]; + if (j.contains("offset")) + val.offset = j["offset"]; + if (j.contains("z-offset")) + val.z_offset = j["z-offset"]; + if (j.contains("depth-offset")) + val.depth_offset = j["depth-offset"]; } static void to_json(nlohmann::json& j, const anim_def& val) { const anim_def def{}; - j["object_name"sv] = val.object_name; + j["object_name"] = val.object_name; if (val.anim_name != def.anim_name) - j["anim_name"sv] = val.anim_name; + j["anim_name"] = val.anim_name; if (val.pixel_size != def.pixel_size) - j["pixel_size"sv] = val.pixel_size; + j["pixel_size"] = val.pixel_size; if (val.nframes != def.nframes) - j["nframes"sv] = val.nframes; + j["nframes"] = val.nframes; if (val.action_frame != def.action_frame) - j["action-frame"sv] = val.action_frame; + j["action-frame"] = val.action_frame; if (val.action_frame2 != def.action_frame2) - j["action-frame-2"sv] = val.action_frame2; + j["action-frame-2"] = val.action_frame2; if (val.fps != def.fps) - j["fps"sv] = val.fps; - j["groups"sv] = val.groups; - j["scale"sv] = val.scale; + j["fps"] = val.fps; + j["groups"] = val.groups; + j["scale"] = val.scale; } static void from_json(const nlohmann::json& j, anim_def& val) { val = {}; - val.object_name = j["object_name"sv]; + val.object_name = j["object_name"]; fm_soft_assert(!val.object_name.isEmpty()); - if (j.contains("anim_name"sv)) // todo underscore to hyphen - val.anim_name = j["anim_name"sv]; - if (j.contains("pixel_size"sv)) - val.pixel_size = j["pixel_size"sv]; - if (j.contains("nframes"sv)) - val.nframes = j["nframes"sv]; - if (j.contains("action-frame"sv)) - val.action_frame = j["action-frame"sv]; - if (j.contains("action-frame-2"sv)) - val.action_frame2 = j["action-frame-2"sv]; - if (j.contains("fps"sv)) - val.fps = j["fps"sv]; - val.groups = j["groups"sv]; + if (j.contains("anim_name")) // todo underscore to hyphen + val.anim_name = j["anim_name"]; + if (j.contains("pixel_size")) + val.pixel_size = j["pixel_size"]; + if (j.contains("nframes")) + val.nframes = j["nframes"]; + if (j.contains("action-frame")) + val.action_frame = j["action-frame"]; + if (j.contains("action-frame-2")) + val.action_frame2 = j["action-frame-2"]; + if (j.contains("fps")) + val.fps = j["fps"]; + val.groups = j["groups"]; fm_soft_assert(!val.groups.empty()); - val.scale = j["scale"sv]; + val.scale = j["scale"]; fm_soft_assert(val.scale.type != anim_scale_type::invalid); } diff --git a/serialize/scenery.cpp b/serialize/scenery.cpp index 2994d778..8519fd49 100644 --- a/serialize/scenery.cpp +++ b/serialize/scenery.cpp @@ -13,7 +13,6 @@ namespace { using namespace floormat; -using namespace std::string_view_literals; constexpr struct { scenery_type value = scenery_type::none; @@ -86,24 +85,24 @@ void adl_serializer<scenery_proto>::to_json(json& j, const scenery_proto& f) fm_assert(f.atlas); const scenery_proto default_scenery; if (f.type != default_scenery.type) - j["type"sv] = f.type; - j["atlas-name"sv] = f.atlas->name(); + j["type"] = f.type; + j["atlas-name"] = f.atlas->name(); if (f.frame != default_scenery.frame) - j["frame"sv] = f.frame; + j["frame"] = f.frame; if (f.r != default_scenery.r) - j["rotation"sv] = f.r; + j["rotation"] = f.r; if (f.pass != default_scenery.pass) - j["pass-mode"sv] = f.pass; + j["pass-mode"] = f.pass; if (f.active != default_scenery.active) - j["active"sv] = f.active; + j["active"] = f.active; if (f.interactive != default_scenery.interactive) - j["interactive"sv] = f.interactive; + j["interactive"] = f.interactive; if (f.offset != default_scenery.offset) - j["offset"sv] = Vector2i(f.offset); + j["offset"] = Vector2i(f.offset); if (f.bbox_offset != default_scenery.bbox_offset) - j["bbox-offset"sv] = Vector2i(f.bbox_offset); + j["bbox-offset"] = Vector2i(f.bbox_offset); if (f.bbox_size != default_scenery.bbox_size) - j["bbox-size"sv] = Vector2ui(f.bbox_size); + j["bbox-size"] = Vector2ui(f.bbox_size); } void adl_serializer<scenery_proto>::from_json(const json& j, scenery_proto& f) @@ -115,7 +114,7 @@ void adl_serializer<scenery_proto>::from_json(const json& j, scenery_proto& f) value = j[s]; }; - StringView atlas_name = j["atlas-name"sv]; + StringView atlas_name = j["atlas-name"]; fm_soft_assert(!atlas_name.isEmpty()); f = {}; f.atlas = loader.anim_atlas(atlas_name, loader_::SCENERY_PATH); @@ -170,17 +169,17 @@ void adl_serializer<serialized_scenery>::to_json(json& j, const serialized_scene fm_soft_assert(val.proto.atlas); j = val.proto; const auto name = !val.name.isEmpty() ? StringView{val.name} : val.proto.atlas->name(); - j["name"sv] = name; - j["description"sv] = val.descr; + j["name"] = name; + j["description"] = val.descr; } void adl_serializer<serialized_scenery>::from_json(const json& j, serialized_scenery& val) { val = {}; val.proto = j; - val.name = j["name"sv]; - if (j.contains("description"sv)) - val.descr = j["description"sv]; + val.name = j["name"]; + if (j.contains("description")) + val.descr = j["description"]; } } // namespace nlohmann diff --git a/serialize/tile-atlas.cpp b/serialize/tile-atlas.cpp index 3918d5b0..3d8c7d2f 100644 --- a/serialize/tile-atlas.cpp +++ b/serialize/tile-atlas.cpp @@ -10,12 +10,11 @@ #include <nlohmann/json.hpp> using namespace floormat; -using namespace std::string_view_literals; namespace { struct proxy { - String name; + StringView name; Vector2ub size; Optional<pass_mode> passability; }; @@ -35,7 +34,7 @@ void adl_serializer<std::shared_ptr<tile_atlas>>::to_json(json& j, const std::sh { to_json(j, proxy{x->name(), x->num_tiles2(), NullOpt}); if (auto p = x->pass_mode()) - j["pass-mode"sv] = *p; + j["pass-mode"] = *p; } } @@ -49,8 +48,8 @@ void adl_serializer<std::shared_ptr<tile_atlas>>::from_json(const json& j, std:: proxy x; from_json(j, x); Optional<pass_mode> p; - if (j.contains("pass-mode"sv)) - p = {InPlaceInit, j["pass-mode"sv]}; + if (j.contains("pass-mode")) + p = {InPlaceInit, j["pass-mode"]}; val = loader.tile_atlas(x.name, x.size, p); if (auto p2 = val->pass_mode(); p && p2 != p) { diff --git a/serialize/wall-atlas.cpp b/serialize/wall-atlas.cpp index f9e718bc..e3d8f0a9 100644 --- a/serialize/wall-atlas.cpp +++ b/serialize/wall-atlas.cpp @@ -8,7 +8,6 @@ #include <string_view> #include <Corrade/Containers/PairStl.h> #include <Corrade/Containers/StringStl.h> -#include <Corrade/Containers/StringStlView.h> #include <Magnum/ImageView.h> #include <Magnum/Trade/ImageData.h> #include <nlohmann/json.hpp> @@ -17,8 +16,6 @@ namespace floormat::Wall::detail { -using namespace std::string_view_literals; - uint8_t direction_index_from_name(StringView s) { for (uint8_t i = 0; auto [n, _] : wall_atlas::directions) @@ -38,10 +35,10 @@ StringView direction_index_to_name(size_t i) Array<Frame> read_all_frames(const json& jroot) { - fm_assert(jroot.contains("frames"sv)); + fm_assert(jroot.contains("frames")); Array<Frame> frames; - const auto& jframes = jroot["frames"sv]; + const auto& jframes = jroot["frames"]; fm_assert(jframes.is_array()); const auto sz = jframes.size(); @@ -65,33 +62,41 @@ Group read_group_metadata(const json& jgroup) { int count = 0, index = -1; - bool has_count = jgroup.contains("count"sv) && (count = jgroup["count"sv]) != 0, - has_index = jgroup.contains("offset"sv) && (index = jgroup["offset"sv]) != -1; + bool has_count = jgroup.contains("count") && (count = jgroup["count"]) != 0, + has_index = jgroup.contains("offset") && (index = jgroup["offset"]) != -1; fm_soft_assert(has_count == has_index); fm_soft_assert(!has_index || index >= 0 && index < 1 << 20); fm_soft_assert(count >= 0); + if (has_count) + { + val.index = (uint32_t)index; + val.count = (uint32_t)count; + } // todo check index within range } - if (jgroup.contains("pixel-size"sv)) - val.pixel_size = jgroup["pixel-size"sv]; - if (jgroup.contains("tint-mult"sv)) - val.tint_mult = Vector4(jgroup["tint-mult"sv]); - if (jgroup.contains("tint-add"sv)) - val.tint_add = Vector3(jgroup["tint-add"sv]); - if (jgroup.contains("from-rotation"sv)) - val.from_rotation = (uint8_t)direction_index_from_name(std::string{ jgroup["from-rotation"sv] }); - if (jgroup.contains("mirrored"sv)) - val.mirrored = !!jgroup["mirrored"sv]; - if (jgroup.contains("default-tint"sv)) - val.default_tint = !!jgroup["default-tint"sv]; + if (jgroup.contains("pixel-size")) + val.pixel_size = jgroup["pixel-size"]; + if (jgroup.contains("tint-mult")) + val.tint_mult = Vector4(jgroup["tint-mult"]); + if (jgroup.contains("tint-add")) + val.tint_add = Vector3(jgroup["tint-add"]); + if (jgroup.contains("from-rotation") && !jgroup["from-rotation"].is_null()) + val.from_rotation = (uint8_t)direction_index_from_name(std::string{ jgroup["from-rotation"] }); + if (jgroup.contains("mirrored")) + val.mirrored = !!jgroup["mirrored"]; + if (jgroup.contains("default-tint")) + val.default_tint = !!jgroup["default-tint"]; return val; } Direction read_direction_metadata(const json& jroot, Direction_ dir) { - std::string_view s = direction_index_to_name((size_t)dir); + const auto s_ = direction_index_to_name((size_t)dir); + fm_assert(s_.size() == 1); + std::string_view s = {s_.data(), s_.size()}; + fm_assert(s.size() == 1); if (!jroot.contains(s)) return {}; const auto& jdir = jroot[s]; @@ -100,7 +105,7 @@ Direction read_direction_metadata(const json& jroot, Direction_ dir) for (auto [s_, memfn, tag] : Direction::groups) { - std::string_view s = s_; + std::string_view s = {s_.data(), s_.size()}; if (!jdir.contains(s)) continue; val.*memfn = read_group_metadata(jdir[s]); @@ -130,57 +135,62 @@ Pair<Array<Direction>, std::array<DirArrayIndex, 4>> read_all_directions(const j Info read_info_header(const json& jroot) { - fm_soft_assert(jroot.contains(("name"sv))); + fm_soft_assert(jroot.contains(("name"))); fm_soft_assert(jroot.contains(("depth"))); - Info val = {std::string{jroot["name"sv]}, {}, jroot["depth"sv]}; + Info val = {std::string{jroot["name"]}, {}, jroot["depth"]}; fm_soft_assert(val.depth > 0); - if (jroot.contains("description"sv)) - val.description = std::string{jroot["description"sv]}; + if (jroot.contains("description")) + val.description = std::string{jroot["description"]}; return val; } void write_all_frames(json& jroot, ArrayView<const Frame> array) { - auto jframes = json{json::value_t::array}; + auto jframes = json{}; for (const Frame& frame : array) { json jframe = frame; jframes.push_back(std::move(jframe)); } - jroot["frames"sv] = std::move(jframes); + jroot["frames"] = std::move(jframes); } void write_group_metadata(json& jgroup, const Group& val) { - fm_assert(jgroup.is_object()); + constexpr Group group_defaults; + + fm_assert(jgroup.is_null()); if (val.index != (uint32_t)-1) - jgroup["offset"sv] = val.index; + jgroup["offset"] = val.index; + else + jgroup["offset"] = -1; + + jgroup["count"] = val.count; + jgroup["pixel-size"] = val.pixel_size; + jgroup["tint-mult"] = Vector4(val.tint_mult); + jgroup["tint-add"] = Vector3(val.tint_add); + if (val.from_rotation != group_defaults.from_rotation) + jgroup["from-rotation"] = direction_index_to_name(val.from_rotation); else - jgroup["offset"sv] = -1; - - jgroup["count"sv] = val.count; - jgroup["pixel-size"sv] = val.pixel_size; - jgroup["tint-mult"sv] = Vector4(val.tint_mult); - jgroup["tint-add"sv] = Vector3(val.tint_add); - jgroup["from-rotation"sv] = val.from_rotation; - jgroup["mirrored"sv] = val.mirrored; - jgroup["default-tint"sv] = val.default_tint; + jgroup["from-rotation"] = nullptr; + jgroup["mirrored"] = val.mirrored; + jgroup["default-tint"] = val.default_tint; } void write_direction_metadata(json& jdir, const Direction& dir) { for (auto [s_, memfn, tag] : Direction::groups) { - std::string_view s = s_; + std::string_view s = {s_.data(), s_.size()}; const auto& group = dir.*memfn; write_group_metadata(jdir[s], group); } - if (jdir.contains("top"sv)) + if (jdir.contains("top")) { - auto& top = jdir["top"sv]; - if (top.contains("pixel-size"sv)) - top["pixel-size"sv] = Vector2i{top["pixel-size"sv]}.flipped(); + auto& top = jdir["top"]; + if (top.contains("pixel-size")) + top["pixel-size"] = Vector2i{top["pixel-size"]}.flipped(); } } @@ -190,7 +200,7 @@ void write_all_directions(json& jroot, const wall_atlas& a) { if (const auto* dir = a.direction((size_t)i)) { - auto jdir = json{json::value_t::object}; + auto jdir = json{}; write_direction_metadata(jdir, *dir); jroot[name] = std::move(jdir); } @@ -198,10 +208,10 @@ void write_all_directions(json& jroot, const wall_atlas& a) } void write_info_header(json& jroot, const Info& info) -{ jroot["name"sv] = info.name; +{ jroot["name"] = info.name; if (info.description) - jroot["description"sv] = info.description; - jroot["depth"sv] = info.depth; + jroot["description"] = info.description; + jroot["depth"] = info.depth; } } // namespace floormat::Wall::detail @@ -237,7 +247,7 @@ void adl_serializer<std::shared_ptr<wall_atlas>>::from_json(const json& j, std:: auto [dirs, map] = read_all_directions(j); Array<Frame> frames; auto img = loader.texture(loader.WALL_TILESET_PATH, info.name); - if (j.contains("frames"sv)) + if (j.contains("frames")) frames = read_all_frames(j); x = std::make_shared<wall_atlas>(std::move(info), img, std::move(frames), std::move(dirs), map); diff --git a/src/wall-atlas.cpp b/src/wall-atlas.cpp index 31b2ad2d..d63d0ec0 100644 --- a/src/wall-atlas.cpp +++ b/src/wall-atlas.cpp @@ -180,9 +180,31 @@ bool Direction::is_empty() const noexcept } bool Frame::operator==(const Frame&) const noexcept = default; -bool Group::operator==(const Group&) const noexcept = default; bool Direction::operator==(const Direction&) const noexcept = default; bool Info::operator==(const floormat::Wall::Info&) const noexcept = default; bool DirArrayIndex::operator==(const floormat::Wall::DirArrayIndex&) const noexcept = default; +#if 1 +bool Group::operator==(const Group&) const noexcept = default; +#else +bool Group::operator==(const Group& other) const noexcept +{ + bool ret = index == other.index && count == other.count && + pixel_size == other.pixel_size && + from_rotation == other.from_rotation && + mirrored == other.mirrored && default_tint == other.default_tint; + + if (!ret) + return ret; + + constexpr auto eps = 1e-5f; + if (auto diff = Math::abs(Vector4(tint_mult) - Vector4(other.tint_mult)).sum(); diff > eps) + return false; + if (auto diff = Math::abs(Vector3(tint_add) - Vector3(other.tint_add)).sum(); diff > eps) + return false; + + return true; +} +#endif + } // namespace floormat::Wall diff --git a/test/wall-atlas.cpp b/test/wall-atlas.cpp index 1578e68f..a2ac3043 100644 --- a/test/wall-atlas.cpp +++ b/test/wall-atlas.cpp @@ -3,13 +3,12 @@ #include "serialize/wall-atlas.hpp" #include "serialize/json-helper.hpp" #include "loader/loader.hpp" -#include <Corrade/Containers/StringStlView.h> +#include <Corrade/Containers/StringStl.h> #include <Corrade/Utility/Path.h> namespace floormat::Wall::detail { using nlohmann::json; -using namespace std::string_view_literals; namespace { @@ -44,13 +43,13 @@ void test_read_empty_directions(StringView filename) test_read_header(filename); fm_assert(!jroot.empty()); - fm_assert( jroot.contains("n"sv) ); - fm_assert(!jroot.contains("e"sv) ); - fm_assert(!jroot.contains("s"sv) ); - fm_assert( jroot.contains("w"sv) ); + fm_assert( jroot.contains("n") ); + fm_assert(!jroot.contains("e") ); + fm_assert(!jroot.contains("s") ); + fm_assert( jroot.contains("w") ); - fm_assert(jroot["n"sv].is_object() && jroot["n"sv].empty()); - fm_assert(jroot["w"sv].is_object() && jroot["w"sv].empty()); + fm_assert(jroot["n"].is_object() && jroot["n"].empty()); + fm_assert(jroot["w"].is_object() && jroot["w"].empty()); } void test_read_groups(StringView filename) @@ -63,13 +62,13 @@ void test_read_groups(StringView filename) fm_assert(info.depth == 42); fm_assert(info.description == ""_s); - fm_assert(jroot["depth"sv] == 42); - fm_assert( jroot.contains("n"sv) ); - fm_assert(!jroot.contains("e"sv) ); - fm_assert(!jroot.contains("s"sv) ); - fm_assert( jroot.contains("w"sv) ); - fm_assert(jroot["n"sv].is_object() && jroot["n"sv].empty()); - fm_assert(jroot["w"sv].is_object() && !jroot["w"sv].empty()); + fm_assert(jroot["depth"] == 42); + fm_assert( jroot.contains("n") ); + fm_assert(!jroot.contains("e") ); + fm_assert(!jroot.contains("s") ); + fm_assert( jroot.contains("w") ); + fm_assert(jroot["n"].is_object() && jroot["n"].empty()); + fm_assert(jroot["w"].is_object() && !jroot["w"].empty()); fm_assert(read_direction_metadata(jroot, Direction_::N).is_empty()); fm_assert(read_direction_metadata(jroot, Direction_::E).is_empty()); fm_assert(read_direction_metadata(jroot, Direction_::S).is_empty()); @@ -89,7 +88,7 @@ void test_read_groups(StringView filename) struct wall_atlas_ { - bool operator==(const wall_atlas_&) const noexcept = default; + bool operator==(const wall_atlas_&) const noexcept; Info header; std::array<Direction, 4> directions = {}; @@ -115,7 +114,7 @@ struct wall_atlas_ { auto i = (size_t)curdir; atlas.directions[i] = read_direction_metadata(jroot, curdir); - got_any_directions = true; + got_any_directions = got_any_directions || atlas.directions[i]; } if (do_checks) fm_assert(got_any_directions); @@ -137,14 +136,14 @@ struct wall_atlas_ void write_to_temp_file(const wall_atlas_& atlas) { - auto jroot = json{json::value_t::object}; + auto jroot = json{}; write_info_header(jroot, atlas.header); write_all_frames(jroot, atlas.frames); for (const auto [name_, dir] : wall_atlas::directions) { - std::string_view name = name_; + std::string_view name = {name_.data(), name_.size()}; auto i = (size_t)dir; if (atlas.directions[i]) write_direction_metadata(jroot[name], atlas.directions[i]); @@ -154,6 +153,20 @@ void write_to_temp_file(const wall_atlas_& atlas) json_helper::to_json_(jroot, filename); } +bool wall_atlas_::operator==(const wall_atlas_& other) const noexcept +{ + if (header != other.header) + return false; + if (directions != other.directions) + return false; + if (frames.size() != other.frames.size()) + return false; + for (auto i = 0uz; i < frames.size(); i++) + if (frames[i] != other.frames[i]) + return false; + return true; +} + } // namespace } // namespace floormat::Wall::detail |