diff --git a/bonsai/src/bt.rs b/bonsai/src/bt.rs index 8b03709..74f091c 100644 --- a/bonsai/src/bt.rs +++ b/bonsai/src/bt.rs @@ -1,7 +1,7 @@ use std::fmt::Debug; use crate::visualizer::NodeType; -use crate::{ActionArgs, Behavior, State, Status, UpdateEvent}; +use crate::{state::State, ActionArgs, Behavior, Status, UpdateEvent}; use petgraph::dot::{Config, Dot}; use petgraph::Graph; @@ -14,7 +14,7 @@ use serde::{Deserialize, Serialize}; #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct BT { /// constructed behavior tree - pub state: State, + state: State, /// keep the initial state initial_behavior: Behavior, /// The data storage shared by all nodes in the tree. This is generally @@ -35,7 +35,8 @@ impl BT { } } - /// Updates the cursor that tracks an event. + /// Updates the cursor that tracks an event. If the behavior tree previously + /// finished (either success or failure), it will automatically be restarted. /// /// The action need to return status and remaining delta time. /// Returns status and the remaining delta time. @@ -53,7 +54,13 @@ impl BT { E: UpdateEvent, F: FnMut(ActionArgs, &mut B) -> (Status, f64), { - self.state.tick(e, &mut self.bb, f) + match self.state.tick(e, &mut self.bb, f) { + result @ (Status::Success | Status::Failure, _) => { + self.reset_bt(); + result + } + result => result, + } } /// Retrieve a mutable reference to the blackboard for @@ -62,12 +69,6 @@ impl BT { &mut self.bb } - /// Retrieve a mutable reference to the internal state - /// of the Behavior Tree - pub fn get_state(bt: &mut BT) -> &mut State { - &mut bt.state - } - /// The behavior tree is a stateful data structure in which the immediate /// state of the BT is allocated and updated in heap memory through the lifetime /// of the BT. The state of the BT is said to be `transient` meaning upon entering diff --git a/bonsai/src/lib.rs b/bonsai/src/lib.rs index 88747e5..512672b 100644 --- a/bonsai/src/lib.rs +++ b/bonsai/src/lib.rs @@ -124,7 +124,7 @@ pub use behavior::Behavior::{ pub use bt::BT; pub use event::{Event, Timer, UpdateArgs, UpdateEvent}; -pub use state::{ActionArgs, State, RUNNING}; +pub use state::{ActionArgs, RUNNING}; pub use status::Status::{self, Failure, Running, Success}; mod behavior; diff --git a/bonsai/src/sequence.rs b/bonsai/src/sequence.rs index e51f697..15e3139 100644 --- a/bonsai/src/sequence.rs +++ b/bonsai/src/sequence.rs @@ -1,5 +1,5 @@ use crate::status::Status::*; -use crate::{event::UpdateEvent, ActionArgs, Behavior, State, Status, RUNNING}; +use crate::{event::UpdateEvent, state::State, ActionArgs, Behavior, Status, RUNNING}; pub struct SequenceArgs<'a, A, E, F, B> { pub select: bool, diff --git a/bonsai/src/state.rs b/bonsai/src/state.rs index 0df0037..73064a7 100644 --- a/bonsai/src/state.rs +++ b/bonsai/src/state.rs @@ -28,19 +28,19 @@ pub struct ActionArgs<'a, E: 'a, A: 'a> { /// Keeps track of a behavior. #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub enum State { +pub(crate) enum State { /// Executes an action. - ActionState(A), + Action(A), /// Converts `Success` into `Failure` and vice versa. - InvertState(Box>), + Invert(Box>), /// Ignores failures and always return `Success`. - AlwaysSucceedState(Box>), + AlwaysSucceed(Box>), /// Keeps track of waiting for a period of time before continuing. - WaitState { time_to_wait: f64, elapsed_time: f64 }, + Wait { time_to_wait: f64, elapsed_time: f64 }, /// Waits forever. - WaitForeverState, + WaitForever, /// Keeps track of an `If` behavior. - IfState { + If { /// The behavior to run if the status is a success. on_success: Box>, /// The behavior to run if the status is a failure. @@ -52,7 +52,7 @@ pub enum State { current_state: Box>, }, /// Keeps track of a `Select` behavior. - SelectState { + Select { /// The behaviors that will be selected across in order. behaviors: Vec>, /// The index of the behavior currently being executed. @@ -61,7 +61,7 @@ pub enum State { current_state: Box>, }, /// Keeps track of an `Sequence` behavior. - SequenceState { + Sequence { /// The behaviors that will be executed in order. behaviors: Vec>, /// The index of the behavior currently being executed. @@ -70,7 +70,7 @@ pub enum State { current_state: Box>, }, /// Keeps track of a `While` behavior. - WhileState { + While { /// The state of the condition of the loop. The loop continues to run /// while this state is running. condition_state: Box>, @@ -82,7 +82,7 @@ pub enum State { loop_body_state: Box>, }, /// Keeps track of a `WhileAll` behavior. - WhileAllState { + WhileAll { /// The state of the condition of the loop. The loop continues to run /// while this state is running, though this is only checked once at the /// start of each loop. @@ -98,12 +98,12 @@ pub enum State { }, /// Keeps track of a `WhenAll` behavior. As the states finish, they are set /// to [`None`]. - WhenAllState(Vec>>), + WhenAll(Vec>>), /// Keeps track of a `WhenAny` behavior. As the states finish, they are set /// to [`None`]. - WhenAnyState(Vec>>), + WhenAny(Vec>>), /// Keeps track of an `After` behavior. - AfterState { + After { /// The index of the next state that must succeed. next_success_index: usize, /// The states for the behaviors currently executing. All the states @@ -122,17 +122,17 @@ impl State { /// the executing instance of that behavior. pub fn new(behavior: Behavior) -> Self { match behavior { - Behavior::Action(action) => State::ActionState(action), - Behavior::Invert(ev) => State::InvertState(Box::new(State::new(*ev))), - Behavior::AlwaysSucceed(ev) => State::AlwaysSucceedState(Box::new(State::new(*ev))), - Behavior::Wait(dt) => State::WaitState { + Behavior::Action(action) => State::Action(action), + Behavior::Invert(ev) => State::Invert(Box::new(State::new(*ev))), + Behavior::AlwaysSucceed(ev) => State::AlwaysSucceed(Box::new(State::new(*ev))), + Behavior::Wait(dt) => State::Wait { time_to_wait: dt, elapsed_time: 0.0, }, - Behavior::WaitForever => State::WaitForeverState, + Behavior::WaitForever => State::WaitForever, Behavior::If(condition, on_success, on_failure) => { let state = State::new(*condition); - State::IfState { + State::If { on_success, on_failure, status: Status::Running, @@ -141,7 +141,7 @@ impl State { } Behavior::Select(behaviors) => { let state = State::new(behaviors[0].clone()); - State::SelectState { + State::Select { behaviors, current_index: 0, current_state: Box::new(state), @@ -149,7 +149,7 @@ impl State { } Behavior::Sequence(behaviors) => { let state = State::new(behaviors[0].clone()); - State::SequenceState { + State::Sequence { behaviors, current_index: 0, current_state: Box::new(state), @@ -157,16 +157,16 @@ impl State { } Behavior::While(condition, loop_body) => { let state = State::new(loop_body[0].clone()); - State::WhileState { + State::While { condition_state: Box::new(State::new(*condition)), loop_body, loop_body_index: 0, loop_body_state: Box::new(state), } } - Behavior::WhenAll(all) => State::WhenAllState(all.into_iter().map(|ev| Some(State::new(ev))).collect()), - Behavior::WhenAny(any) => State::WhenAnyState(any.into_iter().map(|ev| Some(State::new(ev))).collect()), - Behavior::After(after_all) => State::AfterState { + Behavior::WhenAll(all) => State::WhenAll(all.into_iter().map(|ev| Some(State::new(ev))).collect()), + Behavior::WhenAny(any) => State::WhenAny(any.into_iter().map(|ev| Some(State::new(ev))).collect()), + Behavior::After(after_all) => State::After { next_success_index: 0, states: after_all.into_iter().map(State::new).collect(), }, @@ -177,7 +177,7 @@ impl State { .expect("WhileAll's sequence of behaviors to run cannot be empty!") .clone(), ); - State::WhileAllState { + State::WhileAll { condition_state: Box::new(State::new(*condition)), check_condition: true, loop_body, @@ -209,7 +209,7 @@ impl State { // double match statements match (upd, self) { - (_, &mut ActionState(ref action)) => { + (_, &mut Action(ref action)) => { // println!("In ActionState: {:?}", action); f( ActionArgs { @@ -220,7 +220,7 @@ impl State { blackboard, ) } - (_, &mut InvertState(ref mut cur)) => { + (_, &mut Invert(ref mut cur)) => { // println!("In InvertState: {:?}", cur); match cur.tick(e, blackboard, f) { (Running, dt) => (Running, dt), @@ -228,7 +228,7 @@ impl State { (Success, dt) => (Failure, dt), } } - (_, &mut AlwaysSucceedState(ref mut cur)) => { + (_, &mut AlwaysSucceed(ref mut cur)) => { // println!("In AlwaysSucceedState: {:?}", cur); match cur.tick(e, blackboard, f) { (Running, dt) => (Running, dt), @@ -237,7 +237,7 @@ impl State { } ( Some(dt), - &mut WaitState { + &mut Wait { time_to_wait, ref mut elapsed_time, }, @@ -254,7 +254,7 @@ impl State { } ( _, - &mut IfState { + &mut If { ref on_success, ref on_failure, ref mut status, @@ -301,7 +301,7 @@ impl State { } ( _, - &mut SelectState { + &mut Select { behaviors: ref seq, current_index: ref mut i, current_state: ref mut cursor, @@ -322,7 +322,7 @@ impl State { } ( _, - &mut SequenceState { + &mut Sequence { behaviors: ref seq, current_index: ref mut i, current_state: ref mut cursor, @@ -343,7 +343,7 @@ impl State { } ( _, - &mut WhileState { + &mut While { ref mut condition_state, ref loop_body, ref mut loop_body_index, @@ -394,19 +394,19 @@ impl State { } RUNNING } - (_, &mut WhenAllState(ref mut cursors)) => { + (_, &mut WhenAll(ref mut cursors)) => { // println!("In WhenAllState: {:?}", cursors); let any = false; when_all(any, upd, cursors, e, f, blackboard) } - (_, &mut WhenAnyState(ref mut cursors)) => { + (_, &mut WhenAny(ref mut cursors)) => { // println!("In WhenAnyState: {:?}", cursors); let any = true; when_all(any, upd, cursors, e, f, blackboard) } ( _, - &mut AfterState { + &mut After { ref mut next_success_index, ref mut states, }, @@ -443,7 +443,7 @@ impl State { } ( _, - &mut WhileAllState { + &mut WhileAll { ref mut condition_state, ref mut check_condition, ref loop_body, diff --git a/bonsai/src/visualizer.rs b/bonsai/src/visualizer.rs index 41534b8..f4dfad8 100644 --- a/bonsai/src/visualizer.rs +++ b/bonsai/src/visualizer.rs @@ -1,5 +1,5 @@ #![allow(dead_code, unused_imports, unused_variables)] -use crate::{Behavior, Select, Sequence, State, BT}; +use crate::{state::State, Behavior, Select, Sequence, BT}; use petgraph::{graph::Graph, stable_graph::NodeIndex, Direction::Outgoing}; use std::{collections::VecDeque, fmt::Debug}; diff --git a/bonsai/src/when_all.rs b/bonsai/src/when_all.rs index 3e3954f..8a1df76 100644 --- a/bonsai/src/when_all.rs +++ b/bonsai/src/when_all.rs @@ -1,5 +1,5 @@ use crate::status::Status::*; -use crate::{event::UpdateEvent, ActionArgs, State, Status, RUNNING}; +use crate::{event::UpdateEvent, state::State, ActionArgs, Status, RUNNING}; // `WhenAll` and `WhenAny` share same algorithm. // diff --git a/bonsai/tests/behavior_tests.rs b/bonsai/tests/behavior_tests.rs index 543e14e..2787a70 100644 --- a/bonsai/tests/behavior_tests.rs +++ b/bonsai/tests/behavior_tests.rs @@ -1,7 +1,7 @@ use crate::behavior_tests::TestActions::{Dec, Inc, LessThan, LessThanRunningSuccess}; use bonsai_bt::{ - Action, ActionArgs, After, AlwaysSucceed, Event, Failure, If, Invert, Select, Sequence, State, Status::Running, - Success, UpdateArgs, Wait, WaitForever, WhenAll, While, WhileAll, + Action, ActionArgs, After, AlwaysSucceed, Event, Failure, If, Invert, Select, Sequence, Status::Running, Success, + UpdateArgs, Wait, WaitForever, WhenAll, While, WhileAll, BT, }; /// Some test actions. @@ -18,67 +18,59 @@ enum TestActions { } // A test state machine that can increment and decrement. -fn tick(mut acc: i32, dt: f64, state: &mut State) -> (i32, bonsai_bt::Status, f64) { +fn tick(mut acc: i32, dt: f64, state: &mut BT) -> (i32, bonsai_bt::Status, f64) { let e: Event = UpdateArgs { dt }.into(); println!("acc {}", acc); - let (s, t) = state.tick( - &e, - &mut (), - &mut |args: ActionArgs, _| match *args.action { - Inc => { - acc += 1; + let (s, t) = state.tick(&e, &mut |args: ActionArgs, _| match *args.action { + Inc => { + acc += 1; + (Success, args.dt) + } + Dec => { + acc -= 1; + (Success, args.dt) + } + LessThan(v) => { + println!("inside less than with acc: {}", acc); + if acc < v { + println!("success {}<{}", acc, v); (Success, args.dt) + } else { + println!("failure {}>={}", acc, v); + (Failure, args.dt) } - Dec => { - acc -= 1; + } + TestActions::LessThanRunningSuccess(v) => { + println!("inside LessThanRunningSuccess with acc: {}", acc); + if acc < v { + println!("success {}<{}", acc, v); + (Running, args.dt) + } else { + println!("failure {}>={}", acc, v); (Success, args.dt) } - LessThan(v) => { - println!("inside less than with acc: {}", acc); - if acc < v { - println!("success {}<{}", acc, v); - (Success, args.dt) - } else { - println!("failure {}>={}", acc, v); - (Failure, args.dt) - } - } - TestActions::LessThanRunningSuccess(v) => { - println!("inside LessThanRunningSuccess with acc: {}", acc); - if acc < v { - println!("success {}<{}", acc, v); - (Running, args.dt) - } else { - println!("failure {}>={}", acc, v); - (Success, args.dt) - } - } - }, - ); + } + }); println!("status: {:?} dt: {}", s, t); (acc, s, t) } // A test state machine that can increment and decrement. -fn tick_with_ref(acc: &mut i32, dt: f64, state: &mut State) { +fn tick_with_ref(acc: &mut i32, dt: f64, state: &mut BT) { let e: Event = UpdateArgs { dt }.into(); - state.tick( - &e, - &mut (), - &mut |args: ActionArgs, _| match *args.action { - Inc => { - *acc += 1; - (Success, args.dt) - } - Dec => { - *acc -= 1; - (Success, args.dt) - } - TestActions::LessThanRunningSuccess(_) | LessThan(_) => todo!(), - }, - ); + state.tick(&e, &mut |args: ActionArgs, _| match *args.action { + Inc => { + *acc += 1; + (Success, args.dt) + } + Dec => { + *acc -= 1; + (Success, args.dt) + } + TestActions::LessThanRunningSuccess(_) | LessThan(_) => todo!(), + }); } // Each action that terminates immediately @@ -90,11 +82,12 @@ fn test_immediate_termination() { let mut a: i32 = 0; let seq = Sequence(vec![Action(Inc), Action(Inc)]); - let mut state = State::new(seq); + let mut state = BT::new(seq, ()); tick_with_ref(&mut a, 0.0, &mut state); assert_eq!(a, 2); + // The tree reset since it finished, so it will re-execute. tick_with_ref(&mut a, 1.0, &mut state); - assert_eq!(a, 2) + assert_eq!(a, 4) } // Tree terminates after 2.001 seconds @@ -107,7 +100,7 @@ fn while_wait_sequence_twice() { Box::new(Wait(2.001)), vec![Sequence(vec![Wait(0.5), Action(Inc), Wait(0.5), Action(Inc)])], ); - let mut state = State::new(w); + let mut state = BT::new(w, ()); tick_with_ref(&mut a, 1.0, &mut state); assert_eq!(a, 2); tick_with_ref(&mut a, 1.0, &mut state); @@ -123,7 +116,7 @@ fn while_wait_sequence_twice() { fn wait_sec() { let a: i32 = 0; let seq = Sequence(vec![Wait(1.0), Action(Inc)]); - let mut state = State::new(seq); + let mut state = BT::new(seq, ()); let (a, _, _) = tick(a, 1.0, &mut state); assert_eq!(a, 1); } @@ -134,7 +127,7 @@ fn wait_sec() { fn wait_half_sec() { let a: i32 = 0; let seq = Sequence(vec![Wait(1.0), Action(Inc)]); - let mut state = State::new(seq); + let mut state = BT::new(seq, ()); let (a, _, _) = tick(a, 0.5, &mut state); assert_eq!(a, 0); let (a, _, _) = tick(a, 0.5, &mut state); @@ -146,7 +139,7 @@ fn wait_half_sec() { fn sequence_of_one_event() { let a: i32 = 0; let seq = Sequence(vec![Action(Inc)]); - let mut state = State::new(seq); + let mut state = BT::new(seq, ()); let (a, _, _) = tick(a, 1.0, &mut state); assert_eq!(a, 1); } @@ -156,7 +149,7 @@ fn sequence_of_one_event() { fn wait_two_waits() { let a: i32 = 0; let seq = Sequence(vec![Wait(0.5), Wait(0.5), Action(Inc)]); - let mut state = State::new(seq); + let mut state = BT::new(seq, ()); let (a, _, _) = tick(a, 1.0, &mut state); assert_eq!(a, 1); } @@ -166,7 +159,7 @@ fn wait_two_waits() { fn loop_ten_times() { let a: i32 = 0; let rep = While(Box::new(Wait(50.0)), vec![Wait(0.5), Action(Inc), Wait(0.5)]); - let mut state = State::new(rep); + let mut state = BT::new(rep, ()); // sample after 10 seconds let (a, _, _) = tick(a, 10.0, &mut state); @@ -181,7 +174,7 @@ fn when_all_wait() { WhenAll(vec![Wait(0.5), Wait(1.0)]), Action(Inc), ]); - let mut state = State::new(all); + let mut state = BT::new(all, ()); let (a, _, _) = tick(a, 0.5, &mut state); assert_eq!(a, 0); let (a, _, _) = tick(a, 0.5, &mut state); @@ -195,7 +188,7 @@ fn while_wait_sequence() { Box::new(Wait(9.999999)), vec![Sequence(vec![Wait(0.5), Action(Inc), Wait(0.5), Action(Inc)])], ); - let mut state = State::new(w); + let mut state = BT::new(w, ()); for _ in 0..100 { (a, _, _) = tick(a, 0.1, &mut state); } @@ -207,7 +200,7 @@ fn while_wait_sequence() { fn while_wait_forever_sequence() { let mut a: i32 = 0; let w = While(Box::new(WaitForever), vec![Sequence(vec![Action(Inc), Wait(1.0)])]); - let mut state = State::new(w); + let mut state = BT::new(w, ()); (a, _, _) = tick(a, 1.001, &mut state); assert_eq!(a, 2); } @@ -221,8 +214,9 @@ fn test_if_less_than() { Box::new(Action(Dec)), // else ); - let mut state = State::new(_if); + let mut state = BT::new(_if, ()); + // The tree resets after each tick. let (a, s, _) = tick(a, 0.1, &mut state); assert_eq!(a, 2); assert_eq!(s, Success); @@ -233,7 +227,7 @@ fn test_if_less_than() { assert_eq!(a, 0); assert_eq!(s, Success); let (a, s, _) = tick(a, 0.1, &mut state); - assert_eq!(a, -1); + assert_eq!(a, 1); assert_eq!(s, Success); } @@ -248,7 +242,7 @@ fn when_all_if() { let _while = While(Box::new(Wait(50.0)), vec![Wait(0.5), Action(Inc), Wait(0.5)]); let w = WhenAll(vec![_if, _while]); - let mut state = State::new(w); + let mut state = BT::new(w, ()); // sample state after 8 seconds let (a, _, _) = tick(a, 8.0, &mut state); @@ -263,7 +257,7 @@ fn when_all_if() { fn test_alter_wait_time() { let a: i32 = 0; let rep = While(Box::new(Wait(50.0)), vec![Wait(0.5), Action(Inc), Wait(0.5)]); - let mut state = State::new(rep); + let mut state = BT::new(rep, ()); // sample after 10 seconds let (a, _, _) = tick(a, 10.0, &mut state); @@ -274,7 +268,7 @@ fn test_alter_wait_time() { fn test_select_succeed_on_first() { let a: i32 = 0; let sel = Select(vec![Action(Inc), Action(Inc), Action(Inc)]); - let mut state = State::new(sel); + let mut state = BT::new(sel, ()); let (a, _, _) = tick(a, 0.1, &mut state); assert_eq!(a, 1); @@ -283,31 +277,10 @@ fn test_select_succeed_on_first() { } #[test] -fn test_select_no_state_reset() { - let a: i32 = 3; - let sel = Select(vec![Action(LessThan(1)), Action(Dec), Action(Inc)]); - let mut state = State::new(sel); - - let (a, s, _) = tick(a, 0.1, &mut state); - assert_eq!(a, 2); - assert_eq!(s, Success); - let (a, s, _) = tick(a, 0.1, &mut state); - assert_eq!(a, 1); - assert_eq!(s, Success); - let (a, s, _) = tick(a, 0.1, &mut state); - assert_eq!(a, 0); - assert_eq!(s, Success); - let (a, s, _) = tick(a, 0.1, &mut state); - assert_eq!(a, -1); - assert_eq!(s, Success); -} - -#[test] -fn test_select_with_state_reset() { +fn test_select_auto_reset_state() { let a: i32 = 3; let sel = Select(vec![Action(LessThan(1)), Action(Dec), Action(Inc)]); - let sel_clone = sel.clone(); - let mut state = State::new(sel); + let mut state = BT::new(sel, ()); let (a, s, _) = tick(a, 0.1, &mut state); assert_eq!(a, 2); @@ -318,10 +291,6 @@ fn test_select_with_state_reset() { let (a, s, _) = tick(a, 0.1, &mut state); assert_eq!(a, 0); assert_eq!(s, Success); - - // reset state - state = State::new(sel_clone); - let (a, s, _) = tick(a, 0.1, &mut state); assert_eq!(a, 0); assert_eq!(s, Success); @@ -332,7 +301,7 @@ fn test_select_and_when_all() { let a: i32 = 3; let sel = Select(vec![Action(LessThan(1)), Action(Dec), Action(Inc)]); let whenall = WhenAll(vec![Wait(0.35), sel]); - let mut state = State::new(whenall); + let mut state = BT::new(whenall, ()); let (a, s, _) = tick(a, 0.1, &mut state); assert_eq!(a, 2); @@ -346,10 +315,8 @@ fn test_select_and_when_all() { fn test_select_and_invert() { let a: i32 = 3; let sel = Invert(Box::new(Select(vec![Action(LessThan(1)), Action(Dec), Action(Inc)]))); - let whenall = WhenAll(vec![Wait(0.35), sel]); - let mut state = State::new(whenall); + let mut state = BT::new(sel, ()); - // Running + Failure = Failure let (a, s, _) = tick(a, 0.1, &mut state); assert_eq!(a, 2); assert_eq!(s, Failure); @@ -360,12 +327,12 @@ fn test_select_and_invert() { assert_eq!(a, 0); assert_eq!(s, Failure); let (a, s, _) = tick(a, 0.1, &mut state); - assert_eq!(a, -1); + assert_eq!(a, 0); assert_eq!(s, Failure); } #[test] -fn test_allways_succeed() { +fn test_always_succeed() { let a: i32 = 3; let sel = Sequence(vec![ Wait(0.5), @@ -375,7 +342,7 @@ fn test_allways_succeed() { Wait(0.5), ]); let behavior = AlwaysSucceed(Box::new(sel)); - let mut state = State::new(behavior); + let mut state = BT::new(behavior, ()); let (a, s, _) = tick(a, 0.1, &mut state); assert_eq!(a, 3); @@ -383,19 +350,21 @@ fn test_allways_succeed() { let (a, s, _) = tick(a, 0.7, &mut state); assert_eq!(a, 3); assert_eq!(s, Success); - let (a, s, _) = tick(a, 0.4, &mut state); + // The tree was automatically reset since it completed. + let (a, s, _) = tick(a, 0.5, &mut state); assert_eq!(a, 3); assert_eq!(s, Success); + // The tree was reset again. let (a, s, _) = tick(a, 0.1, &mut state); assert_eq!(a, 3); - assert_eq!(s, Success); + assert_eq!(s, Running); } #[test] fn test_after_all_succeed_in_order() { let a: i32 = 0; let after = After(vec![Action(Inc), Wait(0.1), Wait(0.2)]); - let mut state = State::new(after); + let mut state = BT::new(after, ()); let (a, s, dt) = tick(a, 0.1, &mut state); @@ -414,7 +383,7 @@ fn test_after_all_succeed_in_order() { fn test_after_all_succeed_out_of_order() { let a: i32 = 0; let after = After(vec![Action(Inc), Wait(0.2), Wait(0.1)]); - let mut state = State::new(after); + let mut state = BT::new(after, ()); let (a, s, dt) = tick(a, 0.05, &mut state); @@ -435,7 +404,7 @@ fn test_repeat_sequence() { let a: i32 = 0; let after = WhileAll(Box::new(Action(LessThanRunningSuccess(5))), vec![Action(Inc)]); - let mut state = State::new(after); + let mut state = BT::new(after, ()); let (a, s, dt) = tick(a, 0.0, &mut state); @@ -459,7 +428,7 @@ fn test_repeat_sequence_double_running() { Action(LessThan(0)), // failure ], ); - let mut state = State::new(after); + let mut state = BT::new(after, ()); let mut current_value = 0; loop { @@ -489,7 +458,7 @@ fn test_repeat_sequence2() { Action(Dec), // success... 2 ], ); - let mut state = State::new(after); + let mut state = BT::new(after, ()); let mut current_value = 0; let mut current_status; @@ -523,7 +492,7 @@ fn test_repeat_sequence3() { Action(Dec), ], ); - let mut state = State::new(after); + let mut state = BT::new(after, ()); let mut current_value = 0; let mut current_status; @@ -559,7 +528,7 @@ fn test_repeat_sequence_nested() { dec2, // -2 ], // == 3 ); - let mut state = State::new(after); + let mut state = BT::new(after, ()); let mut current_value = 0; let mut current_status; @@ -586,7 +555,7 @@ fn test_repeat_sequence_fail() { Box::new(Action(LessThanRunningSuccess(5))), vec![Action(Dec), Action(LessThan(0))], ); - let mut state = State::new(after); + let mut state = BT::new(after, ()); let (a, s, dt) = tick(a, 0.0, &mut state); assert_eq!(a, 3); assert_eq!(s, Failure); @@ -603,7 +572,7 @@ fn test_repeat_sequence_timed() { Box::new(Action(LessThanRunningSuccess(steps))), vec![Wait(time_step), Action(Inc)], ); - let mut state = State::new(after); + let mut state = BT::new(after, ()); // increment 3 times let (a, s, dt) = tick(a, time_step * 3.0, &mut state); @@ -622,5 +591,5 @@ fn test_repeat_sequence_timed() { fn test_repeat_sequence_empty() { let after = WhileAll(Box::new(Action(LessThanRunningSuccess(0))), vec![]); // panics because no behaviors... - let _state = State::new(after); + let _state = BT::new(after, ()); } diff --git a/bonsai/tests/dynamic_behavior_tests.rs b/bonsai/tests/dynamic_behavior_tests.rs index 4c77bee..f682ee7 100644 --- a/bonsai/tests/dynamic_behavior_tests.rs +++ b/bonsai/tests/dynamic_behavior_tests.rs @@ -1,5 +1,5 @@ use crate::dynamic_behavior_tests::TestActions::{DynamicWait, Inc}; -use bonsai_bt::{Action, ActionArgs, Event, State, Success, UpdateArgs, Wait, While, RUNNING}; +use bonsai_bt::{Action, ActionArgs, Event, Success, UpdateArgs, Wait, While, BT, RUNNING}; type Times = Vec; /// Some test actions. @@ -12,37 +12,33 @@ enum TestActions { } // A test state machine that can increment and decrement. -fn tick(mut acc: usize, dt: f64, t: &mut f64, counter: &mut usize, state: &mut State) -> usize { +fn tick(mut acc: usize, dt: f64, t: &mut f64, counter: &mut usize, state: &mut BT) -> usize { let e: Event = UpdateArgs { dt }.into(); - let (_s, _t) = state.tick( - &e, - &mut (), - &mut |args: ActionArgs, _| match args.action { - Inc => { - acc += 1; - (Success, args.dt) + let (_s, _t) = state.tick(&e, &mut |args: ActionArgs, _| match args.action { + Inc => { + acc += 1; + (Success, args.dt) + } + DynamicWait(times) => { + // reset dynamic timer + if *counter >= times.len() { + *counter = 0 } - DynamicWait(times) => { - // reset dynamic timer - if *counter >= times.len() { - *counter = 0 - } - let wait_t = times[counter.to_owned()]; + let wait_t = times[counter.to_owned()]; - if *t + dt >= wait_t { - let time_overdue = *t + dt - wait_t; - *counter += 1; - *t = -dt; - (Success, time_overdue) - } else { - *t += dt; - RUNNING - } + if *t + dt >= wait_t { + let time_overdue = *t + dt - wait_t; + *counter += 1; + *t = -dt; + (Success, time_overdue) + } else { + *t += dt; + RUNNING } - }, - ); + } + }); acc } @@ -56,7 +52,7 @@ fn test_alter_wait_time() { Box::new(Wait(50.0)), vec![Action(DynamicWait(vec![1.0, 2.0, 3.0])), Action(Inc)], ); - let mut state = State::new(rep); + let mut state = BT::new(rep, ()); // time passed=1.0 let a = tick(a, 1.0, &mut timer, &mut counter, &mut state);