Skip to main content

Runtime

Struct Runtime 

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

A Runtime is the primary integration point between moxie and an embedder. Each independent instance is responsible for an event loop and tracks time using a Revision which it increments on each iteration of the loop. Owns the cache and state for a given context.

§Key considerations

§Event Loops

moxie assumes that it will be responsible for interfacing with or managing an event loop with the basic structure:

  1. enter loop
  2. present interface
  3. wait for changes
  4. goto (2)

Step (2) is implemented in Runtime::run_once, and the user code run by that method is expected to register the runtime for wakeups on future events. Step (3) is implemented by the embedder, waiting until the runtime’s change notification waker is invoked.

§Change notifications

Each runtime should be provided with a std::task::Waker that will notify the embedding environment to run the loop again. This is done by calling Runtime::set_state_change_waker.

For scenarios without an obvious “main thread” this can be done for you by binding a root function to a RunLoop which implements std::future::Future and can be spawned as a task onto an executor. For more nuanced scenarios it can be necessary to write your own waker to ensure scheduling compatible with the embedding environment. By default a no-op waker is provided.

The most common way of notifying a runtime of a change is to update a state variable.

§Caching

When a runtime is repeatedly invoking the same code for every Revision there’s likely to be a lot of repetitive work. This might be something complex like a slow computation over the set of visible items, or it might be something simple like using the same DOM node for a given button on every Revision.

While not strictly necessary to integrate moxie, much of the runtime’s potential value comes from identifying work that’s repeated across frames and storing it in the runtime’s cache instead of recomputing every time.

Internally the runtime hosts a dyn-cache instance which is garbage-collected at the end of each Revision. All cached values are stored there and evicted at the end of revisions where they went unused. This behavior also provides deterministic drop timing for values cached by the runtime.

§Tasks

Each runtime expects to be able to spawn futures as async tasks, provided with Runtime::set_task_executor. By default a no-op spawner is provided.

§Minimal Example

This example has no side effects in its root function, and doesn’t have any state variables which might require change notifications.

let mut rt = Runtime::new();
assert_eq!(rt.revision().0, 0);
for i in 1..10 {
    rt.run_once(|| ());
    assert_eq!(rt.revision(), Revision(i));
}

Implementations§

Source§

impl Runtime

Source

pub fn looped<Root, Out>(self, root: Root) -> RunLoop<Root>
where Root: FnMut() -> Out,

Returns this runtime bound with a specific root function it will run in a loop.

Source§

impl Runtime

Source

pub fn new() -> Self

Construct a new Runtime with blank storage and no external waker or task executor.

Source

pub fn revision(&self) -> Revision

The current revision of the runtime, or how many times run_once has been invoked.

Source

pub fn run_once<Out>(&mut self, op: impl FnOnce() -> Out) -> Out

Runs the root closure once with access to the runtime context, increments the runtime’s Revision, and drops any cached values which were not marked alive.

Source

pub fn set_state_change_waker(&mut self, wk: Waker)

Sets the std::task::Waker which will be called when state variables receive commits. By default the runtime no-ops on a state change, which is probably the desired behavior if the embedding system will call Runtime::run_once on a regular interval regardless.

Source

pub fn set_task_executor(&mut self, sp: impl LocalSpawn + 'static)

Sets the executor that will be used to spawn normal priority tasks.

Trait Implementations§

Source§

impl Default for Runtime

Source§

fn default() -> Runtime

Returns the “default value” for a type. Read more

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
Source§

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

Source§

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.
Source§

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.
Source§

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.
Source§

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.
Source§

impl<T> Erased for T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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, 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.