Skip to main content

arora_behavior/
golden.rs

1//! Golden keys: well-known store slots the runtime maintains for every behavior.
2//!
3//! The runtime writes these at the start of each step — before it ticks any
4//! behavior — so a behavior reads the current frame's timing straight from the
5//! [`store`](super::BehaviorContext::store) instead of taking it as a tick
6//! argument. Timing stays out of the
7//! [`BehaviorInterpreter`](super::BehaviorInterpreter) API: it is
8//! just data, like any other slot, and a behavior (an animation module, a graph
9//! time node) derives whatever it needs — `dt`, elapsed time — by reading these
10//! keys.
11//!
12//! The keys live under the reserved [`PREFIX`] namespace. The runtime keeps them
13//! local: it never forwards them out to the bridge or hardware, since a
14//! wall-clock advancing every frame is noise to a remote. Behaviors must not
15//! publish their own keys under this prefix.
16
17/// Reserved namespace for runtime-maintained golden keys. The runtime owns it
18/// and does not forward it outbound; behaviors must not write their own keys
19/// under this prefix.
20pub const PREFIX: &str = "arora/";
21
22/// Monotonic **nanoseconds** since the runtime started, as a
23/// [`U64`](arora_types::value::Value::U64) value. The runtime advances it by the
24/// step's `dt` before each tick. Integer nanoseconds are exact (no float drift
25/// over a long run) and give ~584 years of range before `u64` overflows.
26pub const TIME: &str = "arora/time";
27
28/// **Nanoseconds** elapsed since the previous step, as a
29/// [`U64`](arora_types::value::Value::U64) value — the step's `dt`, surfaced for
30/// behaviors that pace themselves (an animation module, a graph time node).
31pub const DT: &str = "arora/dt";
32
33/// Whether `key` is a reserved golden key: runtime-owned and never forwarded
34/// outbound. The runtime uses this to keep the golden namespace out of the
35/// changes it flushes to the bridge and hardware each step.
36pub fn is_golden(key: &str) -> bool {
37    key.starts_with(PREFIX)
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43
44    #[test]
45    fn golden_keys_share_the_reserved_prefix() {
46        assert!(is_golden(TIME));
47        assert!(is_golden(DT));
48        assert!(TIME.starts_with(PREFIX));
49        assert!(DT.starts_with(PREFIX));
50    }
51
52    #[test]
53    fn ordinary_keys_are_not_golden() {
54        assert!(!is_golden("sensor/x"));
55        assert!(!is_golden("actuator/y"));
56        // A key that merely mentions "arora" later in the path is not reserved.
57        assert!(!is_golden("device/arora/time"));
58    }
59}