behaviortree_rs/nodes/control/
fallback.rs1use behaviortree_rs_derive::bt_node;
2
3use crate::{
4 basic_types::NodeStatus,
5 nodes::{NodeError, NodeResult},
6};
7
8#[bt_node(ControlNode)]
19pub struct FallbackNode {
20 #[bt(default = "0")]
21 child_idx: usize,
22 #[bt(default = "true")]
23 all_skipped: bool,
24}
25
26#[bt_node(ControlNode)]
27impl FallbackNode {
28 async fn tick(&mut self) -> NodeResult {
29 if node_.status == NodeStatus::Idle {
30 self.all_skipped = true;
31 }
32
33 node_.status = NodeStatus::Running;
34
35 while self.child_idx < node_.children.len() {
36 let cur_child = &mut node_.children[self.child_idx];
37
38 let _prev_status = cur_child.status();
39 let child_status = cur_child.execute_tick().await?;
40
41 self.all_skipped &= child_status == NodeStatus::Skipped;
42
43 match &child_status {
44 NodeStatus::Running => {
45 return Ok(NodeStatus::Running);
46 }
47 NodeStatus::Failure => {
48 self.child_idx += 1;
49 }
50 NodeStatus::Success => {
51 node_.reset_children().await;
52 self.child_idx = 0;
53 return Ok(NodeStatus::Success);
54 }
55 NodeStatus::Skipped => {
56 self.child_idx += 1;
57 }
58 NodeStatus::Idle => {
59 return Err(NodeError::StatusError(
60 "Name here".to_string(),
61 "Idle".to_string(),
62 ));
63 }
64 };
65 }
66
67 if self.child_idx == node_.children.len() {
68 node_.reset_children().await;
69 self.child_idx = 0;
70 }
71
72 match self.all_skipped {
73 true => Ok(NodeStatus::Skipped),
74 false => Ok(NodeStatus::Failure),
75 }
76 }
77
78 async fn halt(&mut self) {
79 self.child_idx = 0;
80 node_.reset_children().await;
81 }
82}