diff --git a/libs/bt/include/psemek/bt/by_index.hpp b/libs/bt/include/psemek/bt/by_index.hpp new file mode 100644 index 00000000..b217a0f5 --- /dev/null +++ b/libs/bt/include/psemek/bt/by_index.hpp @@ -0,0 +1,65 @@ +#pragma once + +#include + +#include + +namespace psemek::bt +{ + + template + struct by_index_node; + + template + struct by_index_node, IndexFn> + : node> + { + using tree_type = tree; + using node_type = node; + using typename node_type::finished; + using typename node_type::status; + + by_index_node(IndexFn && index_fn, std::vector> children) + : index_fn_(std::move(index_fn)) + , children_(std::move(children)) + {} + + void start(Args ... args) override + { + current_index_ = index_fn_(args...); + if (current_index_ < children_.size()) + children_[current_index_]->start(args...); + } + + status update(Time dt, Args ... args) override + { + if (current_index_ >= children_.size()) + return finished{false}; + + return children_[current_index_]->update(dt, args...); + } + + bool event(Event const & event, Args ... args) override + { + if (current_index_ < children_.size()) + return children_[current_index_]->event(event, args...); + + return false; + } + + private: + IndexFn index_fn_; + std::vector> children_; + std::size_t current_index_ = 0; + }; + + template + node_ptr by_index(IndexFn && index_fn, node_ptr child, Nodes && ... other_children) + { + std::vector> children; + children.push_back(std::move(child)); + (children.push_back(std::move(other_children)), ...); + return std::make_unique>(std::move(index_fn), std::move(children)); + } + +}