use crate::status::Status::*;
use crate::Float;
use crate::{event::UpdateEvent, state::State, ActionArgs, Behavior, Status, RUNNING};
pub struct SequenceArgs<'a, A, E, F, B> {
pub select: bool,
pub upd: Option<Float>,
pub seq: &'a [Behavior<A>],
pub i: &'a mut usize,
pub cursor: &'a mut Box<State<A>>,
pub e: &'a E,
pub blackboard: &'a mut B,
pub f: &'a mut F,
}
pub fn sequence<A, E, F, B>(args: SequenceArgs<A, E, F, B>) -> (Status, Float)
where
A: Clone,
E: UpdateEvent,
F: FnMut(ActionArgs<E, A>, &mut B) -> (Status, Float),
{
let SequenceArgs {
select,
upd,
seq,
i,
cursor,
e,
blackboard,
f,
} = args;
let (status, inv_status) = if select {
(Status::Failure, Status::Success)
} else {
(Status::Success, Status::Failure)
};
let mut remaining_dt = upd.unwrap_or(0.0);
let mut remaining_e;
while *i < seq.len() {
match cursor.tick(
match upd {
Some(_) => {
remaining_e = UpdateEvent::from_dt(remaining_dt, e).unwrap();
&remaining_e
}
_ => e,
},
blackboard,
f,
) {
(Running, _) => {
break;
}
(s, new_dt) if s == inv_status => {
return (inv_status, new_dt);
}
(s, new_dt) if s == status => {
remaining_dt = match upd {
Some(_) => new_dt,
_ => {
if *i == seq.len() - 1 {
return (status, new_dt);
} else {
*i += 1;
**cursor = State::new(seq[*i].clone());
return RUNNING;
}
}
}
}
_ => unreachable!(),
};
*i += 1;
if *i >= seq.len() {
return (status, remaining_dt);
}
**cursor = State::new(seq[*i].clone());
}
RUNNING
}