1use crate::{
2 BehaviorCallback, BehaviorNode, BehaviorNodeContainer, BehaviorResult, Blackboard, Context,
3 Lazy, NumChildren, PortSpec, PortType, Symbol,
4};
5
6pub fn tick_child_node<T>(
7 arg: BehaviorCallback,
8 ctx: &mut Context,
9 node: &mut BehaviorNodeContainer,
10) -> BehaviorResult {
11 std::mem::swap(&mut ctx.blackboard_map, &mut node.blackboard_map);
12 let res = node.node.tick(arg, ctx);
13 std::mem::swap(&mut ctx.blackboard_map, &mut node.blackboard_map);
14 res
15}
16
17pub struct SubtreeNode {
19 blackboard: Blackboard,
21 params: Vec<PortSpec>,
22}
23
24impl SubtreeNode {
25 pub fn new(blackboard: Blackboard, params: Vec<PortSpec>) -> Self {
26 Self { blackboard, params }
27 }
28}
29
30impl BehaviorNode for SubtreeNode {
31 fn provided_ports(&self) -> Vec<PortSpec> {
32 self.params.clone()
33 }
34
35 fn tick(&mut self, arg: BehaviorCallback, ctx: &mut Context) -> BehaviorResult {
36 for param in self
37 .params
38 .iter()
39 .filter(|param| matches!(param.ty, PortType::Input | PortType::InOut))
40 {
41 if let Some(value) = ctx.get_any(param.key) {
42 self.blackboard.insert(param.key, value.clone());
43 }
44 }
45
46 std::mem::swap(&mut self.blackboard, &mut ctx.blackboard);
47 let res = ctx.tick_child(0, arg);
48 std::mem::swap(&mut ctx.blackboard, &mut self.blackboard);
49
50 for param in self
53 .params
54 .iter()
55 .filter(|param| matches!(param.ty, PortType::Output | PortType::InOut))
56 {
57 if let Some(value) = self.blackboard.get(¶m.key) {
58 ctx.set_any(param.key, value.clone());
59 }
60 }
61
62 res.unwrap_or(BehaviorResult::Fail)
63 }
64
65 fn max_children(&self) -> NumChildren {
66 NumChildren::Finite(1)
67 }
68}
69
70#[derive(Default)]
71pub struct SequenceNode {
72 current_child: Option<usize>,
73}
74
75impl BehaviorNode for SequenceNode {
76 fn tick(&mut self, arg: BehaviorCallback, ctx: &mut Context) -> BehaviorResult {
77 let from = self.current_child.unwrap_or(0);
78 for i in from..ctx.num_children() {
79 match ctx.tick_child(i, arg) {
80 Some(BehaviorResult::Fail) => {
81 self.current_child = None;
82 return BehaviorResult::Fail;
83 }
84 Some(BehaviorResult::Running) => {
85 self.current_child = Some(i);
86 return BehaviorResult::Running;
87 }
88 _ => (),
89 }
90 }
91 self.current_child = None;
92 BehaviorResult::Success
93 }
94
95 fn max_children(&self) -> NumChildren {
96 NumChildren::Infinite
97 }
98}
99
100#[derive(Default)]
101pub struct ReactiveSequenceNode;
102
103impl BehaviorNode for ReactiveSequenceNode {
104 fn tick(&mut self, arg: BehaviorCallback, ctx: &mut Context) -> BehaviorResult {
105 for i in 0..ctx.num_children() {
106 match ctx.tick_child(i, arg) {
107 Some(BehaviorResult::Fail) => {
108 return BehaviorResult::Fail;
109 }
110 Some(BehaviorResult::Running) => {
111 return BehaviorResult::Running;
112 }
113 _ => (),
114 }
115 }
116 BehaviorResult::Success
117 }
118
119 fn max_children(&self) -> NumChildren {
120 NumChildren::Infinite
121 }
122}
123
124#[derive(Default)]
125pub struct FallbackNode {
126 current_child: Option<usize>,
127}
128
129impl BehaviorNode for FallbackNode {
130 fn tick(&mut self, arg: BehaviorCallback, ctx: &mut Context) -> BehaviorResult {
131 let from = self.current_child.unwrap_or(0);
132 for i in from..ctx.num_children() {
133 match ctx.tick_child(i, arg) {
134 Some(BehaviorResult::Success) => {
135 self.current_child = None;
136 return BehaviorResult::Success;
137 }
138 Some(BehaviorResult::Running) => {
139 self.current_child = Some(i);
140 return BehaviorResult::Running;
141 }
142 _ => (),
143 }
144 }
145 self.current_child = None;
146 BehaviorResult::Fail
147 }
148
149 fn max_children(&self) -> NumChildren {
150 NumChildren::Infinite
151 }
152}
153
154#[derive(Default)]
155pub struct ReactiveFallbackNode;
156
157impl BehaviorNode for ReactiveFallbackNode {
158 fn tick(&mut self, arg: BehaviorCallback, ctx: &mut Context) -> BehaviorResult {
159 for i in 0..ctx.num_children() {
160 match ctx.tick_child(i, arg) {
161 Some(BehaviorResult::Success) => {
162 return BehaviorResult::Success;
163 }
164 Some(BehaviorResult::Running) => {
165 return BehaviorResult::Running;
166 }
167 _ => (),
168 }
169 }
170 BehaviorResult::Fail
171 }
172
173 fn max_children(&self) -> NumChildren {
174 NumChildren::Infinite
175 }
176}
177
178#[derive(Default)]
179pub struct ForceSuccessNode;
180
181impl BehaviorNode for ForceSuccessNode {
182 fn tick(&mut self, arg: BehaviorCallback, ctx: &mut Context) -> BehaviorResult {
183 match ctx.tick_child(0, arg) {
184 Some(BehaviorResult::Running) => BehaviorResult::Running,
185 Some(_) => BehaviorResult::Success,
186 _ => BehaviorResult::Fail,
187 }
188 }
189
190 fn max_children(&self) -> NumChildren {
191 NumChildren::Finite(1)
192 }
193}
194
195#[derive(Default)]
196pub struct ForceFailureNode(Option<BehaviorNodeContainer>);
197
198impl BehaviorNode for ForceFailureNode {
199 fn tick(&mut self, arg: BehaviorCallback, ctx: &mut Context) -> BehaviorResult {
200 if let Some(ref mut node) = self.0 {
201 std::mem::swap(&mut ctx.blackboard_map, &mut node.blackboard_map);
202 if let BehaviorResult::Running = node.node.tick(arg, ctx) {
203 std::mem::swap(&mut ctx.blackboard_map, &mut node.blackboard_map);
204 return BehaviorResult::Running;
205 }
206 std::mem::swap(&mut ctx.blackboard_map, &mut node.blackboard_map);
207 BehaviorResult::Fail
208 } else {
209 BehaviorResult::Fail
210 }
211 }
212
213 fn max_children(&self) -> NumChildren {
214 NumChildren::Finite(1)
215 }
216}
217
218#[derive(Default)]
219pub struct InverterNode;
220
221impl BehaviorNode for InverterNode {
222 fn tick(&mut self, arg: BehaviorCallback, ctx: &mut Context) -> BehaviorResult {
223 match ctx.tick_child(0, arg) {
224 Some(BehaviorResult::Running) => BehaviorResult::Running,
225 Some(BehaviorResult::Success) => BehaviorResult::Fail,
226 Some(BehaviorResult::Fail) => BehaviorResult::Success,
227 None => BehaviorResult::Fail,
228 }
229 }
230
231 fn max_children(&self) -> NumChildren {
232 NumChildren::Finite(1)
233 }
234}
235
236static N: Lazy<Symbol> = Lazy::new(|| "n".into());
237
238#[derive(Default)]
239pub(super) struct RepeatNode {
240 n: Option<usize>,
241}
242
243impl BehaviorNode for RepeatNode {
244 fn provided_ports(&self) -> Vec<PortSpec> {
245 vec![PortSpec::new_in(*N)]
246 }
247
248 fn tick(&mut self, arg: BehaviorCallback, ctx: &mut Context) -> BehaviorResult {
249 if let Some(current) = self.n.or_else(|| ctx.get_parse::<usize>("n")) {
250 if current == 0 {
251 self.n = None;
252 return BehaviorResult::Success;
253 }
254 match ctx.tick_child(0, arg) {
255 Some(BehaviorResult::Success) => {
256 self.n = Some(current - 1);
257 return BehaviorResult::Running;
258 }
259 Some(BehaviorResult::Running) => return BehaviorResult::Running,
260 Some(res) => {
261 self.n = None;
262 return res;
263 }
264 _ => return BehaviorResult::Fail,
265 }
266 }
267 BehaviorResult::Fail
268 }
269
270 fn max_children(&self) -> NumChildren {
271 NumChildren::Finite(1)
272 }
273}
274
275#[derive(Default)]
276pub(super) struct RetryNode {
277 n: Option<usize>,
278}
279
280impl BehaviorNode for RetryNode {
281 fn provided_ports(&self) -> Vec<PortSpec> {
282 vec![PortSpec::new_in(*N)]
283 }
284
285 fn tick(&mut self, arg: BehaviorCallback, ctx: &mut Context) -> BehaviorResult {
286 if let Some(current) = self.n.or_else(|| ctx.get_parse::<usize>("n")) {
287 if current == 0 {
288 self.n = None;
289 return BehaviorResult::Success;
290 }
291 match ctx.tick_child(0, arg) {
292 Some(BehaviorResult::Fail) => {
293 self.n = Some(current - 1);
294 return BehaviorResult::Running;
295 }
296 Some(BehaviorResult::Running) => return BehaviorResult::Running,
297 Some(res) => {
298 self.n = None;
299 return res;
300 }
301 _ => return BehaviorResult::Fail,
302 }
303 }
304 BehaviorResult::Fail
305 }
306
307 fn max_children(&self) -> NumChildren {
308 NumChildren::Finite(1)
309 }
310}
311
312pub(crate) static VALUE: Lazy<Symbol> = Lazy::new(|| "value".into());
313pub(crate) static OUTPUT: Lazy<Symbol> = Lazy::new(|| "output".into());
314
315pub(crate) struct SetBoolNode;
316
317impl BehaviorNode for SetBoolNode {
318 fn provided_ports(&self) -> Vec<PortSpec> {
319 vec![PortSpec::new_in(*VALUE), PortSpec::new_out(*OUTPUT)]
320 }
321
322 fn tick(&mut self, _arg: BehaviorCallback, ctx: &mut Context) -> BehaviorResult {
323 let result = ctx.get_parse::<bool>(*VALUE);
324 if let Some(value) = result {
325 ctx.set(*OUTPUT, value);
326 BehaviorResult::Success
327 } else {
328 BehaviorResult::Fail
329 }
330 }
331}
332
333pub(crate) static INPUT: Lazy<Symbol> = Lazy::new(|| "input".into());
334
335pub struct IsTrueNode;
336
337impl BehaviorNode for IsTrueNode {
338 fn provided_ports(&self) -> Vec<PortSpec> {
339 vec![PortSpec::new_in(*INPUT)]
340 }
341
342 fn tick(&mut self, _arg: BehaviorCallback, ctx: &mut Context) -> BehaviorResult {
343 if let Some(input) = ctx.get_parse::<bool>(*INPUT) {
344 if input {
345 BehaviorResult::Success
346 } else {
347 BehaviorResult::Fail
348 }
349 } else {
350 BehaviorResult::Fail
351 }
352 }
353}
354
355#[derive(Default)]
356pub struct IfNode {
357 condition_result: Option<BehaviorResult>,
358}
359
360impl BehaviorNode for IfNode {
361 fn tick(&mut self, arg: BehaviorCallback, ctx: &mut Context) -> BehaviorResult {
362 let condition_result = match self.condition_result {
363 Some(BehaviorResult::Running) => ctx.tick_child(0, arg).unwrap_or(BehaviorResult::Fail),
364 Some(res) => res,
365 None => ctx.tick_child(0, arg).unwrap_or(BehaviorResult::Fail),
366 };
367
368 self.condition_result = Some(condition_result);
370
371 if matches!(condition_result, BehaviorResult::Running) {
372 return BehaviorResult::Running;
373 }
374
375 let branch_result = match condition_result {
376 BehaviorResult::Success => ctx.tick_child(1, arg).unwrap_or(BehaviorResult::Fail),
377 BehaviorResult::Fail => {
378 ctx.tick_child(2, arg).unwrap_or(BehaviorResult::Success)
380 }
381 BehaviorResult::Running => BehaviorResult::Running,
382 };
383
384 if !matches!(branch_result, BehaviorResult::Running) {
387 self.condition_result = None;
388 }
389
390 branch_result
391 }
392
393 fn max_children(&self) -> NumChildren {
394 NumChildren::Finite(3)
395 }
396}
397
398#[cfg(test)]
399mod test;