Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reset BT if tick returns Success or Failure. #44

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions bonsai/src/bt.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -14,7 +14,7 @@ use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct BT<A, B> {
/// constructed behavior tree
pub state: State<A>,
state: State<A>,
/// keep the initial state
initial_behavior: Behavior<A>,
/// The data storage shared by all nodes in the tree. This is generally
Expand All @@ -35,7 +35,8 @@ impl<A: Clone, B> BT<A, B> {
}
}

/// 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.
Expand All @@ -53,7 +54,13 @@ impl<A: Clone, B> BT<A, B> {
E: UpdateEvent,
F: FnMut(ActionArgs<E, A>, &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
Expand All @@ -62,12 +69,6 @@ impl<A: Clone, B> BT<A, B> {
&mut self.bb
}

/// Retrieve a mutable reference to the internal state
/// of the Behavior Tree
pub fn get_state(bt: &mut BT<A, B>) -> &mut State<A> {
&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
Expand Down
2 changes: 1 addition & 1 deletion bonsai/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion bonsai/src/sequence.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
78 changes: 39 additions & 39 deletions bonsai/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<A> {
pub(crate) enum State<A> {
/// Executes an action.
ActionState(A),
Action(A),
/// Converts `Success` into `Failure` and vice versa.
InvertState(Box<State<A>>),
Invert(Box<State<A>>),
/// Ignores failures and always return `Success`.
AlwaysSucceedState(Box<State<A>>),
AlwaysSucceed(Box<State<A>>),
/// 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<Behavior<A>>,
/// The behavior to run if the status is a failure.
Expand All @@ -52,7 +52,7 @@ pub enum State<A> {
current_state: Box<State<A>>,
},
/// Keeps track of a `Select` behavior.
SelectState {
Select {
/// The behaviors that will be selected across in order.
behaviors: Vec<Behavior<A>>,
/// The index of the behavior currently being executed.
Expand All @@ -61,7 +61,7 @@ pub enum State<A> {
current_state: Box<State<A>>,
},
/// Keeps track of an `Sequence` behavior.
SequenceState {
Sequence {
/// The behaviors that will be executed in order.
behaviors: Vec<Behavior<A>>,
/// The index of the behavior currently being executed.
Expand All @@ -70,7 +70,7 @@ pub enum State<A> {
current_state: Box<State<A>>,
},
/// 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<State<A>>,
Expand All @@ -82,7 +82,7 @@ pub enum State<A> {
loop_body_state: Box<State<A>>,
},
/// 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.
Expand All @@ -98,12 +98,12 @@ pub enum State<A> {
},
/// Keeps track of a `WhenAll` behavior. As the states finish, they are set
/// to [`None`].
WhenAllState(Vec<Option<State<A>>>),
WhenAll(Vec<Option<State<A>>>),
/// Keeps track of a `WhenAny` behavior. As the states finish, they are set
/// to [`None`].
WhenAnyState(Vec<Option<State<A>>>),
WhenAny(Vec<Option<State<A>>>),
/// 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
Expand All @@ -122,17 +122,17 @@ impl<A: Clone> State<A> {
/// the executing instance of that behavior.
pub fn new(behavior: Behavior<A>) -> 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,
Expand All @@ -141,32 +141,32 @@ impl<A: Clone> State<A> {
}
Behavior::Select(behaviors) => {
let state = State::new(behaviors[0].clone());
State::SelectState {
State::Select {
behaviors,
current_index: 0,
current_state: Box::new(state),
}
}
Behavior::Sequence(behaviors) => {
let state = State::new(behaviors[0].clone());
State::SequenceState {
State::Sequence {
behaviors,
current_index: 0,
current_state: Box::new(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(),
},
Expand All @@ -177,7 +177,7 @@ impl<A: Clone> State<A> {
.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,
Expand Down Expand Up @@ -209,7 +209,7 @@ impl<A: Clone> State<A> {

// double match statements
match (upd, self) {
(_, &mut ActionState(ref action)) => {
(_, &mut Action(ref action)) => {
// println!("In ActionState: {:?}", action);
f(
ActionArgs {
Expand All @@ -220,15 +220,15 @@ impl<A: Clone> State<A> {
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),
(Failure, dt) => (Success, dt),
(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),
Expand All @@ -237,7 +237,7 @@ impl<A: Clone> State<A> {
}
(
Some(dt),
&mut WaitState {
&mut Wait {
time_to_wait,
ref mut elapsed_time,
},
Expand All @@ -254,7 +254,7 @@ impl<A: Clone> State<A> {
}
(
_,
&mut IfState {
&mut If {
ref on_success,
ref on_failure,
ref mut status,
Expand Down Expand Up @@ -301,7 +301,7 @@ impl<A: Clone> State<A> {
}
(
_,
&mut SelectState {
&mut Select {
behaviors: ref seq,
current_index: ref mut i,
current_state: ref mut cursor,
Expand All @@ -322,7 +322,7 @@ impl<A: Clone> State<A> {
}
(
_,
&mut SequenceState {
&mut Sequence {
behaviors: ref seq,
current_index: ref mut i,
current_state: ref mut cursor,
Expand All @@ -343,7 +343,7 @@ impl<A: Clone> State<A> {
}
(
_,
&mut WhileState {
&mut While {
ref mut condition_state,
ref loop_body,
ref mut loop_body_index,
Expand Down Expand Up @@ -394,19 +394,19 @@ impl<A: Clone> State<A> {
}
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,
},
Expand Down Expand Up @@ -443,7 +443,7 @@ impl<A: Clone> State<A> {
}
(
_,
&mut WhileAllState {
&mut WhileAll {
ref mut condition_state,
ref mut check_condition,
ref loop_body,
Expand Down
2 changes: 1 addition & 1 deletion bonsai/src/visualizer.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down
2 changes: 1 addition & 1 deletion bonsai/src/when_all.rs
Original file line number Diff line number Diff line change
@@ -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.
//
Expand Down
Loading
Loading