summaryrefslogtreecommitdiffhomepage
path: root/editor
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-04-13 12:26:26 +0200
committerStanislaw Halik <sthalik@misaki.pl>2024-04-13 12:26:26 +0200
commitcb13eb86db3593e723ce06c48a5cb2c94505d6ae (patch)
tree9b56825b1debc908dc999feace69645eb56eb2f8 /editor
parent2c042d30d96827941e5052d4eca0cc03965cacc8 (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.cpp87
-rw-r--r--editor/scenery-editor.cpp20
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