Skip to main content

BuildCtx

Struct BuildCtx 

Source
pub struct BuildCtx<'a> { /* private fields */ }
Expand description

Context threaded through View::build / View::rebuild.

Three responsibilities: allocating unique WidgetIds (it borrows the id counter owned by the render root so ids stay monotonic across passes), carrying the effective focus chain — whether every link from the root down to the node being built/rebuilt/torn down is focused (see BuildCtx::has_focus) — and carrying the element-replaced signal a same-typed element swap raises for its enclosing reconciler (see BuildCtx::mark_element_replaced).

Implementations§

Source§

impl<'a> BuildCtx<'a>

Source

pub fn new(next_id: &'a mut u64) -> Self

Create a context borrowing the render root’s id counter.

The focus chain seeds true — “unknown, assume live”. A caller that does not thread the chain therefore keeps the pre-chain behavior (every reconciler under it treats a focused pod as the live one) instead of silently suppressing a release it owed: over-releasing costs the user one tap, while under-releasing strands the shell’s IME surface over a widget that no longer exists and nothing on an idle screen ever corrects it (the same default-to-must-run rule the frame gate follows). The seams that know the real value — RenderRoot::rebuild’s view diff and ComponentWidget’s inner context — set it explicitly with BuildCtx::set_has_focus.

Source

pub fn alloc_id(&mut self) -> WidgetId

Allocate a fresh, unique widget id.

Source

pub fn has_focus(&self) -> bool

Whether the recorded focus path is live all the way from the root to the node currently being built/rebuilt/torn down — the rebuild-pass mirror of PaintCtx::has_focus, composed the same way (self.focused && ctx.has_focus()).

This is what makes a focused ChildPod flag deep inside a blurred branch harmless. A container-routed blur clears the focus link at the nearest common ancestor only, so flags below it legitimately go stale until focus next enters that subtree; a pod under a cleared link sees has_focus() == false here, exactly as it sees false in paint and exactly as focus-routed events never reach it. A reconciler therefore raises mark_focus_orphaned only when ctx.has_focus() && pod.is_focused() — only when the pod losing its identity is the one whose session is actually live.

Source

pub fn set_has_focus(&mut self, has_focus: bool)

Seed the effective focus chain (see BuildCtx::has_focus).

For the two kinds of seam that start a chain rather than descend one: RenderRoot’s view diff, which seeds it from the root’s own session mirror, and a component-style widget that builds an inner BuildCtx over its own id counter (ComponentWidget is the in-crate one) and must carry its outer chain across that boundary. A container descending into a child pod uses BuildCtx::with_focus_link instead — it can only narrow, which is what keeps this an AND-chain.

Run f with the focus chain extended by one link, restoring the caller’s chain when it returns.

link_focused is the descended-into pod’s own ChildPod::is_focused flag, so the closure sees self.has_focus() && link_focused: a cleared link anywhere above forces false for the whole subtree below it, and no descent can ever widen the chain. The rebuild-pass counterpart of ChildPod::paint_child’s set_has_focus(self.focused && ctx.has_focus()), in the scoped-closure shape SemanticsCtx::descend_into_pod already uses for the semantics pass.

Source

pub fn mark_element_replaced(&mut self)

Report that this view’s rebuild replaced its element’s widget while keeping the element type — an enum view switching arms (Either, EitherOf3 .. EitherOf8 in frust-widgets) is the shape this exists for.

A reconciler detects an AnyView concrete-type swap by comparing the boxed widget’s type id across the rebuild; on a swap it drops the child pod’s capture (active) and focus (focused) links, because the fresh widget never saw the Down and never claimed focus. An enum element keeps one static type across an arm swap, so that comparison cannot see it. Calling this makes the enclosing reconciler treat the rebuild exactly like a concrete-type swap.

Scope rule. The nearest enclosing track_element_replaced scope consumes the signal. An enum nested inline inside another enum (no pod between them) therefore propagates to the outer one’s scope — the same pod lost its widget — while a pod anywhere inside the swapped subtree runs its own scope and consumes its own signal, leaving the outer pod’s flags intact. A signal raised where no scope encloses it (a root-level enum, or a container that rebuilds a child without a pod) is inert or, at worst, reaches the next scope up: an over-release, never an under-release.

Source

pub fn track_element_replaced<R>( &mut self, f: impl FnOnce(&mut Self) -> R, ) -> (R, bool)

Run f as a tracking scope for mark_element_replaced, returning f’s result and whether anything inside it raised the signal.

The caller’s pending value is saved and cleared before f runs and restored afterwards, so a scope sees only signals raised inside it and a signal raised by an earlier sibling is neither consumed nor lost. A reconciler wraps each child’s nested rebuild in this and ORs the result into its own type-swap detection.

Auto Trait Implementations§

§

impl<'a> !UnwindSafe for BuildCtx<'a>

§

impl<'a> Freeze for BuildCtx<'a>

§

impl<'a> RefUnwindSafe for BuildCtx<'a>

§

impl<'a> Send for BuildCtx<'a>

§

impl<'a> Sync for BuildCtx<'a>

§

impl<'a> Unpin for BuildCtx<'a>

§

impl<'a> UnsafeUnpin for BuildCtx<'a>

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

Source§

fn as_borrowed(&self) -> &T

Borrows the value.
Source§

fn into_taken(self) -> T

Takes the value.
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.