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}