behaviortree_core/behavior_traits.rs
1// Copyright © 2026 Stephan Kunz
2//! Core behavior traits.
3
4use alloc::boxed::Box;
5use core::{any::Any, ops::Range};
6
7use dataport::PortList;
8#[cfg(feature = "std")]
9use libloading::Library;
10use tinyscript::SharedRuntime;
11
12#[cfg(feature = "std")]
13use crate::Arc;
14use crate::{
15 BehaviorCreationFn, BehaviorResult, ConstString, behavior_data::BehaviorData, behavior_description::BehaviorDescription,
16 behavior_kind::BehaviorKind, behavior_state::BehaviorState, error::Error, tree::BehaviorTreeElementList,
17};
18
19/// Supertrait for execution of a [`Behavior`].
20/// The contained functions are generated by the derive macros.
21pub trait BehaviorExecution: Any + Behavior {
22 /// Dynamic downcasting.
23 fn as_any(&self) -> &dyn Any;
24
25 /// Mutable dynamic downcasting.
26 fn as_any_mut(&mut self) -> &mut dyn Any;
27
28 /// Get the [`BehaviorKind`] of the behavior.
29 fn kind(&self) -> BehaviorKind;
30
31 /// Access the [`PortList`]
32 fn portlist(&self) -> &dyn PortList;
33
34 /// Access the [`PortList`]
35 fn portlist_mut(&mut self) -> &mut dyn PortList;
36}
37
38/// Defines the methods common to all behaviors.
39/// These methods are available when traversing a behavior tree.
40#[async_trait::async_trait]
41pub trait Behavior: Send + Sync {
42 /// Method called during stop/cancel/halt of a behavior,
43 /// intended to reset the internal fields of your behavior.
44 ///
45 /// It is not necessary to care about children and maintaining state,
46 /// which at this point has already be done by the tree.
47 ///
48 /// Default implementation does nothing.
49 /// # Errors
50 /// - if something prevents stopping the behavior properly
51 fn on_halt(&mut self) -> Result<(), Error> {
52 Ok(())
53 }
54
55 /// Method is called before starting to tick a behavior,
56 /// intended to do preliminary stuff for your behavior.
57 ///
58 /// In general it is not necessary to care about children
59 /// and maintaining state, which will be done by the
60 /// default `start()` method.
61 ///
62 /// Default implementation does nothing.
63 /// # Errors
64 /// - if something prevents starting the behavior properly
65 fn on_start(
66 &mut self,
67 _behavior: &mut BehaviorData,
68 _children: &mut BehaviorTreeElementList,
69 _runtime: &SharedRuntime,
70 ) -> Result<(), Error> {
71 Ok(())
72 }
73
74 /// Method is called on first tick of a behavior instead of `tick()`.
75 /// If this method returns [`BehaviorState::Running`], the
76 /// behavior becomes asynchronous.
77 ///
78 /// Default implementation calls `on_start(...)` and then tick(...).
79 /// # Errors
80 /// - if something prevents starting the behavior properly
81 async fn start(
82 &mut self,
83 behavior: &mut BehaviorData,
84 children: &mut BehaviorTreeElementList,
85 runtime: &SharedRuntime,
86 ) -> BehaviorResult {
87 self.on_start(behavior, children, runtime)?;
88 self.tick(behavior, children, runtime).await
89 }
90
91 /// Method to tick a behavior.
92 /// # Errors
93 async fn tick(
94 &mut self,
95 behavior: &mut BehaviorData,
96 children: &mut BehaviorTreeElementList,
97 runtime: &SharedRuntime,
98 ) -> BehaviorResult;
99
100 /// Method to halt a behavior.
101 ///
102 /// Default implementation calls `children.halt(...)` and then `self.on_halt(...)`.
103 /// # Errors
104 fn halt(
105 &mut self,
106 _behavior: &mut BehaviorData,
107 children: &mut BehaviorTreeElementList,
108 runtime: &SharedRuntime,
109 ) -> BehaviorResult {
110 children.halt(runtime)?;
111 self.on_halt()?;
112 Ok(BehaviorState::Idle)
113 }
114}
115
116// Methods to be provided by behavior factories/registries.
117pub trait BehaviorRegistry {
118 /// Add a behavior to the registry
119 /// # Errors
120 /// - if the behavior entry already exists
121 fn add_behavior(&mut self, desc: BehaviorDescription, creation_fn: Box<BehaviorCreationFn>) -> Result<(), Error>;
122
123 /// Add a behavior tree definition to the registry.
124 /// # Errors
125 /// - if the behavior tree definition is already registered.
126 fn add_tree_defintion(&mut self, id: &str, tree_definition: ConstString, range: Range<usize>) -> Result<(), Error>;
127 /// Get a reference to the registered libraries.
128 /// Typically these are cloned to ensure their existence during further operation.
129 #[cfg(feature = "std")]
130 #[must_use]
131 fn libraries(&self) -> &alloc::vec::Vec<Arc<Library>>;
132
133 /// Get a reference to the prepared scripting runtime.
134 /// Typically this is cloned to be used with its registered extensions.
135 #[must_use]
136 fn runtime(&self) -> &tinyscript::Runtime;
137
138 /// Register an enums key/value pair.
139 /// # Errors
140 /// - if the key is already used
141 fn register_enum_tuple(&mut self, key: &str, value: i8) -> Result<(), Error>;
142}