pub trait BehaviorNode:
Send
+ Sync
+ Debug {
// Required method
fn tick<'life0, 'life1, 'async_trait>(
&'life0 mut self,
ctx: &'life1 Context,
) -> Pin<Box<dyn Future<Output = Result<NodeStatus, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
// Provided methods
fn name(&self) -> &str { ... }
fn children_mut(&mut self) -> Vec<&mut dyn BehaviorNode> { ... }
fn reset<'life0, 'async_trait>(
&'life0 mut self,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait { ... }
fn on_init<'life0, 'life1, 'async_trait>(
&'life0 mut self,
ctx: &'life1 Context,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait { ... }
fn on_terminate<'life0, 'life1, 'async_trait>(
&'life0 mut self,
ctx: &'life1 Context,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait { ... }
}Expand description
Core trait that all behavior nodes must implement.
This is the fundamental building block of the behavior system. Everything - from simple actions to complex AI models to composition primitives - implements this trait.
§Design Principles
- Simplicity - One method:
tick() - Async-first - All behaviors are async by default
- Composable - Nodes can be freely combined
- Type-safe - Rust’s type system ensures correctness
§Example
use mecha10_behavior_runtime::prelude::*;
#[derive(Debug)]
struct PrintMessage {
message: String,
}
#[async_trait]
impl BehaviorNode for PrintMessage {
async fn tick(&mut self, ctx: &Context) -> anyhow::Result<NodeStatus> {
println!("{}", self.message);
Ok(NodeStatus::Success)
}
fn name(&self) -> &str {
"print_message"
}
}Required Methods§
Sourcefn tick<'life0, 'life1, 'async_trait>(
&'life0 mut self,
ctx: &'life1 Context,
) -> Pin<Box<dyn Future<Output = Result<NodeStatus, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn tick<'life0, 'life1, 'async_trait>(
&'life0 mut self,
ctx: &'life1 Context,
) -> Pin<Box<dyn Future<Output = Result<NodeStatus, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Execute one tick of the behavior.
This method is called repeatedly by the execution engine. It should:
- Perform one unit of work
- Return quickly (non-blocking)
- Return
NodeStatusto indicate progress
§Arguments
ctx- Execution context with access to messaging, sensors, etc.
§Returns
NodeStatus::Success- Behavior completed successfullyNodeStatus::Failure- Behavior failed (irrecoverable error)NodeStatus::Running- Behavior is still executing (call again)
§Errors
Return an error for exceptional conditions that should halt execution.
For recoverable failures, return Ok(NodeStatus::Failure) instead.
Provided Methods§
Sourcefn name(&self) -> &str
fn name(&self) -> &str
Get the name of this behavior node.
Used for debugging, logging, and monitoring. The default implementation returns the type name.
Sourcefn children_mut(&mut self) -> Vec<&mut dyn BehaviorNode>
fn children_mut(&mut self) -> Vec<&mut dyn BehaviorNode>
Return mutable references to this node’s child behaviors, in the order they should receive lifecycle events.
Leaf nodes have no children and should not override this - the default
implementation returns an empty list. Composite nodes (e.g. SequenceNode,
SelectOrNode, ParallelNode, SubsumptionNode, EnsembleNode) override
this to expose their children, which drives the default on_init/
on_terminate/reset propagation below without each composite having to
hand-roll the same loop.
Sourcefn reset<'life0, 'async_trait>(
&'life0 mut self,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn reset<'life0, 'async_trait>(
&'life0 mut self,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Reset the behavior to its initial state.
Called when the behavior needs to be restarted (e.g., in a loop or
after a failure). The default implementation propagates the reset to
every child returned by children_mut.
Sourcefn on_init<'life0, 'life1, 'async_trait>(
&'life0 mut self,
ctx: &'life1 Context,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn on_init<'life0, 'life1, 'async_trait>(
&'life0 mut self,
ctx: &'life1 Context,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Called when the behavior is first initialized.
Use this for one-time setup like loading models, establishing connections, etc.
The default implementation propagates on_init to every child returned by
children_mut.
Sourcefn on_terminate<'life0, 'life1, 'async_trait>(
&'life0 mut self,
ctx: &'life1 Context,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn on_terminate<'life0, 'life1, 'async_trait>(
&'life0 mut self,
ctx: &'life1 Context,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Called when the behavior is being terminated.
Use this for cleanup like closing connections, saving state, etc.
The default implementation propagates on_terminate to every child
returned by children_mut.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".