From 9641703375c9fd80b1b5a360a2698e1be5613140 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Sat, 23 Oct 2021 10:29:30 +0300 Subject: [PATCH] Behavior trees: implement events in updater & include node arguments in event handler --- .../include/psemek/util/behavior_tree.hpp | 111 ++++++++++++++---- 1 file changed, 85 insertions(+), 26 deletions(-) diff --git a/libs/util/include/psemek/util/behavior_tree.hpp b/libs/util/include/psemek/util/behavior_tree.hpp index 1d83c288..ea41e43e 100644 --- a/libs/util/include/psemek/util/behavior_tree.hpp +++ b/libs/util/include/psemek/util/behavior_tree.hpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace psemek::util { @@ -30,7 +31,7 @@ namespace psemek::util { virtual void start(Args ...) = 0; virtual status update(Time, Args ...) = 0; - virtual bool event(Event const &) = 0; + virtual bool event(Event const &, Args ...) = 0; virtual ~any_node_base() {} }; @@ -55,9 +56,9 @@ namespace psemek::util return node.update(dt, args...); } - bool event(Event const & e) override + bool event(Event const & e, Args ... args) override { - return node.event(e); + return node.event(e, args...); } }; @@ -78,9 +79,9 @@ namespace psemek::util return impl_->update(dt, args...); } - bool event(Event const & e) + bool event(Event const & e, Args ... args) { - return impl_->event(e); + return impl_->event(e, args...); } private: @@ -103,6 +104,27 @@ namespace psemek::util new_.push_back(node_data{std::move(node), {args...}, 0, 0}); } + template + void event(Event const & e, Filter && filter) + { + for (node_data & n : active_) + { + if (std::apply(filter, n.args)) + std::apply([&](Args ... args){ n.node.event(e, args...); }, n.args); + } + + for (node_data & n : suspended_) + { + if (std::apply(filter, n.args)) + { + if (std::apply([&](Args ... args){ return n.node.event(e, args...); }, n.args)) + { + n.duration = n.elapsed; + } + } + } + } + struct update_statistics { int active_count = 0; @@ -202,7 +224,7 @@ namespace psemek::util return finished{true}; } - bool event(Event const &) + bool event(Event const &, Args ...) { return false; } @@ -232,7 +254,7 @@ namespace psemek::util return suspended{remaining_time}; } - bool event(Event const &) + bool event(Event const &, Args ...) { return false; } @@ -255,12 +277,49 @@ namespace psemek::util return finished{condFn(args...)}; } - bool event(Event const &) + bool event(Event const &, Args ...) { return false; } }; + template + struct on_event + { + EventFn eventFn; + Child child; + + std::optional cached_status; + + on_event(EventFn eventFn, Child child) + : eventFn(std::move(eventFn)) + , child(std::move(child)) + {} + + void start(Args ... args) + { + child.start(args...); + } + + status update(Time dt, Args ... args) + { + if (cached_status) + { + auto result = *cached_status; + cached_status = std::nullopt; + return result; + } + + return child.update(dt, std::forward(args)...); + } + + bool event(Event const & e, Args ... args) + { + cached_status = eventFn(e, args...); + return static_cast(cached_status); + } + }; + template struct success { @@ -283,9 +342,9 @@ namespace psemek::util return child_status; } - bool event(Event const & e) + bool event(Event const & e, Args ... args) { - return child.event(e); + return child.event(e, args...); } }; @@ -311,9 +370,9 @@ namespace psemek::util return child_status; } - bool event(Event const & e) + bool event(Event const & e, Args ... args) { - return child.event(e); + return child.event(e, args...); } }; @@ -347,9 +406,9 @@ namespace psemek::util return result; } - bool event(Event const & e) + bool event(Event const & e, Args ... args) { - return child.event(e); + return child.event(e, args...); } }; @@ -383,9 +442,9 @@ namespace psemek::util return result; } - bool event(Event const & e) + bool event(Event const & e, Args ... args) { - return child.event(e); + return child.event(e, args...); } }; @@ -418,9 +477,9 @@ namespace psemek::util return update_impl<0>(dt, args...); } - bool event(Event const & e) + bool event(Event const & e, Args ... args) { - return event_impl<0>(e); + return event_impl<0>(e, args...); } private: @@ -461,7 +520,7 @@ namespace psemek::util } template - bool event_impl(Event const & e) + bool event_impl(Event const & e, Args ... args) { if constexpr (I == sizeof...(Children)) { @@ -471,11 +530,11 @@ namespace psemek::util { if (current == I) { - return std::get(children).event(e); + return std::get(children).event(e, args...); } else { - return event_impl(e); + return event_impl(e, args...); } } } @@ -510,9 +569,9 @@ namespace psemek::util return update_impl<0>(dt, args...); } - bool event(Event const & e) + bool event(Event const & e, Args ... args) { - return event_impl<0>(e); + return event_impl<0>(e, args...); } private: @@ -555,7 +614,7 @@ namespace psemek::util } template - bool event_impl(Event const & e) + bool event_impl(Event const & e, Args ... args) { if constexpr (I == sizeof...(Children)) { @@ -565,11 +624,11 @@ namespace psemek::util { if (current == I) { - return std::get(children).event(e); + return std::get(children).event(e, args...); } else { - return event_impl(e); + return event_impl(e, args...); } } }