Skip to main content

RouteOutlet

Struct RouteOutlet 

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

Mounts one Navigator as presentation-aware stack content.

The outlet owns the integration state the navigator cannot: per-route mount tags feeding the focus ownership oracle, a RouteFocusState driven across transitions, and one RouteTaskBinding per live route (lifetime-owned, including unmounted-but-alive routes). Use one outlet per navigator; nested navigators get nested outlets and stay isolated through disjoint tags and states.

Dropping the outlet releases the integration: focus records, bindings, and tags go with it (bound scopes then follow ordinary TaskScope ownership, detached from later removals).

State inventory (owner → invariant): navigator (cloned handle — identity and lifetimes live in navigation); focus, bindings, tags (outlet — pruned to live routes on every reconcile); nested/parent (attachment graph — weak both ways, single-parent, acyclic); driver (driving runtime — claimed on drive, released on detach or runtime drop); task_parent (host scope — never mutated); presented/pending (transition bookkeeping — advance only on commit); epoch (attempt context — one per driven frame); composing/consumed (composition record — receipted mounting builders only, promoted on success only); signaled (schedule memo — edge-triggered per revision); namespace/root_key (immutable construction identity); tag_sequence (monotonic, never reused); revision (invalidation generation — doubles as the drive counter); mount (attached element — cleared when it vanishes).

Implementations§

Source§

impl RouteOutlet

Source

pub fn new(navigator: &Navigator, task_parent: &TaskScope) -> Self

Hosts navigator, parenting route task scopes under task_parent (typically the window scope, so close still cancels through existing ownership).

Source

pub fn attach_nested( outlet: &Rc<RefCell<Self>>, nested: &Rc<RefCell<Self>>, ) -> Result<(), OutletAttachError>

Registers a directly nested outlet whose content mounts inside this outlet’s routes. Nested elements resolve to the nested outlet, so inner navigation can neither overwrite outer saved focus nor be restored over by it. Sibling outlets sharing only an ancestor need nothing: disjoint subtrees never attribute across. Transitivity follows containment — register each outlet with its direct parent.

Topology is enforced before any mutation, borrowing the back-dispatch lesson without coupling to it: self-attachment and cycles are rejected (cascade driving must terminate), and each outlet has at most one live parent (cascade driving visits every registered child, so a shared child would drive twice per frame). Re-registering with the same parent is an idempotent no-op; moving parents requires Self::detach_nested first. Registration holds weakly: dropping the nested outlet releases it, and dead entries prune on every present, so repeated replacement never grows metadata.

Source

pub fn detach_nested(outlet: &Rc<RefCell<Self>>, nested: &Rc<RefCell<Self>>)

Detaches a nested outlet. The child keeps its own records, bindings, and tags, but the parent’s cascade no longer drives it: a detached outlet receives no frame work even while application code retains its handle. Detach also releases the child’s driver claim, so ownership transfers cleanly — reattaching elsewhere (or driving it standalone, including under another runtime) claims anew. Detaching a non-child is a no-op.

Source

pub fn frame_drive_count(&self) -> u64

Frames driven through this outlet, cascade included. Each Self::present_frame on the driving root advances every participating outlet by exactly one. Reads the invalidation generation, which advances once per driven frame and needs no separate counter.

Source

pub fn nested_widget(nested: &Rc<RefCell<Self>>) -> Widget

Mounts a nested outlet’s widget with the required builder identity: a stable keyed boundary driven by the nested revision, so ancestor rebuilds retain the slot instead of remounting it. Hosts compose this inside outer route content instead of assembling stateful builders by hand; no nested attach is needed on top. Presenting the outer outlet drives the whole tree in one frame — nested outlets never need their own present_frame calls.

Source

pub fn attached_nested_count(&self) -> usize

Number of live nested attachments. Dead handles prune on every present; useful for hosts composing nested outlets dynamically.

Source

pub fn set_modal_route_scopes(&mut self, enabled: bool)

Returns the navigator this outlet hosts. Publishes each route’s ModalRoute to its content, so ModalRoute::of works inside routes. Off by default: the scope is an inherited (lazily built) node, so route content then validates when it mounts rather than before the outlet commits a rebuild, and a malformed route reports InvalidGeneratedChild instead of failing the rebuild atomically.

Source

pub fn modal_route_scopes(&self) -> bool

Source

