1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//! Behavior interpreters: the executors the Arora runtime ticks each step.
//!
//! Two things share the word "behavior", and this crate is about only one of
//! them:
//!
//! - A **behavior** (the noun) is an *authored, editable representation* of what
//! a device should do — a behavior tree, a node graph — produced in a visual
//! editor (Studio, the Vizij Workspace) and shipped as data.
//! - A [`BehaviorInterpreter`] is the *runtime-level executor* that runs one of
//! those: a behavior-tree interpreter, a node-graph interpreter. It is the
//! thing the runtime actually ticks.
//!
//! The runtime holds one `Box<dyn BehaviorInterpreter>` and ticks it — swapping
//! the interpreter replaces the behavior. The behavior tree is one interpreter
//! (`arora-behavior-tree`'s [`BehaviorTreeInterpreter`]); a Vizij node graph is
//! another. Adding a new *kind of authored behavior* means adding a new
//! interpreter here. Hand-implementing the trait to hard-code a single behavior
//! in Rust is possible, but it is a corner case — the promoted path is to author
//! a behavior in an editor and let an interpreter run it.
//!
//! An authored behavior is a [`graph::Graph`] — nodes bound to functions, with
//! typed I/Os and links — and interpreters are edited by
//! [`apply`](BehaviorInterpreter::apply)ing a [`graph::GraphDiff`]. Loading a
//! behavior is applying a diff onto an empty graph. See [`graph`] for the model.
//!
//! Each tick an interpreter gets a [`BehaviorContext`]: the shared
//! [`DataStore`](arora_types::data::DataStore) (read inputs, write intent /
//! outputs) and a [`CallBridge`](arora_types::call::CallBridge) (so a
//! module-calling interpreter like the behavior tree can reach the engine). An
//! interpreter uses whichever it needs — a graph reads/writes the store; the
//! tree drives the caller.
//!
//! Timing is not a tick argument. The runtime publishes the frame's clock into
//! the store under the [`golden`] keys before it ticks, so an interpreter that
//! needs `dt` or elapsed time reads it from the store like any other slot.
use CallBridge;
use DataStore;
pub use ;
/// Whether an interpreter wants to be ticked again.
/// What a [`BehaviorInterpreter`] receives each
/// [`tick`](BehaviorInterpreter::tick).
/// An interpreter failed to tick.
/// 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.