Skip to main content

Speculation

Struct Speculation 

Source
pub struct Speculation<R: StoryRng = FastRng> { /* private fields */ }
Expand description

A sandboxed, self-contained speculative run over a story’s current state. See the module docs for the full picture.

Owns everything it needs to drive itself: an Arc-shared Program (cheap to bump, never mutated), an owned clone of the source World (read through, never written back), a Mode::Sandbox fork of the source FlowLocal (where every write lands, and which is simply dropped to discard them), and a clone of the source FlowInstance’s current execution position. Dropping a Speculation is the entire discard operation — nothing it did ever reached the state it was forked from.

Implementations§

Source§

impl<R: StoryRng> Speculation<R>

Source

pub fn fork_from( program: Arc<Program>, world: &World, local: &FlowLocal, flow: &FlowInstance, line_tables: &[Vec<LineEntry>], ) -> Self

Fork a Speculation from an arbitrary flow’s current state.

This is the composable, flow-level constructor — bevy-brink (or any other orchestration layer juggling multiple FlowInstances over possibly-distinct Worlds) can call this directly for any flow, not just a crate::Story’s default one. crate::Story::speculate is a convenience wrapper over this for the common case.

world is cloned (an owned snapshot — the source World is never touched again by this speculation), local is forked in Mode::Sandbox (every unit routes Local; writes never reach world or local’s own future writes), and flow is cloned to capture the exact execution position to speculate from.

Source

pub fn go_to_path(&mut self, path: &str) -> Result<(), RuntimeError>

Move this speculation’s play head to a named knot/stitch path — the speculative equivalent of FlowInstance::choose_path_string. Only this speculation’s own (sandboxed) position moves; the flow it was forked from is untouched.

§Errors

Same as FlowInstance::choose_path_string: an unknown path, a jump while parked on an unresolved external, or a jump while a function evaluation is in progress.

Source

pub fn choose(&mut self, index: usize) -> Result<(), RuntimeError>

Select a pending choice by index — the speculative equivalent of FlowInstance::choose.

§Errors

RuntimeError::NotWaitingForChoice if this speculation isn’t waiting on a choice; RuntimeError::InvalidChoiceIndex for an out-of-range index.

Source

pub fn advance( &mut self, budget: Budget, handler: &dyn ExternalFnHandler, ) -> Result<SpeculationStep, RuntimeError>

Drive this speculation forward by one visible line, honoring budget in place of the runtime’s hardcoded step/line ceilings.

Checks budget.lines against the running total of lines this speculation has already produced before stepping — a speculation that has already hit its line budget errors immediately rather than stepping further. Otherwise drives exactly one visible line (or a yield point) via FlowInstance::advance’s machinery, capped at budget.steps VM steps instead of the production 1,000,000.

A deferred external (crate::ExternalResult::Pending) surfaces as SpeculationStep::AwaitingExternal — resolve it via resolve_external and call advance again, exactly as FlowInstance::advance’s callers do.

§Errors

RuntimeError::LineLimitExceeded if budget.lines has already been reached; RuntimeError::StepLimitExceeded if budget.steps is exhausted before a line completes; any other error advance itself can produce (e.g. RuntimeError::StoryEnded).

Source

pub fn eval_function( &mut self, name: &str, args: &[Value], handler: &dyn ExternalFnHandler, ) -> Result<FunctionEval, RuntimeError>

Evaluate an ink function on this speculation, returning its value — the speculative equivalent of crate::Story::call_function / FlowInstance::begin_function_eval. Output is isolated (as for any engine→ink call) and, being on the sandboxed fork, can never escape to the live story either way.

§Errors

RuntimeError::FunctionNotFound for an unknown name; RuntimeError::ArgCountMismatch if args.len() doesn’t match the function’s declared parameter count; any error FlowInstance::begin_function_eval itself can produce.

Source

pub fn resume_function_eval( &mut self, handler: &dyn ExternalFnHandler, ) -> Result<FunctionEval, RuntimeError>

Resume a function evaluation on this speculation that paused on FunctionEval::AwaitingExternal, after the pending external has been resolved via resolve_external — the speculative equivalent of FlowInstance::resume_function_eval.

Closes the F4.1 gap: eval_function could pause on a deferred external with no way to continue. The full cycle is eval_functionAwaitingExternalresolve_external(value)resume_function_evalReturned(value).

§Errors

RuntimeError::NotEvaluatingFunction if no evaluation is in progress on this speculation; any error FlowInstance::resume_function_eval itself can produce.

Source

pub fn resolve_external(&mut self, value: Value)

Resolve a pending external call on this speculation by supplying its return value. No-op if none is pending. See FlowInstance::resolve_external.

Source

pub fn pending_external_name(&self) -> Option<&str>

The ink-declared name of the external this speculation is paused on, if any. See FlowInstance::pending_external_name.

Source

pub fn transcript(&self) -> &[OutputPart]

The append-only transcript of output parts produced by this speculation so far — structural references, resolved against whatever line tables the caller has (see FlowInstance::transcript). Empty for a freshly-forked speculation that hasn’t been driven yet.

Source

pub fn rendered_transcript(&self) -> Vec<(String, Vec<String>)>

transcript, resolved to (text, tags) pairs against this speculation’s own program and line tables — the read-facing sibling for callers (e.g. brink-web’s wasm binding) that want rendered text rather than raw structural parts. Mirrors crate::transcript::render_transcript.

Auto Trait Implementations§

§

impl<R> Freeze for Speculation<R>

§

impl<R> RefUnwindSafe for Speculation<R>
where R: RefUnwindSafe,

§

impl<R> Send for Speculation<R>
where R: Send,

§

impl<R> Sync for Speculation<R>
where R: Sync,

§

impl<R> Unpin for Speculation<R>
where R: Unpin,

§

impl<R> UnsafeUnpin for Speculation<R>

§

impl<R> UnwindSafe for Speculation<R>
where R: UnwindSafe,

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