Skip to main content

Session

Struct Session 

Source
pub struct Session<G: Game> { /* private fields */ }
Expand description

A game running against an offscreen target, one frame per Session::step.

The session owns the game for its whole life, exactly as run does, and borrows nothing from the caller. The caller is its player: Session::set_pointer, Session::press, Session::release, Session::pointer_delta, Session::wheel_delta and Session::type_text are its controls. Each move reaches what the game reads, the UI, or both: the UI is given the egui::Event a window’s own event reaches it as, and reads no PointerDelta of its own; text reaches the UI alone. A rebind lasts the session and is written to no store, and so does everything the game saves — every key returns its fallback until the session itself saves one.

Implementations§

Source§

impl<G: Game> Session<G>

Source

pub fn new( config: Config, size: UVec2, init: impl FnOnce(&mut InitContext<'_, G>) -> Result<G, Error>, ) -> Result<Self, Error>

Acquires a GPU, builds an offscreen target size physical pixels across, and runs init against it, as run does without a window.

size replaces the configuration’s window size, which means nothing without a window; the clear color and the rest of config apply as usual. Fails if no GPU is available, if size has a zero side, if a style of the game’s does not compile, or if init does.

Source

pub fn tick(&mut self)

Runs one fixed simulation step: Game::tick with Config::tick_interval, or the step the game last set.

Headless time moves only when called; a step set during a tick is taken from the next tick on. A tick covers the span it simulates, so it reads the clock at the end of that span and the step after it draws at that same instant.

Source

pub fn with_frame_interval(self, interval: Duration) -> Self

The same session, with the time each Session::step covers set to interval.

A session’s clock is the caller’s: a tick advances it by its own interval, and a step by this one. What a frame reads as FrameContext::elapsed is the later of the two, so a caller that ticks and steps over the same span counts it once, as a window would. A session starts at Duration::ZERO, which leaves every step at the same instant.

The UI paces its own animations by that clock, so an interval is what moves a fade or a highlight of the UI’s own with no window.

Source

pub fn set_frame_interval(&mut self, interval: Duration)

Sets the time each later Session::step covers; see Session::with_frame_interval.

Source

pub fn step(&mut self) -> FrameStats

Runs one frame: Game::frame records its draws, and the engine draws exactly those into the target, replacing what was there.

Nothing is timed for you — wrap the call to measure it. Drawing never ticks: Session::tick is the only thing that simulates. A step advances the clock by with_frame_interval, which is the dt the frame reads.

A floating UI window just opened may need a few more step calls before it draws; a capture taken right after may not show it.

Source

pub fn set_pointer(&mut self, at: Vec2)

Moves the pointer to at, in physical pixels from the target’s top left, which is what FrameContext::pointer reads.

The next tick or step reads it, and it stays there until this moves it again. The distance it moves is what a PointerDelta binding reads, exactly as a cursor’s is, and the UI reads the same move.

Source

pub fn press(&mut self, control: impl Into<Switch>)

Presses control, which every action bound to it reads as down, and which the UI reads as the same press.

The next tick and the step after it read the press as an edge, and no tick or step after them reads that edge again. The control stays down until Session::release.

Source

pub fn release(&mut self, control: impl Into<Switch>)

Releases control, which the next tick and the step after it read as an edge the same way.

Source

pub fn pointer_delta(&mut self, lane: PointerDelta, pixels: f32)

Moves lane of the pointer by pixels, counted right and up as Session::set_pointer counts them.

An axis bound to that lane reads it through its own scale, a fraction of what it moved. The UI reads nothing of it. The next tick or step reads it: a lane reports a distance since the last reading, never a place.

Source

pub fn wheel_delta(&mut self, lane: WheelDelta, notches: f32)

Turns lane of the wheel by notches, counted right and away: one notch is one step of a mouse wheel, the same on every target.

An axis bound to that lane reads it through its own scale, a fraction of what it turned, and the UI scrolls by what a window reports for those notches. The next tick or step reads it: a lane reports a distance since the last reading, never a place.

Source

pub fn type_text(&mut self, text: &str)

Types text into the UI, wherever it holds the keyboard.

The next Session::step reads it. The game’s own actions read nothing of it: text belongs to the UI layer, and an action reads controls.

Source

pub fn wait_for_gpu(&self) -> Result<(), Error>

Waits until the GPU has finished every submitted frame.

Session::step returns at submission; fence each step to cap work in flight at one frame (vsync’s bound), so step times measure frame cost, not queue depth.

Source

pub fn pixels(&self) -> Result<Vec<u8>, Error>

Reads the target back: 4 * width * height bytes of sRGB-encoded RGBA, row by row from the top left, with no padding between rows.

Every call waits for the GPU and allocates, which suits tests, not measurement done every frame. Before the first Session::step the pixels are undefined.

Source

pub fn size(&self) -> UVec2

The target’s size in physical pixels, as FrameContext::window_size reports it to the game.

Source

pub fn closed(&self) -> bool

Whether the game has requested the end of the run through FrameContext::close, which a window would have closed on.

A session has no loop to end: it runs every tick and step the caller calls for, and this stays true.

Source

pub fn fault(&self) -> Option<Error>

The fault the session’s device reported, which a run behind a window would have ended on: that the device was lost, or that it ran out of memory.

The text is the log line a run behind a window would write, never the text a player reads, which states the adapter a window run drew on. Each Session::step reads the device, and this reports the first fault it read, every call, as Session::closed does: a session has no loop to end, and the caller stops when it chooses. A call the device refused leaves nothing here; the engine logs it at error level.

Source

pub fn cursor(&self) -> Cursor

The cursor the last Session::step drew the pointer as: what the frame set through FrameContext::set_cursor, or the UI’s where the UI sets a cursor of its own.

Cursor::Arrow before the first step, and where a step’s frame set none. A cursor the UI sets that Cursor does not hold reads as the nearest one it holds. Cursor::Held reads back like any other: a session has no window to hold a pointer in, so Session::set_pointer places it as it always does.

Source

pub fn game(&self) -> &G

The game being driven, for code that reads it between steps.

Source

pub fn game_mut(&mut self) -> &mut G

The game being driven, for code that changes it between steps.

Auto Trait Implementations§

§

impl<G> !RefUnwindSafe for Session<G>

§

impl<G> !Sync for Session<G>

§

impl<G> !UnwindSafe for Session<G>

§

impl<G> Freeze for Session<G>
where GameThread<G>: Freeze,

§

impl<G> Send for Session<G>
where GameThread<G>: Send,

§

impl<G> Unpin for Session<G>
where GameThread<G>: Unpin,

§

impl<G> UnsafeUnpin for Session<G>
where GameThread<G>: UnsafeUnpin,

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

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

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> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T> Instrument for T

Source§

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

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

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

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

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

Initializes a with the given initializer. Read more
Source§

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

Dereferences the given pointer. Read more
Source§

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

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

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

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

Source§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

Source§

fn simd_from(_simd: S, value: T) -> T

Source§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

Source§

fn simd_into(self, simd: S) -> T

Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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

impl<T> Upcast<T> for T

Source§

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

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WithSubscriber for T

Source§

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

fn with_current_subscriber(self) -> WithDispatch<Self>

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