Skip to main content

ScriptHost

Trait ScriptHost 

Source
pub trait ScriptHost:
    Send
    + Sync
    + 'static {
    type Closure: Clone + Send + Sync + 'static;

    const FILLS_COMPONENTS: bool = false;
Show 22 methods // Required methods fn compile_check(&self, source: &str, uri: &str) -> Result<(), ScriptError>; fn load(&mut self, source: &str, uri: &str) -> Result<(), ScriptError>; fn replace(&mut self, source: &str, uri: &str) -> Result<(), ScriptError>; fn reset(&mut self); fn call( &mut self, fn_name: &str, args: &[ScriptValue], ) -> Result<CallOutcome, CallFailure>; fn call_closure( &mut self, closure: &Self::Closure, args: &[ScriptValue], ) -> Result<ScriptValue, ScriptError>; fn register_script_fn(&mut self, f: &ScriptFn) -> Result<(), ScriptError>; fn lang(&self) -> &'static str; // Provided methods fn eval_derivation( &mut self, closure: &Self::Closure, deps: &[String], name: &str, ) -> Result<String, ScriptError> { ... } fn drain_commands(&mut self) -> Vec<ScriptCommand> { ... } fn push_commands(&mut self, cmds: Vec<ScriptCommand>) { ... } fn mirror_get(&self, name: &str) -> Option<ScriptValue> { ... } fn mirror_set(&mut self, name: &str, value: ScriptValue) { ... } fn mirror_sync_str(&mut self, name: &str, value: &str) { ... } fn handler_for(&self, event: &str, key: &str) -> Option<String> { ... } fn derivations_matching( &self, dirty: &HashSet<&str>, pending: &HashSet<String>, ) -> Vec<(String, Vec<String>, Self::Closure)> { ... } fn pending_initial(&self) -> HashSet<String> { ... } fn clear_pending(&mut self, evaluated: &[String]) { ... } fn dispatch_event_handler( &mut self, token: u64, ) -> Result<bool, ScriptError> { ... } fn drop_event_handler(&mut self, token: u64) { ... } fn add_prelude(&mut self, ns: &str, source: &str) { ... } fn builtins(&self) -> &'static [BuiltinFn] { ... }
}
Expand description

Backend that compiles + executes scripts and exposes the host-neutral registries the generic runtime (lumen-script) drives: the command sink, the rich-typed signal mirror, the per-id handler registry, and the derivation registry.

Send + Sync bound: hosts sit in a plain bevy Resource and participate in parallel scheduling. A host that cannot be Send needs a NonSend variant of the install path.

One script-side callable the generic runtime can re-invoke is modeled by Self::Closure - Rhai: FnPtr; candela: a function handle once its embedding API lands.

Provided Associated Constants§

Source

const FILLS_COMPONENTS: bool = false

Whether this host is the one a component marker in the tree names a function in.

A marker is what the build leaves where a component has to run, and markup blocks are one language’s macro, so exactly one host answers for them. Every other host leaves a marker alone rather than reporting a function it was never going to have.

Required Associated Types§

Source

type Closure: Clone + Send + Sync + 'static

Host-native handle to a script closure (a derive(...) body).

Required Methods§

Source

fn compile_check(&self, source: &str, uri: &str) -> Result<(), ScriptError>

Compile-only, side-effect free, with the exact engine settings Self::load uses - lumenc check and run must agree on what parses. uri seeds ScriptError::Compile::uri.

Source

fn load(&mut self, source: &str, uri: &str) -> Result<(), ScriptError>

Compile + evaluate the top level into persistent state. Fresh-start load; replaces any previously loaded program.

Source

fn replace(&mut self, source: &str, uri: &str) -> Result<(), ScriptError>

Hot reload: compile first (no state touched on a parse error), then swap atomically. Snapshot the registries, clear them, re-evaluate the top level into the existing persistent scope, and roll the snapshot back in full if that evaluation fails. Persistent across the swap: engine registrations, scope bindings, the signal mirror, and the in-flight command sink.

On success the snapshot is merged back under whatever the new top level registered, via carry_forward. Lifecycle callbacks do not re-fire on reload, so a handler an app bound from on_start has no second chance to register itself; without the merge every such handler would go quiet after the first reload.

Source

fn reset(&mut self)

Drop the loaded program and all persistent state. Genuine restart; hot reload should use Self::replace.

Source

fn call( &mut self, fn_name: &str, args: &[ScriptValue], ) -> Result<CallOutcome, CallFailure>

Call a script function by name. A missing function is silent success (found: false); see CallOutcome. A function that raises returns CallFailure, which still carries the commands it queued before the error.

Source

fn call_closure( &mut self, closure: &Self::Closure, args: &[ScriptValue], ) -> Result<ScriptValue, ScriptError>

