Skip to main content

BehaviorInterpreter

Trait BehaviorInterpreter 

Source
pub trait BehaviorInterpreter {
    // Required method
    fn tick(
        &mut self,
        ctx: &mut BehaviorContext<'_>,
    ) -> Result<BehaviorStatus, BehaviorError>;

    // Provided methods
    fn apply(&mut self, diff: GraphDiff) -> Result<(), BehaviorError> { ... }
    fn load(&mut self, graph: Graph) -> Result<(), BehaviorError> { ... }
    fn spawn(
        &mut self,
        call: Call,
        policy: RunPolicy,
    ) -> Result<TaskHandle, BehaviorError> { ... }
    fn halt(&mut self, task: TaskId) -> Result<(), BehaviorError> { ... }
}
Expand description

A behavior executor: something the Arora runtime ticks once per step to run an authored behavior.

Implemented by the behavior tree (arora-behavior-tree’s [BehaviorTreeInterpreter]) and by other interpreters such as a Vizij node-graph interpreter. The runtime holds one Box<dyn BehaviorInterpreter> and ticks it without knowing which is which.

Implement this to add a new kind of executor (a new authored-behavior representation the runtime can run), not to hand-code one particular behavior — authored behaviors come from the visual editors, run by an existing interpreter.

Not Send: the runtime is a single-owner, single-thread step loop.

Required Methods§

Source

fn tick( &mut self, ctx: &mut BehaviorContext<'_>, ) -> Result<BehaviorStatus, BehaviorError>

Advance one step. Return BehaviorStatus::Running to be ticked again, or BehaviorStatus::Done to be dropped — Done(Ok(())) for a clean stop, Done(Err(e)) for a terminal fault whose reason e is surfaced.

An Err from tick is different from Ok(Done(Err(..))): an Err is a transient failure — the runtime keeps the interpreter installed and ticks it again next step (a momentary lowering or call-bridge hiccup), only raising the reason on the standing error watch. Done(Err(..)) is terminal: the run has ended and will not be retried.

Provided Methods§

Source

fn apply(&mut self, diff: GraphDiff) -> Result<(), BehaviorError>

Edit the running behavior by applying a GraphDiff: add/remove nodes and links, set/override predetermined keys. Loading a behavior is applying a diff onto an empty graph.

The default rejects edition — override it in interpreters that carry an editable graph::Graph (the behavior tree does). A hand-coded, non-graph interpreter (the corner case above) can leave this as-is.

apply validates and stores the edit; an implementation may defer re-lowering its runtime form to the next tick (which carries the store in its context), so a lowering problem can surface there rather than here. This keeps apply callable from anywhere a GraphDiff arrives — notably the interpreter’s engine-registered edit function, which holds no store.

Source

fn load(&mut self, graph: Graph) -> Result<(), BehaviorError>

Replace the running behavior with graph, whole. Like apply it is store-less — an implementation may defer lowering to the next tick — so it is callable from the interpreter’s engine-registered load function. The default rejects loading, for hand-coded interpreters that carry no graph.

Source

fn spawn( &mut self, call: Call, policy: RunPolicy, ) -> Result<TaskHandle, BehaviorError>

Spawn call as a concurrent task run under policy, returning a TaskHandle to follow and stop it. Non-blocking: the run advances with the normal tick, and its lifecycle surfaces on the handle’s keys.

The default rejects spawning — override it in interpreters that host concurrent runs (a run is realised however the interpreter hosts behavior: a parallel behavior-tree subtree, a node-graph subgraph). A hand-coded interpreter can leave this as-is.

Source

fn halt(&mut self, task: TaskId) -> Result<(), BehaviorError>

Halt the run identified by task (idempotent): a clean stop that may run compensation, not a hard kill. On reaching a terminal state the run is dropped and its status key reflects the outcome.

The default rejects halting — override it alongside spawn.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§