Skip to main content

Runner

Struct Runner 

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

Wgpu runtime owned by the host. One instance per surface/format.

All backend-agnostic state — interaction state, paint-stream scratch, per-stage layout/animation hooks — lives in core: RunnerCore and is shared with the vulkano backend. The fields below are wgpu-specific resources only.

Implementations§

Source§

impl Runner

Source

pub fn new(device: &Device, queue: &Queue, target_format: TextureFormat) -> Self

Create a runner for the given target color format. The host passes its swapchain/render-target format here so pipelines and the glyph atlas are built compatible.

Source

pub fn with_sample_count( device: &Device, queue: &Queue, target_format: TextureFormat, sample_count: u32, ) -> Self

Like Self::new, but builds all pipelines with sample_count MSAA samples. The host must provide a matching multisampled render target and a single-sample resolve target. sample_count of 1 is the non-MSAA default.

Defaults per_sample_shading to true — appropriate for native adapters, where DownlevelFlags::MULTISAMPLED_SHADING is the norm. Web/WebGL2 hosts must instead route through Self::with_caps and pass the actual cap from the adapter, otherwise stock pipelines fail naga validation on shader-module creation.

Source

pub fn with_caps( device: &Device, _queue: &Queue, target_format: TextureFormat, sample_count: u32, per_sample_shading: bool, ) -> Self

Like Self::with_sample_count, but with the per_sample_shading downlevel cap supplied explicitly. Hosts that target backends without DownlevelFlags::MULTISAMPLED_SHADING (WebGL2, most browser WebGPU) read the flag off the adapter and pass it here:

let caps = adapter.get_downlevel_capabilities();
let pss = caps.flags.contains(wgpu::DownlevelFlags::MULTISAMPLED_SHADING);
Runner::with_caps(&device, &queue, format, sample_count, pss)

When false, every pipeline (stock and later-registered custom) has @interpolate(perspective, sample) rewritten to @interpolate(perspective) before WGSL compilation. The shader then interpolates at pixel centre instead of per MSAA sample — MSAA coverage still works at sample_count > 1; only the per-sub-sample brightness pass is skipped, slightly thickening the AA band on curved SDF edges.

Source

pub fn set_surface_size(&mut self, width: u32, height: u32)

Tell the runner the swapchain texture size in physical pixels. Call this once after surface.configure(...) and again on every WindowEvent::Resized. The runner uses this as the canonical viewport_px for scissor math; without it, the value is derived from viewport.w * scale_factor, which can drift by one pixel when scale_factor is fractional and trip wgpu’s set_scissor_rect validation.

Source

pub fn warm_default_glyphs(&mut self)

Set the theme used to resolve implicit widget surfaces to shaders. Pre-rasterize printable ASCII for the bundled default faces (Inter Variable + JetBrains Mono Variable). Pays the ~40ms one-time MSDF-generation cost up-front so the first frame that introduces each character doesn’t take a 20-30ms paint hit. Hosts that interactively render UI text (the showcase, custom apps, etc.) should call this once after constructing the Runner and before the first frame; headless fixtures that render only static content can skip it. MSDF keys are size-independent so each character is rasterized exactly once and reused for every size + weight afterwards.

Source

pub fn set_theme(&mut self, theme: Theme)

Source

pub fn theme(&self) -> &Theme

Source

pub fn set_icon_material(&mut self, material: IconMaterial)

Select the stock material used by the vector-icon painter. Prefer Theme::with_icon_material for app-level routing; this remains useful for low-level render fixtures.

Source

pub fn icon_material(&self) -> IconMaterial

Source

