Behavior trees: implement events in updater & include node arguments in event handler
This commit is contained in:
parent
73bf540967
commit
9641703375
1 changed files with 85 additions and 26 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace psemek::util
|
namespace psemek::util
|
||||||
{
|
{
|
||||||
|
|
@ -30,7 +31,7 @@ namespace psemek::util
|
||||||
{
|
{
|
||||||
virtual void start(Args ...) = 0;
|
virtual void start(Args ...) = 0;
|
||||||
virtual status update(Time, 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() {}
|
virtual ~any_node_base() {}
|
||||||
};
|
};
|
||||||
|
|
@ -55,9 +56,9 @@ namespace psemek::util
|
||||||
return node.update(dt, args...);
|
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...);
|
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:
|
private:
|
||||||
|
|
@ -103,6 +104,27 @@ namespace psemek::util
|
||||||
new_.push_back(node_data{std::move(node), {args...}, 0, 0});
|
new_.push_back(node_data{std::move(node), {args...}, 0, 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Filter>
|
||||||
|
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
|
struct update_statistics
|
||||||
{
|
{
|
||||||
int active_count = 0;
|
int active_count = 0;
|
||||||
|
|
@ -202,7 +224,7 @@ namespace psemek::util
|
||||||
return finished{true};
|
return finished{true};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool event(Event const &)
|
bool event(Event const &, Args ...)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -232,7 +254,7 @@ namespace psemek::util
|
||||||
return suspended{remaining_time};
|
return suspended{remaining_time};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool event(Event const &)
|
bool event(Event const &, Args ...)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -255,12 +277,49 @@ namespace psemek::util
|
||||||
return finished{condFn(args...)};
|
return finished{condFn(args...)};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool event(Event const &)
|
bool event(Event const &, Args ...)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename EventFn, typename Child>
|
||||||
|
struct on_event
|
||||||
|
{
|
||||||
|
EventFn eventFn;
|
||||||
|
Child child;
|
||||||
|
|
||||||
|
std::optional<status> 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>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool event(Event const & e, Args ... args)
|
||||||
|
{
|
||||||
|
cached_status = eventFn(e, args...);
|
||||||
|
return static_cast<bool>(cached_status);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Child>
|
template <typename Child>
|
||||||
struct success
|
struct success
|
||||||
{
|
{
|
||||||
|
|
@ -283,9 +342,9 @@ namespace psemek::util
|
||||||
return child_status;
|
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;
|
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;
|
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;
|
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...);
|
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:
|
private:
|
||||||
|
|
@ -461,7 +520,7 @@ namespace psemek::util
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t I>
|
template <size_t I>
|
||||||
bool event_impl(Event const & e)
|
bool event_impl(Event const & e, Args ... args)
|
||||||
{
|
{
|
||||||
if constexpr (I == sizeof...(Children))
|
if constexpr (I == sizeof...(Children))
|
||||||
{
|
{
|
||||||
|
|
@ -471,11 +530,11 @@ namespace psemek::util
|
||||||
{
|
{
|
||||||
if (current == I)
|
if (current == I)
|
||||||
{
|
{
|
||||||
return std::get<I>(children).event(e);
|
return std::get<I>(children).event(e, args...);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return event_impl<I + 1>(e);
|
return event_impl<I + 1>(e, args...);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -510,9 +569,9 @@ namespace psemek::util
|
||||||
return update_impl<0>(dt, args...);
|
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:
|
private:
|
||||||
|
|
@ -555,7 +614,7 @@ namespace psemek::util
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t I>
|
template <size_t I>
|
||||||
bool event_impl(Event const & e)
|
bool event_impl(Event const & e, Args ... args)
|
||||||
{
|
{
|
||||||
if constexpr (I == sizeof...(Children))
|
if constexpr (I == sizeof...(Children))
|
||||||
{
|
{
|
||||||
|
|
@ -565,11 +624,11 @@ namespace psemek::util
|
||||||
{
|
{
|
||||||
if (current == I)
|
if (current == I)
|
||||||
{
|
{
|
||||||
return std::get<I>(children).event(e);
|
return std::get<I>(children).event(e, args...);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return event_impl<I + 1>(e);
|
return event_impl<I + 1>(e, args...);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue