behavior_tree/behavior.rs
1use crate::maybe_profile_function;
2use crate::prelude::*;
3use std::{cell::RefCell, rc::Rc};
4
5pub trait StatefulAction<T> {
6 fn tick(&mut self, data: &mut T) -> Status;
7 fn reset(&mut self);
8}
9
10pub struct BehaviorTree<T> {
11 pub tree: Rc<RefCell<Node<T>>>,
12}
13
14impl<T> BehaviorTree<T> {
15 pub fn new(root: Node<T>) -> Self {
16 let root = Rc::new(RefCell::new(root));
17
18 Self { tree: root }
19 }
20}
21
22pub enum Behavior<T> {
23 Wait {
24 curr: f64,
25 max: f64,
26 },
27
28 RandomWait {
29 curr: f64,
30 curr_max: f64,
31 max: f64,
32 },
33
34 Cond(
35 String,
36 // Rc<dyn Fn(&mut T, &P) -> bool>,
37 fn(&T) -> bool,
38 Rc<RefCell<Node<T>>>,
39 Rc<RefCell<Node<T>>>,
40 ),
41
42 Sequence(usize, Vec<Rc<RefCell<Node<T>>>>),
43 Select(usize, Vec<Rc<RefCell<Node<T>>>>),
44
45 Action(String, fn(&mut T) -> Status),
46 ActionSuccess(String, fn(&mut T) -> ()),
47
48 StatefulAction(String, Box<dyn StatefulAction<T>>),
49 // StatefulAction(String, fn(&mut T, &P) -> Status),
50
51 // Invert(Rc<Behavior<T>>),
52 // AlwaysSucceed(Rc<Behavior<T>>),
53 // Condition(Rc<dyn Fn(f64, &mut T, &P) -> bool>, Rc<Behavior<T>>),
54 // WaitForever,
55 // Action(T),
56 While(Box<dyn Fn(&T) -> bool>, Rc<RefCell<Node<T>>>),
57}
58
59fn sequence<T>(
60 delta: f64,
61 context: &mut T,
62 is_sequence: bool,
63 current: &mut usize,
64 xs: &mut Vec<Rc<RefCell<Node<T>>>>,
65) -> Status {
66 maybe_profile_function!();
67
68 let (status_positive, status_negative) = if is_sequence {
69 (Status::Success, Status::Failure)
70 } else {
71 (Status::Failure, Status::Success)
72 };
73
74 let mut repr_string = String::new();
75 let mut status = status_positive;
76
77 let len = xs.len();
78
79 for i in 0..*current {
80 if xs[i].borrow_mut().recheck_condition(context, is_sequence) {
81 *current = i;
82 for j in (i + 1)..len {
83 if j < len {
84 xs[j].borrow_mut().reset();
85 }
86 }
87 // TODO: add a test that verifies that the break is needed
88 break;
89 }
90 }
91
92 // Resetting state
93 if *current == len {
94 *current = 0;
95 }
96
97 while *current < len {
98 let mut x = xs[*current].borrow_mut();
99
100 if x.status == Status::Success || x.status == Status::Failure {
101 // *current += 1;
102 // continue;
103 x.reset();
104 }
105 let res = x.tick(delta, context);
106
107 if res == status_positive {
108 *current += 1;
109 repr_string += "+";
110 } else if res == status_negative {
111 status = status_negative;
112 repr_string += "-";
113 break;
114 } else {
115 status = Status::Running;
116 repr_string += ".";
117 break;
118 }
119
120 // match x.tick(delta, context) {
121 // (Status::Success, repr) => {
122 // }
123 // (Status::Failure, repr) => {
124 // // return (Status::Failure, DebugRepr::new("Sequence", Status::Failure))
125 // }
126 // (Status::Running, repr) => {
127 // // return (Status::Running, DebugRepr::new("Sequence", Status::Running))
128 // }
129 // }
130 }
131
132 status
133}
134//
135// for (i, x) in xs.iter_mut().enumerate() {
136// match x.tick(delta, context) {
137// (Status::Success, repr) => {
138// if i < len - 1 {
139// index += 1;
140// }
141// repr_string += "+";
142// child_repr = Some(repr);
143// }
144// (Status::Failure, repr) => {
145// status = Status::Failure;
146// repr_string += "-";
147// child_repr = Some(repr);
148// break;
149// // return (Status::Failure, DebugRepr::new("Sequence", Status::Failure))
150// }
151// (Status::Running, repr) => {
152// status = Status::Running;
153// repr_string += ".";
154// child_repr = Some(repr);
155// break;
156// // return (Status::Running, DebugRepr::new("Sequence", Status::Running))
157// }
158// }
159// }
160
161impl<T> Behavior<T> {
162 pub fn tick(&mut self, delta: f64, context: &mut T) -> Status {
163 maybe_profile_function!();
164
165 let _status = match self {
166 Behavior::Wait {
167 ref mut curr,
168 max: _,
169 } => {
170 *curr -= delta;
171 let status = if *curr <= 0.0 {
172 Status::Success
173 } else {
174 Status::Running
175 };
176
177 return status;
178 }
179
180 Behavior::RandomWait {
181 ref mut curr,
182 curr_max: _,
183 max: _,
184 } => {
185 *curr -= delta;
186 let status = if *curr <= 0.0 {
187 Status::Success
188 } else {
189 Status::Running
190 };
191
192 return status;
193 }
194
195 Behavior::Cond(_, cond, a, b) => {
196 let c = cond(context);
197
198 let status = if c {
199 a.borrow_mut().tick(delta, context)
200 } else {
201 b.borrow_mut().tick(delta, context)
202 };
203
204 return status;
205 }
206
207 Behavior::Sequence(ref mut current, xs) => {
208 return sequence(delta, context, true, current, xs)
209 }
210
211 Behavior::Select(ref mut current, xs) => {
212 return sequence(delta, context, false, current, xs)
213 }
214
215 Behavior::Action(_, action) => {
216 let status = action(context);
217 return status;
218 }
219
220 Behavior::ActionSuccess(_, action) => {
221 let _ = action(context);
222 return Status::Success;
223 }
224
225 // TODO: state reset?
226 Behavior::StatefulAction(_, action) => {
227 return action.tick(context);
228 }
229
230 Behavior::While(cond, behavior) => {
231 if cond(context) {
232 return behavior.borrow_mut().tick(delta, context);
233 } else {
234 return Status::Failure;
235 }
236 } // Status::Success => Status::Failure,
237 // Status::Failure => Status::Success,
238 // Status::Running => Status::Running,
239 // },
240 // Behavior::AlwaysSucceed(b) => match b.tick(delta, context).0 {
241 // Status::Success | Status::Failure => Status::Success,
242 // Status::Running => Status::Running,
243 // },
244
245 // Behavior::Condition(cond, action) => {
246 // if cond(delta, context) {
247 // action.tick(delta, context).0
248 // } else {
249 // Status::Failure
250 // }
251 // }
252
253 // Behavior::StatefulAction(_) => todo!(),
254 // _ => todo!(),
255 // Behavior::Select(xs) => {
256 // for x in xs.iter_mut() {
257 // match x.tick(delta, context).0 {
258 // Status::Success => {
259 // return (Status::Success, DebugRepr::new("Select", Status::Success))
260 // }
261 // Status::Failure => {
262 // return (Status::Running, DebugRepr::new("Select", Status::Running))
263 // }
264 // Status::Running => {}
265 // }
266 // }
267 //
268 // Status::Failure
269 // }
270 };
271
272 // (status, DebugRepr::new("X", status))
273 }
274
275 pub fn reset(&mut self) {
276 maybe_profile_function!();
277
278 match self {
279 Behavior::Wait { ref mut curr, max } => {
280 *curr = *max;
281 }
282 Behavior::RandomWait {
283 ref mut curr,
284 ref mut curr_max,
285 max,
286 } => {
287 *curr_max = rand::random::<f64>() * *max;
288 *curr = *curr_max;
289 }
290 Behavior::Sequence(ref mut idx, nodes) => {
291 *idx = 0;
292 for node in nodes.iter_mut() {
293 node.borrow_mut().reset();
294 }
295 }
296 Behavior::Select(ref mut idx, nodes) => {
297 *idx = 0;
298 for node in nodes.iter_mut() {
299 node.borrow_mut().reset();
300 }
301 }
302 Behavior::StatefulAction(_name, ref mut state) => {
303 state.reset();
304 }
305
306 Behavior::While(_, node) => node.borrow_mut().reset(),
307 _ => {}
308 }
309 }
310}
311
312impl<T> core::fmt::Debug for Behavior<T> {
313 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
314 maybe_profile_function!();
315
316 match self {
317 Behavior::Wait{curr, max} => {
318 f.debug_struct("Wait").field("current", curr).field("max", max);
319 }
320 Behavior::Action(name, _fn) => {
321 f.debug_struct("Action").field("name", name);
322 }
323 // Behavior::StatefulAction() => todo!(),
324
325 _ => {}
326 // Behavior::Invert(_) => todo!(),
327 // Behavior::AlwaysSucceed(_) => todo!(),
328 // Behavior::Cond(_, _, _) => todo!(),
329 // Behavior::Sequence(_) => todo!(),
330 // Behavior::Select(_) => todo!(),
331 // Behavior::Condition(_, _) => todo!(),
332 // Behavior::ActionSuccess(_) => todo!(),
333 // Behavior::StatefulAction(_) => todo!(),
334 };
335
336 Ok(())
337 }
338}