1use crate::status::Status::*;
2use crate::tracer::{first_child_id, next_sibling_id, NodeMeta, Tracer};
3use crate::Float;
4use crate::{event::UpdateEvent, state::State, ActionArgs, Behavior, Status, RUNNING};
5
6pub struct SequenceArgs<'a, A, E, F, B, T> {
7 pub select: bool,
8 pub upd: Option<Float>,
9 pub seq: &'a [Behavior<A>],
10 pub i: &'a mut usize,
11 pub cursor: &'a mut Box<State<A>>,
12 pub e: &'a E,
13 pub blackboard: &'a mut B,
14 pub f: &'a mut F,
15 pub parent_id: usize,
16 pub metas: &'a [NodeMeta],
17 pub tracer: &'a mut T,
18}
19
20pub fn sequence<A, E, F, B, T>(args: SequenceArgs<A, E, F, B, T>) -> (Status, Float)
25where
26 A: Clone,
27 E: UpdateEvent,
28 F: FnMut(ActionArgs<E, A>, &mut B) -> (Status, Float),
29 T: Tracer,
30{
31 let SequenceArgs {
32 select,
33 upd,
34 seq,
35 i,
36 cursor,
37 e,
38 blackboard,
39 f,
40 parent_id,
41 metas,
42 tracer,
43 } = args;
44
45 let (status, inv_status) = if select {
46 (Status::Failure, Status::Success)
48 } else {
49 (Status::Success, Status::Failure)
51 };
52 let mut child_id = first_child_id::<T>(parent_id);
53 if T::IS_RECORDING {
54 for _ in 0..*i {
55 child_id = next_sibling_id::<T>(metas, child_id);
56 }
57 }
58 let mut remaining_dt = upd.unwrap_or(0.0);
59 let mut remaining_e;
60 while *i < seq.len() {
61 match cursor.tick(
62 child_id,
63 metas,
64 match upd {
65 Some(_) => {
66 remaining_e = UpdateEvent::from_dt(remaining_dt, e).unwrap();
67 &remaining_e
68 }
69 _ => e,
70 },
71 blackboard,
72 f,
73 tracer,
74 ) {
75 (Running, _) => {
76 break;
77 }
78 (s, new_dt) if s == inv_status => {
79 return (inv_status, new_dt);
80 }
81 (s, new_dt) if s == status => {
82 remaining_dt = match upd {
83 Some(_) => new_dt,
85 _ => {
88 if *i == seq.len() - 1 {
89 return (status, new_dt);
90 } else {
91 *i += 1;
92 **cursor = State::new(seq[*i].clone());
95 return RUNNING;
96 }
97 }
98 }
99 }
100 _ => unreachable!(),
101 };
102 *i += 1;
103 if T::IS_RECORDING {
104 child_id = next_sibling_id::<T>(metas, child_id);
105 }
106 if *i >= seq.len() {
109 return (status, remaining_dt);
110 }
111 **cursor = State::new(seq[*i].clone());
114 }
115 RUNNING
116}
117
118pub struct MemorylessSequenceArgs<'a, A, E, F, B, T> {
119 pub select: bool,
120 pub upd: Option<Float>,
121 pub seq: &'a [Behavior<A>],
122 pub cursor: &'a mut Box<State<A>>,
123 pub e: &'a E,
124 pub blackboard: &'a mut B,
125 pub f: &'a mut F,
126 pub parent_id: usize,
127 pub metas: &'a [NodeMeta],
128 pub tracer: &'a mut T,
129}
130
131#[inline]
143pub fn memoryless_sequence<A, E, F, B, T>(args: MemorylessSequenceArgs<A, E, F, B, T>) -> (Status, Float)
144where
145 A: Clone,
146 E: UpdateEvent,
147 F: FnMut(ActionArgs<E, A>, &mut B) -> (Status, Float),
148 T: Tracer,
149{
150 let MemorylessSequenceArgs {
151 select,
152 upd,
153 seq,
154 cursor,
155 e,
156 blackboard,
157 f,
158 parent_id,
159 metas,
160 tracer,
161 } = args;
162
163 let initial_dt = upd.unwrap_or(0.0);
164
165 if seq.is_empty() {
166 return if select {
167 (Status::Failure, initial_dt)
168 } else {
169 (Status::Success, initial_dt)
170 };
171 }
172
173 let (terminal_status, short_circuit_status) = if select {
174 (Status::Failure, Status::Success)
175 } else {
176 (Status::Success, Status::Failure)
177 };
178
179 let mut child_id = first_child_id::<T>(parent_id);
180 let mut remaining_dt = initial_dt;
181 let mut remaining_e;
182
183 for child in seq {
184 **cursor = State::new(child.clone());
186
187 let ev = match upd {
188 Some(_) => {
189 remaining_e = UpdateEvent::from_dt(remaining_dt, e).unwrap();
190 &remaining_e
191 }
192 None => e,
193 };
194
195 match cursor.tick(child_id, metas, ev, blackboard, f, tracer) {
196 (Running, _) => return RUNNING,
197 (s, dt) if s == short_circuit_status => return (s, dt),
198 (s, dt) if s == terminal_status => {
199 if upd.is_some() {
200 remaining_dt = dt;
201 }
202 }
203 _ => unreachable!(),
204 }
205
206 if T::IS_RECORDING {
207 child_id = next_sibling_id::<T>(metas, child_id);
208 }
209 }
210
211 (terminal_status, remaining_dt)
212}