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}