Skip to content

Commit 27494b6

Browse files
authored
feat: add f32 feature (#48)
- Add `f32` feature - f64 as default precision - Use `Float` type for `f32` and `f64`
1 parent 8cd64f5 commit 27494b6

17 files changed

Lines changed: 89 additions & 53 deletions

bonsai/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ serde = { version = "1.0.137", features = ["derive"], optional = true }
2424

2525
[features]
2626
visualize = ["dep:petgraph"]
27+
f32 = []
2728

2829
[dev-dependencies]
2930
serde_json = { version = "1.0.81" }

bonsai/src/behavior.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#[cfg(feature = "serde")]
22
use serde::{Deserialize, Serialize};
33

4+
use crate::Float;
5+
46
/// Describes a behavior.
57
///
68
/// This is used for more complex event logic.
@@ -10,8 +12,8 @@ use serde::{Deserialize, Serialize};
1012
pub enum Behavior<A> {
1113
/// Waits an amount of time before continuing
1214
///
13-
/// f64: Time in seconds
14-
Wait(f64),
15+
/// Float: Time in seconds
16+
Wait(Float),
1517
/// Wait forever.
1618
WaitForever,
1719
/// A high level description of an action.
@@ -131,20 +133,23 @@ pub enum Behavior<A> {
131133
#[cfg(test)]
132134
#[cfg(feature = "serde")]
133135
mod tests {
134-
use crate::Behavior::{self, Action, Sequence, Wait, WaitForever, WhenAny, While};
136+
use crate::{
137+
Behavior::{self, Action, Sequence, Wait, WaitForever, WhenAny, While},
138+
Float,
139+
};
135140

136141
#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
137142
pub(crate) enum EnemyAction {
138143
/// Circles forever around target pos.
139144
Circling,
140145
/// Waits until player is within distance.
141-
PlayerWithinDistance(f64),
146+
PlayerWithinDistance(Float),
142147
/// Fly toward player.
143148
FlyTowardPlayer,
144149
/// Waits until player is far away from target.
145-
PlayerFarAwayFromTarget(f64),
150+
PlayerFarAwayFromTarget(Float),
146151
/// Makes player loose more blood.
147-
AttackPlayer(f64),
152+
AttackPlayer(Float),
148153
}
149154

150155
#[test]

bonsai/src/bt.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::fmt::Debug;
22

3-
use crate::{state::State, ActionArgs, Behavior, Status, UpdateEvent};
3+
use crate::{state::State, ActionArgs, Behavior, Float, Status, UpdateEvent};
44

55
#[cfg(feature = "serde")]
66
use serde::{Deserialize, Serialize};
@@ -45,15 +45,15 @@ impl<A: Clone, B> BT<A, B> {
4545
/// Passes event, delta time in seconds, action and state to closure.
4646
/// The closure should return a status and remaining delta time.
4747
///
48-
/// return: (Status, f64)
48+
/// return: (Status, Float)
4949
/// function returns the result of the tree traversal, and how long
5050
/// it actually took to complete the traversal and propagate the
5151
/// results back up to the root node
5252
#[inline]
53-
pub fn tick<E, F>(&mut self, e: &E, f: &mut F) -> Option<(Status, f64)>
53+
pub fn tick<E, F>(&mut self, e: &E, f: &mut F) -> Option<(Status, Float)>
5454
where
5555
E: UpdateEvent,
56-
F: FnMut(ActionArgs<E, A>, &mut B) -> (Status, f64),
56+
F: FnMut(ActionArgs<E, A>, &mut B) -> (Status, Float),
5757
{
5858
if self.finished {
5959
return None;

bonsai/src/event.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
1010
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1111
pub struct UpdateArgs {
1212
/// Delta time in seconds.
13-
pub dt: f64,
13+
pub dt: Float,
1414
}
1515

1616
impl UpdateArgs {
@@ -54,7 +54,7 @@ pub trait UpdateEvent: Sized {
5454
/// Creates an update event.
5555
fn from_update_args(args: &UpdateArgs, old_event: &Self) -> Option<Self>;
5656
/// Creates an update event with delta time.
57-
fn from_dt(dt: f64, old_event: &Self) -> Option<Self> {
57+
fn from_dt(dt: Float, old_event: &Self) -> Option<Self> {
5858
UpdateEvent::from_update_args(&UpdateArgs { dt }, old_event)
5959
}
6060
/// Calls closure if this is an update event.
@@ -84,6 +84,8 @@ impl UpdateEvent for Event {
8484

8585
use std::time::Instant;
8686

87+
use crate::Float;
88+
8789
/// A monotonic clock/timer that can be used to keep track
8890
/// of the time increments (delta time) between tick/tree traversals
8991
/// and the total duration since the behavior tree was first invoked/traversed
@@ -101,18 +103,24 @@ impl Timer {
101103
}
102104

103105
/// Compute duration since timer started
104-
pub fn duration_since_start(&self) -> f64 {
106+
pub fn duration_since_start(&self) -> Float {
105107
let new_now: Instant = Instant::now();
106108
let duration = new_now.duration_since(self.start);
107-
duration.as_secs_f64()
109+
#[cfg(feature = "f32")]
110+
return duration.as_secs_f32();
111+
#[cfg(not(feature = "f32"))]
112+
return duration.as_secs_f64();
108113
}
109114

110115
/// Compute time difference last invocation of `get_dt()` function
111-
pub fn get_dt(&mut self) -> f64 {
116+
pub fn get_dt(&mut self) -> Float {
112117
let new_now: Instant = Instant::now();
113118
let duration = new_now.duration_since(self.now);
114119
self.now = new_now;
115-
duration.as_secs_f64()
120+
#[cfg(feature = "f32")]
121+
return duration.as_secs_f32();
122+
#[cfg(not(feature = "f32"))]
123+
return duration.as_secs_f64();
116124
}
117125
}
118126

bonsai/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,9 @@ mod when_all;
137137

138138
#[cfg(feature = "visualize")]
139139
mod visualizer;
140+
141+
#[cfg(feature = "f32")]
142+
pub type Float = f32;
143+
144+
#[cfg(not(feature = "f32"))]
145+
pub type Float = f64;

bonsai/src/sequence.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use crate::status::Status::*;
2+
use crate::Float;
23
use crate::{event::UpdateEvent, state::State, ActionArgs, Behavior, Status, RUNNING};
34

45
pub struct SequenceArgs<'a, A, E, F, B> {
56
pub select: bool,
6-
pub upd: Option<f64>,
7+
pub upd: Option<Float>,
78
pub seq: &'a [Behavior<A>],
89
pub i: &'a mut usize,
910
pub cursor: &'a mut Box<State<A>>,
@@ -16,11 +17,11 @@ pub struct SequenceArgs<'a, A, E, F, B> {
1617
//
1718
// `Sequence` fails if any fails and succeeds when all succeeds.
1819
// `Select` succeeds if any succeeds and fails when all fails.
19-
pub fn sequence<A, E, F, B>(args: SequenceArgs<A, E, F, B>) -> (Status, f64)
20+
pub fn sequence<A, E, F, B>(args: SequenceArgs<A, E, F, B>) -> (Status, Float)
2021
where
2122
A: Clone,
2223
E: UpdateEvent,
23-
F: FnMut(ActionArgs<E, A>, &mut B) -> (Status, f64),
24+
F: FnMut(ActionArgs<E, A>, &mut B) -> (Status, Float),
2425
{
2526
let SequenceArgs {
2627
select,

bonsai/src/state.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ use crate::sequence::{sequence, SequenceArgs};
33
use crate::state::State::*;
44
use crate::status::Status::*;
55
use crate::when_all::when_all;
6-
use crate::{Behavior, Status};
6+
use crate::{Behavior, Float, Status};
77
use std::fmt::Debug;
88

99
#[cfg(feature = "serde")]
1010
use serde::{Deserialize, Serialize};
1111

1212
/// The action is still running, and thus the action consumes
1313
/// all the remaining delta time for the tick
14-
pub const RUNNING: (Status, f64) = (Running, 0.0);
14+
pub const RUNNING: (Status, Float) = (Running, 0.0);
1515

1616
/// The arguments in the action callback.
1717
pub struct ActionArgs<'a, E: 'a, A: 'a> {
@@ -20,7 +20,7 @@ pub struct ActionArgs<'a, E: 'a, A: 'a> {
2020
/// The remaining delta time. When one action terminates,
2121
/// it can consume some of dt and the remaining is passed
2222
/// onto the next action.
23-
pub dt: f64,
23+
pub dt: Float,
2424
/// The action running.
2525
pub action: &'a A,
2626
}
@@ -36,7 +36,7 @@ pub(crate) enum State<A> {
3636
/// Ignores failures and always return `Success`.
3737
AlwaysSucceed(Box<State<A>>),
3838
/// Keeps track of waiting for a period of time before continuing.
39-
Wait { time_to_wait: f64, elapsed_time: f64 },
39+
Wait { time_to_wait: Float, elapsed_time: Float },
4040
/// Waits forever.
4141
WaitForever,
4242
/// Keeps track of an `If` behavior.
@@ -196,14 +196,14 @@ impl<A: Clone> State<A> {
196196
/// Passes event, delta time in seconds, action and state to closure.
197197
/// The closure should return a status and remaining delta time.
198198
///
199-
/// return: (Status, f64)
199+
/// return: (Status, Float)
200200
/// function returns the result of the tree traversal, and how long
201201
/// it actually took to complete the traversal and propagate the
202202
/// results back up to the root node
203-
pub fn tick<E, F, B>(&mut self, e: &E, blackboard: &mut B, f: &mut F) -> (Status, f64)
203+
pub fn tick<E, F, B>(&mut self, e: &E, blackboard: &mut B, f: &mut F) -> (Status, Float)
204204
where
205205
E: UpdateEvent,
206-
F: FnMut(ActionArgs<E, A>, &mut B) -> (Status, f64),
206+
F: FnMut(ActionArgs<E, A>, &mut B) -> (Status, Float),
207207
{
208208
let upd = e.update(|args| Some(args.dt)).unwrap_or(None);
209209

@@ -413,7 +413,7 @@ impl<A: Clone> State<A> {
413413
) => {
414414
// println!("In AfterState: {}", next_success_index);
415415
// Get the least delta time left over.
416-
let mut min_dt = f64::MAX;
416+
let mut min_dt = Float::MAX;
417417
for (j, item) in states.iter_mut().enumerate().skip(*next_success_index) {
418418
match item.tick(e, blackboard, f) {
419419
(Running, _) => {

bonsai/src/visualizer.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
#![allow(dead_code, unused_imports, unused_variables)]
2-
use crate::{state::State, Behavior, Select, Sequence, BT};
2+
use crate::{state::State, Behavior, Float, Select, Sequence, BT};
33
use petgraph::{graph::Graph, stable_graph::NodeIndex, Direction::Outgoing};
44
use std::{collections::VecDeque, fmt::Debug};
55

66
#[derive(Debug, Clone)]
77
pub(crate) enum NodeType<A> {
88
Root,
9-
Wait(f64),
9+
Wait(Float),
1010
WaitForever,
1111
Action(A),
1212
Invert,
@@ -152,7 +152,7 @@ mod tests {
152152
}
153153

154154
// A test state machine that can increment and decrement.
155-
fn tick(mut acc: i32, dt: f64, bt: &mut BT<TestActions, HashMap<String, i32>>) -> (i32, Status, f64) {
155+
fn tick(mut acc: i32, dt: Float, bt: &mut BT<TestActions, HashMap<String, i32>>) -> (i32, Status, Float) {
156156
let e: Event = UpdateArgs { dt }.into();
157157
let (s, t) = bt
158158
.tick(&e, &mut |args, blackboard| match args.action {

bonsai/src/when_all.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::status::Status::*;
2+
use crate::Float;
23
use crate::{event::UpdateEvent, state::State, ActionArgs, Status, RUNNING};
34

45
// `WhenAll` and `WhenAny` share same algorithm.
@@ -8,16 +9,16 @@ use crate::{event::UpdateEvent, state::State, ActionArgs, Status, RUNNING};
89
#[rustfmt::skip]
910
pub fn when_all<A, E, F, B>(
1011
any: bool,
11-
upd: Option<f64>,
12+
upd: Option<Float>,
1213
cursors: &mut [Option<State<A>>],
1314
e: &E,
1415
f: &mut F,
1516
blackboard: &mut B,
16-
) -> (Status, f64)
17+
) -> (Status, Float)
1718
where
1819
A: Clone,
1920
E: UpdateEvent,
20-
F: FnMut(ActionArgs<E, A>, &mut B) -> (Status, f64),
21+
F: FnMut(ActionArgs<E, A>, &mut B) -> (Status, Float),
2122
{
2223
let (status, inv_status) = if any {
2324
// `WhenAny`
@@ -27,7 +28,7 @@ where
2728
(Status::Success, Status::Failure)
2829
};
2930
// Get the least delta time left over.
30-
let mut min_dt = f64::MAX;
31+
let mut min_dt = Float::MAX;
3132
// Count number of terminated events.
3233
let mut terminated = 0;
3334
for cur in cursors.iter_mut() {

bonsai/tests/behavior_tests.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::behavior_tests::TestActions::{Dec, Inc, LessThan, LessThanRunningSuccess};
22
use bonsai_bt::{
3-
Action, ActionArgs, After, AlwaysSucceed, Event, Failure, If, Invert, Select, Sequence, Status::Running, Success,
4-
UpdateArgs, Wait, WaitForever, WhenAll, While, WhileAll, BT,
3+
Action, ActionArgs, After, AlwaysSucceed, Event, Failure, Float, If, Invert, Select, Sequence, Status::Running,
4+
Success, UpdateArgs, Wait, WaitForever, WhenAll, While, WhileAll, BT,
55
};
66

77
/// Some test actions.
@@ -18,7 +18,7 @@ enum TestActions {
1818
}
1919

2020
// A test state machine that can increment and decrement.
21-
fn tick(mut acc: i32, dt: f64, state: &mut BT<TestActions, ()>) -> (i32, bonsai_bt::Status, f64) {
21+
fn tick(mut acc: i32, dt: Float, state: &mut BT<TestActions, ()>) -> (i32, bonsai_bt::Status, Float) {
2222
let e: Event = UpdateArgs { dt }.into();
2323
println!("acc {}", acc);
2424
let (s, t) = state
@@ -59,7 +59,7 @@ fn tick(mut acc: i32, dt: f64, state: &mut BT<TestActions, ()>) -> (i32, bonsai_
5959
}
6060

6161
// A test state machine that can increment and decrement.
62-
fn tick_with_ref(acc: &mut i32, dt: f64, state: &mut BT<TestActions, ()>) {
62+
fn tick_with_ref(acc: &mut i32, dt: Float, state: &mut BT<TestActions, ()>) {
6363
let e: Event = UpdateArgs { dt }.into();
6464

6565
state

0 commit comments

Comments
 (0)