From 23828de853b97173f5e4a4a9e3e9706b892fd7cf Mon Sep 17 00:00:00 2001 From: lisyarus Date: Sun, 24 Oct 2021 12:36:56 +0300 Subject: [PATCH] Behavior tree: add repeat_while primitive --- .../include/psemek/util/behavior_tree.hpp | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/libs/util/include/psemek/util/behavior_tree.hpp b/libs/util/include/psemek/util/behavior_tree.hpp index 6e2e9962..48af1093 100644 --- a/libs/util/include/psemek/util/behavior_tree.hpp +++ b/libs/util/include/psemek/util/behavior_tree.hpp @@ -414,6 +414,81 @@ namespace psemek::util } }; + template + struct repeat_while + { + Condition condition; + Child child; + bool current_started = false; + int current = 0; + + repeat_while(Condition condition, Child child) + : condition(std::move(condition)) + , child(std::move(child)) + {} + + void start(Args ...) + { + current = 0; + current_started = false; + } + + status update(Time dt, Args ... args) + { + if (current == 0) + { + if (!current_started) + { + condition.start(args...); + current_started = true; + } + + auto result = condition.update(dt, args...); + if (auto f = std::get_if(&result)) + { + if (!(f->result)) + return finished{true}; + else + { + current = 1; + current_started = false; + dt = 0; + } + } + else + return result; + } + + // current == 1 + + if (!current_started) + { + child.start(args...); + current_started = true; + } + + auto result = child.update(dt, args...); + if (auto f = std::get_if(&result)) + { + if (!(f->result)) + return finished{false}; + else + { + current = 0; + current_started = false; + return running{}; + } + } + else + return result; + } + + bool event(Event const & e, Args ... args) + { + return condition.event(e, args...) || child.event(e, args...); + } + }; + template struct retry {