pub fn register_shader( &mut self, device: &Device, name: &'static str, wgsl: &str, )

Register a custom shader. name is the same string passed to aetna_core::shader::ShaderBinding::custom; nodes bound to it via El::shader paint through this pipeline.

The WGSL source must use the shared (rect, vec_a, vec_b, vec_c) instance layout and the FrameUniforms bind group described in the module docs. Compilation happens at register time — invalid WGSL panics here, not mid-frame.

Re-registering the same name replaces the previous pipeline (useful for hot-reload during development).

Source

pub fn register_shader_with( &mut self, device: &Device, name: &'static str, wgsl: &str, samples_backdrop: bool, samples_time: bool, )

Register a custom shader, with opt-in flags for backdrop sampling and time-driven motion.

samples_backdrop=true schedules the shader’s draws into Pass B (after a snapshot of Pass A’s rendered content) and binds the snapshot texture as @group(2) binding=0 (backdrop_tex) plus a sampler at binding=1 (backdrop_smp). See docs/SHADER_VISION.md §“Backdrop sampling architecture”. Backdrop depth is capped at 1.

samples_time=true declares that the shader’s output depends on frame.time. The runtime ORs this into PrepareResult::needs_redraw for any frame that has at least one node bound to the shader, so the host idle loop keeps ticking without a per-El opt-in. Stock shaders self- report through aetna_core::shader::StockShader::is_continuous; this flag is the same signal for app-registered WGSL.

Source

pub fn ui_state(&self) -> &UiState

Borrow the internal UiState — primarily for headless fixtures that want to look up a node’s rect after prepare (e.g., to simulate a pointer at a specific button’s center).

Source

pub fn debug_summary(&self) -> String

One-line diagnostic snapshot of interactive state — passes through to UiState::debug_summary. Intended for per-frame logging (e.g., console.log from the wasm host while debugging hover / animation glitches).

Source

pub fn rect_of_key(&self, key: &str) -> Option<Rect>

Return the most recently laid-out rectangle for a keyed node.

Call after Self::prepare. This is the host-composition hook: reserve a keyed Aetna element in the UI tree, ask for its rect here, then record host-owned rendering into that region using the same encoder / render flow that surrounds Aetna’s pass.

Source

pub fn prepare( &mut self, device: &Device, queue: &Queue, root: &mut El, viewport: Rect, scale_factor: f32, ) -> PrepareResult

Lay out the tree, resolve to draw ops, and upload per-frame buffers (quad instances + glyph atlas). Must be called before Self::draw and outside of any render pass.

viewport is in logical pixels — the units the layout pass works in. scale_factor is the HiDPI multiplier (1.0 on a regular display, 2.0 on most modern HiDPI, can be fractional). The host’s render-pass target should be sized at physical pixels (viewport × scale_factor); the runner maps logical → physical internally so layout, fonts, and SDF math stay device-independent.

Source

pub fn repaint( &mut self, device: &Device, queue: &Queue, viewport: Rect, scale_factor: f32, ) -> PrepareResult

Paint-only frame: rerun [RunnerCore::prepare_paint_cached] + GPU upload + frame-uniform write against the cached ops from the most recent Self::prepare call. Skips rebuild + layout

  • draw_ops + snapshot — only frame.time advances.

Hosts call this when PrepareResult::next_paint_redraw_in fires (a time-driven shader needs another frame) and no input has been processed since the last full prepare. Input always upgrades to the full prepare(...) path.

viewport and scale_factor must match the values passed to the most recent prepare(...) — a resize must go through the full layout path. Returns the same shape of PrepareResult for diagnostic continuity, with both deadlines re-computed from the cached signals: next_layout_redraw_in is None (we didn’t re-evaluate), and next_paint_redraw_in is whatever the cached ops still report. The host owns the layout deadline across paint-only frames.

Source

pub fn pointer_moved(&mut self, p: Pointer) -> PointerMove

Update pointer position and recompute the hovered key. Returns the new hovered key, if any (host can use it for cursor styling or to decide whether to call request_redraw). Pointer moved to p.x, p.y (logical px). Returns the events to dispatch via App::on_event plus a needs_redraw flag — see PointerMove for why hosts must gate request_redraw on the flag. The hovered node is updated on ui_state().hovered regardless. Mouse-only hosts can construct p via Pointer::moving.

Source

pub fn pointer_left(&mut self) -> Vec<UiEvent>

Pointer left the window — clear hover/press. Returns a PointerLeave event for the previously hovered target (when there was one); hosts should route the events through App::on_event like the other pointer entry points.

Source

pub fn file_hovered(&mut self, path: PathBuf, x: f32, y: f32) -> Vec<UiEvent>

File is being dragged over the window. Hosts call this from winit::WindowEvent::HoveredFile (one call per file). Returns the FileHovered event routed to the keyed leaf at the cursor (or window-level if outside any keyed surface).

Source

pub fn file_hover_cancelled(&mut self) -> Vec<UiEvent>

File hover ended without a drop — hosts call this from winit::WindowEvent::HoveredFileCancelled. Window-level event (not routed); apps clear any drop-zone affordance.

Source

pub fn file_dropped(&mut self, path: PathBuf, x: f32, y: f32) -> Vec<UiEvent>

File was dropped on the window. Hosts call this from winit::WindowEvent::DroppedFile (one call per file).

Source

pub fn would_press_focus_text_input(&self, x: f32, y: f32) -> bool

Whether a primary press at (x, y) (logical px) would land on a node that opted into capture_keys — the marker the library uses for text-input-style widgets. Hosts query this from a DOM pointerdown handler to decide whether to focus a hidden textarea (so the soft keyboard can open in the user-gesture context). See [RunnerCore::would_press_focus_text_input] for details.

Source

pub fn focused_captures_keys(&self) -> bool

Whether the currently focused node is a text-input-style widget (i.e. has capture_keys set). Hosts mirror this each frame into platform affordances such as the on-screen keyboard or IME compose-window placement.

Source

pub fn pointer_down(&mut self, p: Pointer) -> Vec<UiEvent>

Pointer pressed at p.x, p.y (logical px) for p.button. For Primary, records the pressed key for press-visual feedback, updates focus, and returns a PointerDown event so widgets that need to react at down-time (text input selection anchor, draggable handles) can do so. For Secondary / Middle, records on a side channel and returns None. The actual click event fires on pointer_up. Mouse-only hosts can construct p via Pointer::mouse.

Source

pub fn set_modifiers(&mut self, modifiers: KeyModifiers)

Replace the tracked modifier mask. Hosts call this from their platform’s “modifiers changed” hook so subsequent pointer events (PointerDown, Drag, Click, …) stamp the current mask into UiEvent.modifiers.

Source

pub fn pointer_up(&mut self, p: Pointer) -> Vec<UiEvent>

Pointer released at p.x, p.y for p.button. Returns the events the host should dispatch in order: for Primary, always a PointerUp (when there was a corresponding down) followed by an optional Click (when the up landed on the down’s node). For Secondary / Middle, an optional SecondaryClick / MiddleClick on the same-node match. Mouse-only hosts can construct p via Pointer::mouse.

Source

pub fn key_down( &mut self, key: UiKey, modifiers: KeyModifiers, repeat: bool, ) -> Vec<UiEvent>

Source

pub fn text_input(&mut self, text: String) -> Option<UiEvent>

Forward an OS-composed text-input string (winit’s keyboard event .text field, or an Ime::Commit) to the focused element as a TextInput event.

Source

pub fn set_hotkeys(&mut self, hotkeys: Vec<(KeyChord, String)>)

Replace the hotkey registry. Call once per frame, after app.build(), passing app.hotkeys() so chords stay in sync with state.

Source

pub fn set_selection(&mut self, selection: Selection)

Push the app’s current selection to the runtime so the painter can draw highlight bands. Hosts call this once per frame alongside Self::set_hotkeys.

Source

pub fn selected_text(&self) -> Option<String>

Resolve the runtime’s current selection to a text payload from the most recently laid-out tree. See [RunnerCore::selected_text] — virtual-list rows are realized during layout, so a freshly built app tree would miss them and a Ctrl+C lookup that walked it would silently come back empty.

Source

pub fn selected_text_for(&self, selection: &Selection) -> Option<String>

Resolve an explicit aetna_core::selection::Selection against the last laid-out tree. See [RunnerCore::selected_text_for].

Source

pub fn push_toasts(&mut self, specs: Vec<ToastSpec>)

Queue toast specs onto the runtime’s toast stack. Hosts call this once per frame with app.drain_toasts(). Each spec is stamped with a monotonic id and an expires_at deadline (now + ttl); the next prepare call drops expired entries and synthesizes a toast_stack floating layer over the rest.

Source

pub fn dismiss_toast(&mut self, id: u64)

Programmatically dismiss a toast by id. Useful for cancelling long-TTL toasts when an external condition resolves (e.g., “reconnecting…” turning into “connected”).

Source

pub fn push_focus_requests(&mut self, keys: Vec<String>)

Queue programmatic focus requests by widget key. Hosts call this once per frame with app.drain_focus_requests(). Each key is resolved during the next prepare against the rebuilt focus order; unmatched keys drop silently.

Source

pub fn push_scroll_requests(&mut self, requests: Vec<ScrollRequest>)

Queue programmatic scroll-to-row requests targeting virtual lists by key. Hosts call this once per frame with app.drain_scroll_requests(). Each request is consumed during the next prepare by the layout pass for the matching list, where viewport height and row heights are known. Unmatched list keys and out-of-range row indices drop silently.

Source

pub fn set_animation_mode(&mut self, mode: AnimationMode)

Switch animation pacing. Default is AnimationMode::Live. Headless render binaries should call this with AnimationMode::Settled so a single-frame snapshot reflects the post-animation visual without depending on integrator timing.

Source

pub fn pointer_wheel(&mut self, x: f32, y: f32, dy: f32) -> bool

Apply a wheel delta in logical pixels at (x, y). Routes to the deepest scrollable container under the cursor in the last laid-out tree. Returns true if the event landed on a scrollable (host should request_redraw so the next frame applies the new offset).

Source

pub fn poll_input(&mut self, now: Instant) -> Vec<UiEvent>

Drain time-driven input events whose deadline has passed (touch long-press today; later: hold-to-repeat, etc.). Hosts call this once per frame before dispatching pointer events. now is web_time::Instant rather than std::time::Instant so the signature compiles on wasm32 — web_time aliases to std on native, so existing native callers passing Instant::now() from std still work. See [aetna_core::RunnerCore::poll_input].

Source

pub fn draw<'pass>(&'pass self, pass: &mut RenderPass<'pass>)

Record draws into the host-managed render pass. Call after Self::prepare. Paint order follows the draw-op stream.

No backdrop sampling. This entry point cannot honor pass boundaries (the host owns the pass lifetime), so any BackdropSnapshot items in the paint stream are no-ops and any shader bound with samples_backdrop=true reads an undefined backdrop binding. Use Self::render for backdrop-aware rendering.

Source

pub fn render( &mut self, device: &Device, encoder: &mut CommandEncoder, target_tex: &Texture, target_view: &TextureView, msaa_view: Option<&TextureView>, load_op: LoadOp<Color>, )

Record draws into a host-supplied encoder, owning pass lifetimes ourselves so backdrop-sampling shaders can sample a snapshot of Pass A’s content.

The host hands us:

  • the encoder (we record into it),
  • the color target’s wgpu::Texture (used as copy_src when we snapshot it; must include COPY_SRC in its usage flags),
  • the corresponding wgpu::TextureView (we attach it to every render pass we begin), and
  • the LoadOp to use on the first pass — Clear(color) to clear behind us, Load to composite onto whatever was already in the target.

Multi-pass schedule when the paint stream contains a BackdropSnapshot:

  1. Pass A — every paint item before the snapshot, with the caller-supplied LoadOp.
  2. copy_texture_to_texture — target → snapshot.
  3. Pass B — paint items from the snapshot onward, with LoadOp::Load so Pass A’s pixels remain underneath.

Without a snapshot, this collapses to a single pass and is equivalent to Self::draw called inside a host-managed pass with the same LoadOp.

Auto Trait Implementations§

§

impl !Freeze for Runner

§

impl !RefUnwindSafe for Runner

§

impl Send for Runner

§

impl Sync for Runner

§

impl Unpin for Runner

§

impl UnsafeUnpin for Runner

§

impl !UnwindSafe for Runner

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

Source§

fn downcast(&self) -> &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> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
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.
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> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,