From 1b254aa3c1489c7efcde1f151724459350b85fcf Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 4 Mar 2023 03:01:25 +0100 Subject: editor/inspect: add rotation enum field --- editor/inspect-types.cpp | 78 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 68 insertions(+), 10 deletions(-) (limited to 'editor') diff --git a/editor/inspect-types.cpp b/editor/inspect-types.cpp index aa6a2faa..49041649 100644 --- a/editor/inspect-types.cpp +++ b/editor/inspect-types.cpp @@ -31,6 +31,10 @@ struct entity_accessors { [](scenery_ref&, StringView) {}, constantly(field_status::readonly), }, + entity::type::field{"rotation"_s, + [](const scenery_ref& x) { return x.frame.r; }, + [](scenery_ref& x, rotation r) { x.frame.r = r; }, + }, entity::type::field{"frame"_s, [](const scenery_ref& x) { return x.frame.frame; }, [](scenery_ref& x, frame_t value) { x.frame.frame = value; }, @@ -69,28 +73,73 @@ struct entity_accessors { #ifdef TEST_STR entity::type::field{"string"_s, [](const scenery_ref&) { return my_str; }, - [](scenery_ref&, String value) { my_str = std::move(value); } + [](scenery_ref&, String value) { my_str = std::move(value); }, + constantly(constraints::max_length{8}), }, #endif }; } }; +template struct has_anim_atlas : std::false_type {}; +template<> struct has_anim_atlas : std::true_type { + static const anim_atlas& get_atlas(const scenery_ref& x) { + fm_assert(x.atlas); + return *x.atlas; + } +}; + using enum_pair = std::pair; +template struct enum_values; -template constexpr auto enum_values(); -template requires (!std::is_enum_v) constexpr std::array enum_values(){ return {}; } +template +struct enum_pair_array { + std::array array; + std::size_t size; + operator ArrayView() const noexcept { return {array.data(), size}; } +}; -template<> -constexpr auto enum_values() -{ - return std::to_array({ +template enum_pair_array(std::array array, std::size_t) -> enum_pair_array; + +template +requires (!std::is_enum_v) +struct enum_values : std::true_type { + static constexpr std::array get() { return {}; } +}; + +template struct enum_values : std::true_type { + static constexpr auto ret = std::to_array({ { "blocked"_s, (std::size_t)pass_mode::blocked, }, { "see-through"_s, (std::size_t)pass_mode::see_through, }, { "shoot-through"_s, (std::size_t)pass_mode::shoot_through, }, { "pass"_s, (std::size_t)pass_mode::pass }, }); -} + static constexpr const auto& get() { return ret; } +}; + +template +requires has_anim_atlas::value +struct enum_values : std::false_type { + static auto get(const U& x) { + const anim_atlas& atlas = has_anim_atlas::get_atlas(x); + std::array array; + constexpr std::pair values[] = { + { "North"_s, rotation::N }, + { "Northeast"_s, rotation::NE }, + { "East"_s, rotation::E }, + { "Southeast"_s, rotation::SE }, + { "South"_s, rotation::S }, + { "Southwest"_s, rotation::SW }, + { "West"_s, rotation::W }, + { "Northwest"_s, rotation::NW }, + }; + std::size_t i = 0; + for (auto [str, val] : values) + if (atlas.check_rotation(val)) + array[i++] = enum_pair{str, (std::size_t)val}; + return enum_pair_array{array, i}; + } +}; template<> bool inspect_type(scenery_ref& x) @@ -98,8 +147,17 @@ bool inspect_type(scenery_ref& x) bool ret = false; visit_tuple([&](const auto& field) { using type = typename std::decay_t::FieldType; - constexpr auto list = enum_values(); - ret |= inspect_field(&x, field.erased(), list); + using enum_type = enum_values; + if constexpr(enum_type::value) + { + constexpr auto list = enum_type::get(); + ret |= inspect_field(&x, field.erased(), list); + } + else + { + const auto& list = enum_type::get(x); + ret |= inspect_field(&x, field.erased(), list); + } }, entity_metadata::accessors); return ret; } -- cgit v1.2.3