npc_engine_core/behavior.rs
1/*
2 * SPDX-License-Identifier: Apache-2.0 OR MIT
3 * © 2020-2022 ETH Zurich and other contributors, see AUTHORS.txt for details
4 */
5
6use crate::{AgentId, Domain, StateDiffRef, Task};
7
8/// A possibly-recursive set of possible tasks.
9///
10/// You need to implement at least two methods: [is_valid](Self::is_valid) and [add_own_tasks](Self::add_own_tasks).
11pub trait Behavior<D: Domain>: 'static {
12 /// Returns if the behavior is valid for the given agent in the given world state.
13 fn is_valid(&self, tick: u64, state: StateDiffRef<D>, agent: AgentId) -> bool;
14
15 /// Collects valid tasks for the given agent in the given world state.
16 #[allow(unused)]
17 fn add_own_tasks(
18 &self,
19 tick: u64,
20 state: StateDiffRef<D>,
21 agent: AgentId,
22 tasks: &mut Vec<Box<dyn Task<D>>>,
23 );
24
25 /// Returns dependent behaviors.
26 fn get_dependent_behaviors(&self) -> &'static [&'static dyn Behavior<D>] {
27 &[]
28 }
29
30 /// Helper method to recursively collect all valid tasks for the given agent in the given world state.
31 ///
32 /// It will not do anything if the behavior is invalid at that point.
33 fn add_tasks(
34 &self,
35 tick: u64,
36 state: StateDiffRef<D>,
37 agent: AgentId,
38 tasks: &mut Vec<Box<dyn Task<D>>>,
39 ) {
40 if !self.is_valid(tick, state, agent) {
41 return;
42 }
43 self.add_own_tasks(tick, state, agent, tasks);
44 self.get_dependent_behaviors()
45 .iter()
46 .for_each(|behavior| behavior.add_tasks(tick, state, agent, tasks));
47 }
48}