pub fn navigator(&self) -> &Navigator

Source

pub fn id(&self) -> OutletId

Returns this outlet’s identity, for error data and host bookkeeping.

Source

pub fn needs_frame(&self) -> bool

Whether navigation arrived that no composition consumed yet — for this outlet or any nested outlet. True before the first composition with a non-empty stack, and after navigation newer than the last consumed snapshot (including navigation during a build, whose paint lags one frame behind the bookkeeping). False once composition consumes current state. Diagnostics and custom drivers only: ordinary hosts must not poll this for mandatory work — the scheduler flag from present_frame carries that. It does not report failed frames (their error return does that).

Source

pub fn attach( outlet: &Rc<RefCell<RouteOutlet>>, runtime: &mut Runtime, ) -> Result<(), OutletError>

Attaches the outlet to its mounted widget so Self::present_frame rebuilds outlet content every frame. Call once after mounting Self::widget: the mount element is located through the outlet root tag. Re-attaching replaces the previous builder harmlessly.

Attachment claims the outlet for runtime’s driver domain: an outlet nested under a live parent, or claimed by another live runtime, is rejected before mutation. Detach (nested) or drop the owning runtime (teardown releases) before attaching elsewhere.

use std::{cell::RefCell, rc::Rc};
use incular_config::Constraints;
use incular_core::{Color, Size};
use incular_navigation::{Navigator, Page};
use incular_runtime::{RouteOutlet, Runtime};
use incular_widgets::{Column, Widget};

let navigator = Navigator::new();
let mut runtime =
    Runtime::new(Column::new(Vec::<Widget>::new()).into()).unwrap();
let parent = runtime.spawner().scope();
let outlet = Rc::new(RefCell::new(RouteOutlet::new(&navigator, &parent)));
// One-time setup: mount the outlet widget, then attach its builder.
let root = runtime.tree().root().expect("root");
let outlet_for_build = outlet.clone();
runtime
    .register_builder(root, move || {
        Column::new(vec![outlet_for_build.borrow().widget()]).into()
    })
    .unwrap();
runtime
    .run_frame(Constraints::tight(Size::new(200., 200.)))
    .unwrap();
RouteOutlet::attach(&outlet, &mut runtime).unwrap();
navigator.push_page(Page::new("a", Widget::box_(Size::new(40., 40.), Color::WHITE)));
// The single recurring operation: rebuild, frame, reconcile.
let _frame =
    RouteOutlet::present_frame(&outlet, &mut runtime, Constraints::tight(Size::new(200., 200.)))
        .unwrap();
assert!(navigator.current().is_some());
Source

pub fn widget(&self) -> Widget

Builds the outlet widget: mounted routes in stack order with each route’s veil as a direct sibling preceding its content, so barrier semantics block every earlier route while the veiled route itself stays visible. The visible suffix paints from the top down to the first opaque page inclusive; retained but covered routes stay Builds the outlet widget for mounting, without touching any bookkeeping: safe to call speculatively and discard. Only the mounting builders (registered by attach, and nested slots) acknowledge what they accept. Covered routes without retention unmount (disposal); retained ones stay mounted inert while invisible; overlay entries are left for their portal host.

Source

pub fn route_task_scope(&self, route: RouteId) -> Option<TaskScope>

Returns the route task scope for spawning route-bound work, if the route is currently mounted and bound.

Source

pub fn present_frame( outlet: &Rc<RefCell<Self>>, runtime: &mut Runtime, constraints: Constraints, ) -> Result<(DisplayList, FrameStats), OutletError>

Presents one production frame through the outlet: validates the tree, captures any pending transition, rebuilds outlet content, runs layout, then commits the transition against the mounted tree. This is the supported recurring operation: the save runs before the frame reconciles (rebuilding may unmount covered content and the drain clears dead focus), while the restore runs after layout when targets are eligible.

Takes the outlet shared (rather than &mut self) because the attached builder reenters it immutably while the frame runs; short borrows never span the frame. Driving claims the whole tree for runtime: presenting a nested child directly, or through a second live runtime, fails before any mutation. A rebuild or frame failure keeps the pending capture for a safe retry instead of consuming the activation, and navigation mid-frame abandons the stale capture without touching committed records.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for S
where T: Real + Zero + Arithmetics + Clone, Swp: WhitePoint<T>, Dwp: WhitePoint<T>, D: AdaptFrom<S, Swp, Dwp, T>,

Source§

fn adapt_into_using<M>(self, method: M) -> D
where M: TransformMatrix<T>,

👎Deprecated since 0.7.7:

replaced by palette::chromatic_adaptation::AdaptIntoUnclamped

Convert the source color to the destination color using the specified method.
Source§

fn adapt_into(self) -> D

👎Deprecated since 0.7.7:

replaced by palette::chromatic_adaptation::AdaptIntoUnclamped

Convert the source color to the destination color using the bradford method by default.
Source§

impl<T, C> AdaptIntoUnclamped<T> for C
where T: AdaptFromUnclamped<C>,

Source§

type Scalar = <T as AdaptFromUnclamped<C>>::Scalar

The number type that’s used as the color’s components.
Source§

fn adapt_into_unclamped_with<M>(self) -> T

Adapt a color of type Self into a color of type T, using the custom matrix M. Read more
Source§

fn adapt_into_unclamped(self) -> T
where Bradford: LmsToXyz<Self::Scalar> + XyzToLms<Self::Scalar>,

Adapt a color of type Self into a color of type T, using the Bradford matrix. Read more
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, C> ArraysFrom<C> for T
where C: IntoArrays<T>,

Source§

fn arrays_from(colors: C) -> T

Cast a collection of colors into a collection of arrays.
Source§

impl<T, C> ArraysInto<C> for T
where C: FromArrays<T>,

Source§

fn arrays_into(self) -> C

Cast this collection of arrays into a collection of colors.
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<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for U
where T: FromCam16Unclamped<WpParam, U>,

Source§

type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar

The number type that’s used in parameters when converting.
Source§

fn cam16_into_unclamped( self, parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>, ) -> T

Converts self into C, using the provided parameters.
Source§

impl<T, C> ComponentsFrom<C> for T
where C: IntoComponents<T>,

Source§

fn components_from(colors: C) -> T

Cast a collection of colors into a collection of color components.
Source§

impl<T, C> ComponentsInto<C> for T

Source§

fn components_into(self) -> C

Cast this collection of color components into a collection of colors. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromAngle<T> for T

Source§

fn from_angle(angle: T) -> T

Performs a conversion from angle.
Source§

impl<T, U> FromStimulus<U> for T
where U: IntoStimulus<T>,

Source§

fn from_stimulus(other: U) -> T

Converts other into Self, while performing the appropriate scaling, rounding and clamping.
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, U> IntoAngle<U> for T
where U: FromAngle<T>,

Source§

fn into_angle(self) -> U

Performs a conversion into T.
Source§

impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for U
where T: Cam16FromUnclamped<WpParam, U>,

Source§

type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar

The number type that’s used in parameters when converting.
Source§

fn into_cam16_unclamped( self, parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>, ) -> T

Converts self into C, using the provided parameters.
Source§

impl<T, U> IntoColor<U> for T
where U: FromColor<T>,

Source§

fn into_color(self) -> U

Convert into T with values clamped to the color defined bounds Read more
Source§

impl<T, U> IntoColorUnclamped<U> for T
where U: FromColorUnclamped<T>,

Source§

fn into_color_unclamped(self) -> U

Convert into T. The resulting color might be invalid in its color space Read more
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> IntoStimulus<T> for T

Source§

fn into_stimulus(self) -> T

Converts self into T, while performing the appropriate scaling, rounding and clamping.
Source§

impl<T, C> TryComponentsInto<C> for T
where C: TryFromComponents<T>,

Source§

type Error = <C as TryFromComponents<T>>::Error

The error for when try_into_colors fails to cast.
Source§

fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>

Try to cast this collection of color components into a collection of colors. Read more
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, U> TryIntoColor<U> for T
where U: TryFromColor<T>,

Source§

fn try_into_color(self) -> Result<U, OutOfBounds<U>>

Convert into T, returning ok if the color is inside of its defined range, otherwise an OutOfBounds error is returned which contains the unclamped color. Read more
Source§

impl<C, U> UintsFrom<C> for U
where C: IntoUints<U>,

Source§

fn uints_from(colors: C) -> U

Cast a collection of colors into a collection of unsigned integers.
Source§

impl<C, U> UintsInto<C> for U
where C: FromUints<U>,

Source§

fn uints_into(self) -> C

Cast this collection of unsigned integers into a collection of colors.
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