Skip to main content

beetry_core/
node.rs

1use mitsein::vec1::Vec1;
2
3use crate::TickStatus;
4
5#[cfg_attr(any(test, feature = "mock"), mockall::automock)]
6/// Runtime contract for executable behavior tree nodes.
7///
8/// Implementations should keep all methods non-blocking. If a node blocks
9/// inside it can stall tree progress and leave execution
10/// stuck until that call returns.
11pub trait Node {
12    /// Advance the node by one execution step.
13    ///
14    /// Returning [`TickStatus::Running`] indicates the node is still in
15    /// progress. Returning [`TickStatus::Success`] or
16    /// [`TickStatus::Failure`] indicates the node has reached a terminal
17    /// state for the current run.
18    fn tick(&mut self) -> TickStatus;
19    /// Reset given node to its default state:
20    /// - should only be called by the behavior tree (root)
21    /// - should not block the thread and ideally be finished during single tick
22    fn reset(&mut self) {}
23
24    /// Interface to abort/cancel running tasks. Signal is generated by
25    /// scheduling (non-leaf) nodes and propagated to children. If leaf
26    /// node's task is running in an executor an abort signal is sent.
27    fn abort(&mut self) {}
28}
29
30/// Boxed type-erased [`Node`].
31pub type BoxNode = Box<dyn Node>;
32
33impl Node for BoxNode {
34    fn tick(&mut self) -> TickStatus {
35        (**self).tick()
36    }
37
38    fn reset(&mut self) {
39        (**self).reset();
40    }
41
42    fn abort(&mut self) {
43        (**self).abort();
44    }
45}
46
47/// Non-empty collection of nodes.
48pub type NonEmptyNodes = Vec1<BoxNode>;