diff options
| author | Stanislaw Halik <sthalik@misaki.pl> | 2024-04-13 12:26:26 +0200 |
|---|---|---|
| committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-04-13 12:26:26 +0200 |
| commit | cb13eb86db3593e723ce06c48a5cb2c94505d6ae (patch) | |
| tree | 9b56825b1debc908dc999feace69645eb56eb2f8 /editor | |
| parent | 2c042d30d96827941e5052d4eca0cc03965cacc8 (diff) | |
use inheritance for scenery, not std::variant
It's still WIP because creating scenery has to branch on all subtypes.
This needs to be taken care of generically in `world::make_object()`.
Diffstat (limited to 'editor')
| -rw-r--r-- | editor/inspect-types.cpp | 87 | ||||
| -rw-r--r-- | editor/scenery-editor.cpp | 20 |
2 files changed, 79 insertions, 28 deletions
diff --git a/editor/inspect-types.cpp b/editor/inspect-types.cpp index be8851ce..520f0f3c 100644 --- a/editor/inspect-types.cpp +++ b/editor/inspect-types.cpp @@ -91,39 +91,56 @@ struct entity_accessors<object, inspect_intent_t> { } }; -template<> -struct entity_accessors<scenery, inspect_intent_t> { +template<> struct entity_accessors<generic_scenery, inspect_intent_t> +{ static constexpr auto accessors() { - using E = Entity<scenery>; + using E = Entity<generic_scenery>; auto tuple0 = entity_accessors<object, inspect_intent_t>::accessors(); auto tuple = std::tuple{ + E::type<bool>::field{"active"_s, + [](const generic_scenery& x) { return x.active; }, + [](generic_scenery& x, bool b) { x.active = b; }, + constantly(st::readonly), + }, E::type<bool>::field{"interactive"_s, - [](const scenery& x) { - return std::visit(overloaded { - [&](const door_scenery& s) { return s.interactive; }, - [&](const generic_scenery& s) { return s.interactive; }, - }, x.subtype); - }, - [](scenery& x, bool b) { - return std::visit(overloaded { - [&](door_scenery& s) { s.interactive = b; }, - [&](generic_scenery& s) { s.interactive = b; }, - }, x.subtype); - }, - [](const scenery& x) { - return std::visit(overloaded { - [&](const door_scenery&) { return st::enabled; }, - [&](const generic_scenery&) { return st::enabled; }, - }, x.subtype); - }, + [](const generic_scenery& x) { return x.interactive; }, + [](generic_scenery& x, bool b) { x.interactive = b; }, + constantly(st::enabled), }, }; return std::tuple_cat(tuple0, tuple); } }; -template<typename T, typename = void> struct has_anim_atlas : std::false_type {}; +template<> struct entity_accessors<door_scenery, inspect_intent_t> +{ + static constexpr auto accessors() + { + using E = Entity<door_scenery>; + auto tuple0 = entity_accessors<object, inspect_intent_t>::accessors(); + auto tuple = std::tuple{ + E::type<bool>::field{"closing"_s, + [](const door_scenery& x) { return x.closing; }, + [](door_scenery& x, bool b) { x.closing = b; }, + constantly(st::readonly), + }, + E::type<bool>::field{"active"_s, + [](const door_scenery& x) { return x.active; }, + [](door_scenery& x, bool b) { x.active = b; }, + constantly(st::readonly), + }, + E::type<bool>::field{"interactive"_s, + [](const door_scenery& x) { return x.interactive; }, + [](door_scenery& x, bool b) { x.interactive = b; }, + constantly(st::enabled), + }, + }; + return std::tuple_cat(tuple0, tuple); + } +}; + +template<typename, typename = void> struct has_anim_atlas : std::false_type {}; template<typename T> requires requires (const T& x) { { x.atlas } -> std::convertible_to<const std::shared_ptr<anim_atlas>&>; } @@ -187,7 +204,7 @@ struct enum_values<rotation, U> }; template<typename T, typename Intent> -static bool inspect_type(T& x, Intent) +bool inspect_type(T& x, Intent) { size_t width = 0; visit_tuple([&](const auto& field) { @@ -271,7 +288,8 @@ struct entity_accessors<light, inspect_intent_t> } }; -template bool inspect_type(scenery&, inspect_intent_t); +template bool inspect_type(generic_scenery&, inspect_intent_t); +template bool inspect_type(door_scenery&, inspect_intent_t); template bool inspect_type(critter&, inspect_intent_t); template bool inspect_type(light&, inspect_intent_t); @@ -280,11 +298,26 @@ bool inspect_object_subtype(object& x) const auto type = x.type(); switch (type) { - case object_type::scenery: return inspect_type(static_cast<scenery&>(x), inspect_intent_t{}); + case object_type::scenery: { + auto& sc = static_cast<scenery&>(x); + const auto sc_type = sc.scenery_type(); + switch (sc_type) + { + case scenery_type::none: + case scenery_type::COUNT: + break; + case scenery_type::generic: + return inspect_type(static_cast<generic_scenery&>(sc), inspect_intent_t{}); + case scenery_type::door: + return inspect_type(static_cast<door_scenery&>(sc), inspect_intent_t{}); + } + fm_warn_once("unknown scenery subtype '%d'", (int)sc_type); [[fallthrough]]; + } case object_type::critter: return inspect_type(static_cast<critter&>(x), inspect_intent_t{}); case object_type::light: return inspect_type(static_cast<light&>(x), inspect_intent_t{}); - case object_type::COUNT: break; - case object_type::none: break; + case object_type::none: + case object_type::COUNT: + break; } fm_warn_once("unknown object subtype '%d'", (int)type); return false; diff --git a/editor/scenery-editor.cpp b/editor/scenery-editor.cpp index 7a99bbb0..28d94263 100644 --- a/editor/scenery-editor.cpp +++ b/editor/scenery-editor.cpp @@ -102,8 +102,26 @@ start: } } else + { + const auto sc_type = s.proto.scenery_type(); // todo check collision at pos - w.make_object<scenery>(w.make_id(), pos, s.proto); + switch (sc_type) + { + case scenery_type::none: + case scenery_type::COUNT: + break; + case scenery_type::generic: + w.make_object<generic_scenery>(w.make_id(), pos, std::get<generic_scenery_proto>(s.proto.subtype), s.proto); + goto ok; + case scenery_type::door: + w.make_object<door_scenery>(w.make_id(), pos, std::get<door_scenery_proto>(s.proto.subtype), s.proto); + goto ok; + } + fm_abort("place_tile: wrong scenery type %d", (int)sc_type); +ok: + void(); + } + } } // namespace floormat |
