use crate::status::Status::*;
use crate::Float;
use crate::{event::UpdateEvent, state::State, ActionArgs, Status, RUNNING};
#[rustfmt::skip]
pub fn when_all<A, E, F, B>(
any: bool,
upd: Option<Float>,
cursors: &mut [Option<State<A>>],
e: &E,
f: &mut F,
blackboard: &mut B,
) -> (Status, Float)
where
A: Clone,
E: UpdateEvent,
F: FnMut(ActionArgs<E, A>, &mut B) -> (Status, Float),
{
let (status, inv_status) = if any {
(Status::Failure, Status::Success)
} else {
(Status::Success, Status::Failure)
};
let mut min_dt = Float::MAX;
let mut terminated = 0;
for cur in cursors.iter_mut() {
match *cur {
None => {}
Some(ref mut cur) => {
match cur.tick(e, blackboard, f) {
(Running, _) => {
continue;
}
(s, new_dt) if s == inv_status => {
return (inv_status, new_dt);
}
(s, new_dt) if s == status => {
min_dt = min_dt.min(new_dt);
}
_ => unreachable!(),
}
}
}
terminated += 1;
*cur = None;
}
#[allow(clippy::manual_unwrap_or)]
match terminated {
0 if cursors.is_empty() => (
status,
match upd {
Some(dt) => dt,
_ => 0.0,
},
),
n if cursors.len() == n => (status, min_dt),
_ => RUNNING,
}
}