behaviortree_rs/nodes/control/
if_then_else.rs1use behaviortree_rs_derive::bt_node;
2use log::warn;
3
4use crate::{
5 basic_types::NodeStatus,
6 nodes::{NodeError, NodeResult},
7};
8
9#[bt_node(ControlNode)]
22pub struct IfThenElseNode {
23 #[bt(default = "0")]
24 child_idx: usize,
25}
26
27#[bt_node(ControlNode)]
28impl IfThenElseNode {
29 async fn tick(&mut self) -> NodeResult {
30 let children_count = node_.children.len();
31 if !(2..=3).contains(&children_count) {
33 return Err(NodeError::NodeStructureError(
34 "IfThenElseNode must have either 2 or 3 children.".to_string(),
35 ));
36 }
37
38 node_.status = NodeStatus::Running;
39
40 if self.child_idx == 0 {
41 let status = node_.children[0].execute_tick().await?;
42 match status {
43 NodeStatus::Running => return Ok(NodeStatus::Running),
44 NodeStatus::Success => self.child_idx += 1,
45 NodeStatus::Failure => {
46 if children_count == 3 {
47 self.child_idx = 2;
48 } else {
49 return Ok(NodeStatus::Failure);
50 }
51 }
52 NodeStatus::Idle => {
53 return Err(NodeError::StatusError(
54 "Node name here".to_string(),
55 "Idle".to_string(),
56 ))
57 }
58 _ => warn!("Condition node of IfThenElseNode returned Skipped"),
59 }
60 }
61
62 if self.child_idx > 0 {
63 let status = node_.children[self.child_idx].execute_tick().await?;
64 match status {
65 NodeStatus::Running => return Ok(NodeStatus::Running),
66 status => {
67 node_.reset_children().await;
68 self.child_idx = 0;
69 return Ok(status);
70 }
71 }
72 }
73
74 Err(NodeError::NodeStructureError(
75 "Something unexpected happened in IfThenElseNode".to_string(),
76 ))
77 }
78
79 async fn halt(&mut self) {
80 self.child_idx = 0;
81 node_.reset_children().await;
82 }
83}