Skip to main content

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}