Skip to main content

ScriptRuntime

Struct ScriptRuntime 

Source
pub struct ScriptRuntime { /* private fields */ }
Expand description

Compiles and caches one [AST] per unique script path (shared across every entity that attaches the same script) and owns each (entity, attachment index)’s running Rhai Scope. Created when the editor’s Play mode starts and dropped when it stops — nothing here is meant to survive a Stop; see the implementation plan’s “Play/Stop snapshot” note for why script state resetting on Stop is load-bearing, not just convenient.

Implementations§

Source§

impl ScriptRuntime

Source

pub fn new(project_root: PathBuf) -> Self

Source

pub fn begin_frame(&mut self, world: &World)

Refreshes the [FrameSnapshot] every world.find(...) call this frame will read from. Call once per frame, before running any script that frame (see the editor’s EditorScene::update, EditorMode::Playing branch).

Source

pub fn start_script( &mut self, world: &mut World, entity: Entity, index: usize, script_path: &Path, renderer: Option<&Renderer<'_>>, ) -> Vec<ScriptError>

Compiles (or reuses the cached [AST] for) the script at script_path, then starts a fresh instance of it for (entity, index): runs the script body once — which defines its top-level locals and on_start/on_update closures — and calls on_start() if the script defined one. world supplies the entity’s starting position/name so on_start sees real data rather than a zeroed placeholder, and (now that it’s &mut) lets this method drain whatever on_start queues via entity/world/scene immediately rather than leaving it pending — a script whose only hook is on_start (no on_update ever runs to drain the shared queue on its behalf) would otherwise have calls like entity.set_persistent(true) or scene.change(...) sit in the queue forever. renderer is threaded through to that drain for the same reason Self::drain_commands needs one (entity.set_sprite/set_model).

A compile/read/body error is fatal — no instance is created and the single resulting error is returned. An on_start error is not: the instance is still created (so on_update still runs on later frames) and the error is only reported, not propagated as a failure to start. Every error encountered (compile/read/body, on_start itself, or anything the drain surfaces) is returned rather than the first one short-circuiting, mirroring Self::update_entity’s own error-collection shape.

Source

pub fn start_all_scripts( &mut self, world: &mut World, base_dir: &Path, renderer: Option<&Renderer<'_>>, ) -> Vec<ScriptError>

Starts every enabled script attachment (in attachment order) that isn’t already running on an entity currently in world — the “start scripts” half of loading a scene, factored out so EditorScene::start_play, runtime’s RuntimeScene::start, and a script-triggered scene.change(...) (see [WorldCommand::ChangeScene]) all run it identically instead of each keeping its own copy of this loop. The “isn’t already running” check is what lets a scene change call this over the whole post-change world (persistent entities included) without restarting a persistent entity’s already-running script and losing its state. base_dir resolves each attachment’s project-relative path into a real file path (an editor project’s root, or an exported game’s res/ directory). Caller must call Self::begin_frame first so world.find(...) inside any on_start sees a snapshot that includes the entities being started (see runtime_tests::on_start_can_read_other_entities_via_find_when_begin_frame_ran_first). renderer is forwarded to each Self::start_script call, for the same reason Self::drain_commands needs one (an on_start that calls entity.set_sprite/ set_model).

Source

pub fn update_entity( &mut self, world: &mut World, entity: Entity, dt: f32, input: &InputState, mouse: &MouseState, mouse_delta: (f32, f32), renderer: Option<&Renderer<'_>>, ) -> Vec<ScriptError>

Calls every started, enabled attachment’s on_update(dt, input) closure for entity, in attachment order (disabled attachments — including ones this call itself just disabled after too many failures — are skipped), syncing the entity’s crate::world::Transform and name in beforehand and applying whatever it queued via entity/world (see Self::drain_commands) right after. One instance erroring doesn’t stop the others; every error encountered is returned rather than the first one short-circuiting. If an attachment despawns its own entity, the remaining attachments on that entity are skipped for the rest of this call — there’s nothing left to update.

renderer is only needed for entity.set_sprite(...)/set_model(...) (loading a new asset needs a live GPU device); pass None when one isn’t available (e.g. in a test with no real Renderer) and any such command just reports a ScriptError instead of silently doing nothing or panicking.

mouse_delta is the caller’s responsibility, same as it is for editor::fly_camera::FlyCamera::update — MouseState only tracks position, not frame-to-frame movement, so the caller (which already diffs MouseState::position() against last frame’s for its own fly camera) passes it through directly.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> Downcast<T> for T

§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Upcast<T> for T

§

fn upcast(&self) -> Option<&T>

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more