Add bt::conditional node
This commit is contained in:
parent
e7482bb165
commit
6d4abb7c03
1 changed files with 85 additions and 0 deletions
85
libs/bt/include/psemek/bt/conditional.hpp
Normal file
85
libs/bt/include/psemek/bt/conditional.hpp
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <psemek/bt/node.hpp>
|
||||||
|
#include <psemek/bt/assert.hpp>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
namespace psemek::bt
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename Tree>
|
||||||
|
struct conditional_node;
|
||||||
|
|
||||||
|
template <typename Time, typename Event, typename ... Args>
|
||||||
|
struct conditional_node<tree<Time, Event, Args...>>
|
||||||
|
: node<tree<Time, Event, Args...>>
|
||||||
|
{
|
||||||
|
using tree_type = tree<Time, Event, Args...>;
|
||||||
|
using node_type = node<tree_type>;
|
||||||
|
using typename node_type::running;
|
||||||
|
using typename node_type::finished;
|
||||||
|
using typename node_type::status;
|
||||||
|
|
||||||
|
conditional_node(node_ptr<tree_type> condition, node_ptr<tree_type> true_branch, node_ptr<tree_type> false_branch)
|
||||||
|
: condition_(std::move(condition))
|
||||||
|
, true_branch_(std::move(true_branch))
|
||||||
|
, false_branch_(std::move(false_branch))
|
||||||
|
{}
|
||||||
|
|
||||||
|
void start(Args ... args) override
|
||||||
|
{
|
||||||
|
condition_result_ = std::nullopt;
|
||||||
|
condition_->start(args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
status update(Time dt, Args ... args) override
|
||||||
|
{
|
||||||
|
if (condition_result_)
|
||||||
|
{
|
||||||
|
if (*condition_result_)
|
||||||
|
return true_branch_->update(dt, args...);
|
||||||
|
else
|
||||||
|
return false_branch_->update(dt, args...);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto result = condition_->update(dt, args...);
|
||||||
|
|
||||||
|
if (auto finished = std::get_if<typename node_type::finished>(&result))
|
||||||
|
{
|
||||||
|
condition_result_ = finished->result;
|
||||||
|
return running{};
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool event(Event const & event, Args ... args) override
|
||||||
|
{
|
||||||
|
if (condition_result_)
|
||||||
|
{
|
||||||
|
if (*condition_result_)
|
||||||
|
return true_branch_->event(event, args...);
|
||||||
|
else
|
||||||
|
return false_branch_->event(event, args...);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return condition_->event(event, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
node_ptr<tree_type> condition_;
|
||||||
|
node_ptr<tree_type> true_branch_;
|
||||||
|
node_ptr<tree_type> false_branch_;
|
||||||
|
std::optional<bool> condition_result_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Tree>
|
||||||
|
node_ptr<Tree> conditional(node_ptr<Tree> condition, node_ptr<Tree> true_branch, node_ptr<Tree> false_branch)
|
||||||
|
{
|
||||||
|
return std::make_unique<conditional_node<Tree>>(std::move(condition), std::move(true_branch), std::move(false_branch));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue