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 <memory>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
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 <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
|
||||
{
|
||||
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 <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>
|
||||
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 <size_t I>
|
||||
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<I>(children).event(e);
|
||||
return std::get<I>(children).event(e, args...);
|
||||
}
|
||||
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...);
|
||||
}
|
||||
|
||||
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 <size_t I>
|
||||
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<I>(children).event(e);
|
||||
return std::get<I>(children).event(e, args...);
|
||||
}
|
||||
else
|
||||
{
|
||||
return event_impl<I + 1>(e);
|
||||
return event_impl<I + 1>(e, args...);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue