Add bt::conditional node

This commit is contained in:
Nikita Lisitsa 2024-12-05 23:04:50 +03:00
parent e7482bb165
commit 6d4abb7c03

View 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));
}
}