Re-entrant closure invocation. Must be callable while the generic runtime holds NO host locks (snapshot-then-call pattern): the closure body may re-enter builtins that touch the sink / mirror.

Source

fn register_script_fn(&mut self, f: &ScriptFn) -> Result<(), ScriptError>

Bind one ScriptFn so the script can call it.

The host maps ScriptNs onto its own name space, binds the signature’s arity range, and retains f in a ScriptFnStore so Self::reset can put it back. A host’s own engine accessors remain available for anything this shape cannot express.

§Errors

The host could not bind the function: its binding window has closed (candela binds host declarations when the artifact loads) or the engine rejected the registration.

Source

fn lang(&self) -> &'static str

Language tag, such as "candela". Used in diagnostics prefixes (lumen-<lang>: ...).

Provided Methods§

Source

fn eval_derivation( &mut self, closure: &Self::Closure, deps: &[String], name: &str, ) -> Result<String, ScriptError>

Evaluate one derivation: read the dep values, invoke closure, store the rich result into the mirror under name, and return the host-canonical stringification for the ECS property store.

Deviation from the original v2 sketch (documented in the design doc section 1.9): the default impl composes mirror_get -> call_closure -> mirror_set -> ScriptValue::stringify, but hosts should override with a native path - round-tripping dep values through ScriptValue loses fidelity for host-native structured values, and stringification is host-canonical (Rhai renders 1.0 where Rust’s f64 Display renders 1; store strings feed bind-text and the parse-back policy, so the host must own the format).

Source

fn drain_commands(&mut self) -> Vec<ScriptCommand>

Drain commands queued by builtins since the last drain. Default: a host with no command sink has nothing to drain.

Source

fn push_commands(&mut self, cmds: Vec<ScriptCommand>)

Put commands back into the sink so they flow through the next tick’s normal drain (the on_start re-stash). Default: dropped.

Source

fn mirror_get(&self, name: &str) -> Option<ScriptValue>

Read a mirror entry. None => never written. Default: no mirror.

Source

fn mirror_set(&mut self, name: &str, value: ScriptValue)

Write a mirror entry (host-native conversion of value). Default: no mirror, so the write is dropped.

Source

fn mirror_sync_str(&mut self, name: &str, value: &str)

section 1.3 type-preserving parse-back of a store string. The trait pins the POLICY: a mirror entry currently holding a scalar (bool / int / float) parses the string back into that SAME type; structured mirror values (arrays, maps) stay authoritative and ignore the string; unparseable strings leave the mirror untouched; absent / string entries take the store string verbatim. Default: no mirror.

Source

fn handler_for(&self, event: &str, key: &str) -> Option<String>

Per-id handler lookup (on(event, id, fn)), including the template-suffix fallback: a handler registered for save also matches user-card:save via the last-: suffix. Default: no handler registry.

Source

fn derivations_matching( &self, dirty: &HashSet<&str>, pending: &HashSet<String>, ) -> Vec<(String, Vec<String>, Self::Closure)>

Snapshot of derivations matching dirty plus pending (name, deps, closure) - taken OUTSIDE any host lock so the driver can invoke closures re-entrantly. Default: no derivation registry.

Source

fn pending_initial(&self) -> HashSet<String>

Names of derivations registered but never successfully evaluated; they all run on the next derivation pass regardless of dirt. Default: none.

Source

fn clear_pending(&mut self, evaluated: &[String])

Remove successfully-evaluated names from the pending-initial set. Erroring derivations stay pending and retry next tick. Default: no-op.

Source

fn dispatch_event_handler(&mut self, token: u64) -> Result<bool, ScriptError>

Invoke the event-handler closure the host registered under token (via its on(node, type, handler) builtin). The host builds its native event object, which reads the process-global current-event cell (crate::event); commands the handler queues are drained via Self::drain_commands afterwards by the caller. Returns whether a closure was found and run.

Default: not supported (no closure registry) -> Ok(false). Hosts that expose on(...) with real closures override this.

Source

fn drop_event_handler(&mut self, token: u64)

Drop the event-handler closure registered under token (the host side of off() / UnbindEvent). Default: no-op.

Source

fn add_prelude(&mut self, ns: &str, source: &str)

Take source a plugin ships alongside the functions it registered under ns, to be compiled ahead of the app’s own program.

This is how a plugin offers sugar over its functions: a struct and an impl block in this host’s own language, so a script calls pin(21).level() instead of the free function. The registry hands a host only the sources written in its language.

A host that cannot stage source says so rather than dropping it, which is what the default does.

Source

fn builtins(&self) -> &'static [BuiltinFn]

The builtin-function metadata table feeding LSP completion / hover and the parity test. Default: none.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§