pub struct Composer { /* private fields */ }Expand description
The state of one composition pass. It writes the slot table and queues node changes for the
applier. Clones share the same pass. Composable functions reach the current composer through
with_current_composer.
Implementations§
Source§impl Composer
impl Composer
Sourcepub fn new(
slots: Rc<SlotsHost>,
applier: Rc<dyn ApplierHost>,
runtime: RuntimeHandle,
root: Option<NodeId>,
) -> Self
pub fn new( slots: Rc<SlotsHost>, applier: Rc<dyn ApplierHost>, runtime: RuntimeHandle, root: Option<NodeId>, ) -> Self
Creates a composer that writes into slots and queues node changes for applier. Top-level
nodes attach under root, or have no parent when root is None.
Sourcepub fn active_slots_host(&self) -> Rc<SlotsHost>
pub fn active_slots_host(&self) -> Rc<SlotsHost>
Returns the slot table host that receives this composer’s writes: the innermost host set up for a subcomposition, otherwise the composition’s own.
Sourcepub fn record_rebound_slot_children(&self, children: &[NodeId])
pub fn record_rebound_slot_children(&self, children: &[NodeId])
Records nodes whose retained subtrees a reused subcompose slot just rebound to new content.
The rebinding recomposes inline during measure, so every repass it schedules is consumed by the layout pass already running — nothing else survives to tell the scoped scene update these subtrees changed, and a translate-only update would keep their stale layers (measured: a 60pt lazy scroll presented the old row’s text at the new row’s position). The structural-change set is the one channel drained after layout, so the rebound children ride it.
Sourcepub fn register_virtual_node(
&self,
node_id: NodeId,
node: Box<dyn Node>,
) -> Result<(), NodeError>
pub fn register_virtual_node( &self, node_id: NodeId, node: Box<dyn Node>, ) -> Result<(), NodeError>
Registers a virtual node in the Applier.
Assigns the node’s ID so its layout registry and invalidation metadata belong to the node stored in the applier.
Sourcepub fn dispose_subcomposed_nodes(
&self,
disposal: SubcomposeDisposal,
) -> Result<(), NodeError>
pub fn dispose_subcomposed_nodes( &self, disposal: SubcomposeDisposal, ) -> Result<(), NodeError>
Detaches and disposes subcomposition roots evicted from their reuse pool. Applies pending composition commands before releasing the roots and their descendants.
let evicted = state.finish_pass();
composer.dispose_subcomposed_nodes(evicted)?;Sourcepub fn node_has_no_parent(&self, node_id: NodeId) -> bool
pub fn node_has_no_parent(&self, node_id: NodeId) -> bool
Checks if a node has no parent (is a root node). Used by SubcomposeMeasureScope to filter subcompose results.
Sourcepub fn node_parent(&self, node_id: NodeId) -> Result<Option<NodeId>, NodeError>
pub fn node_parent(&self, node_id: NodeId) -> Result<Option<NodeId>, NodeError>
Returns a node’s parent, or None for a root node.
Returns an error when the node is no longer present in the applier.
Sourcepub fn get_node_children(&self, node_id: NodeId) -> SmallVec<[NodeId; 8]>
pub fn get_node_children(&self, node_id: NodeId) -> SmallVec<[NodeId; 8]>
Gets the children of a node from the Applier.
This is used by SubcomposeLayoutNode to get children of virtual nodes directly from the Applier, where insert_child commands have been applied.
Sourcepub fn nodes_need_relayout(
&self,
node_ids: impl IntoIterator<Item = NodeId>,
) -> bool
pub fn nodes_need_relayout( &self, node_ids: impl IntoIterator<Item = NodeId>, ) -> bool
Whether any node needs measurement or placement before its cached layout can be reused.
!composer.nodes_need_relayout(children.iter().copied())Sourcepub fn record_subcompose_child(&self, child_id: NodeId)
pub fn record_subcompose_child(&self, child_id: NodeId)
Records a child node in the current parent frame’s expected children list.
Used by SubcomposeLayout’s perform_subcompose to register virtual nodes
with the outer composer’s parent frame. This ensures that the pop_parent
call at the end of subcompose_slot generates a correct SyncChildren
command that preserves (rather than removes) the virtual nodes.
Without this, pop_parent would generate SyncChildren { expected: [] },
which removes all virtual nodes and their subtrees from the applier.
Sourcepub fn clear_node_children(&self, node_id: NodeId)
pub fn clear_node_children(&self, node_id: NodeId)
Clears all children of a node in the Applier.
This is used by SubcomposeLayoutNode when reusing a virtual node for different content. Without clearing, old children remain attached, causing duplicate/interleaved items in lazy lists after scrolling.
Sourcepub fn install<R>(&self, f: impl FnOnce(&Composer) -> R) -> R
pub fn install<R>(&self, f: impl FnOnce(&Composer) -> R) -> R
Runs f with this composer as the current one and its runtime as the active runtime. Both
are restored when f returns.
Sourcepub fn with_group<R>(&self, key: Key, f: impl FnOnce(&Composer) -> R) -> R
pub fn with_group<R>(&self, key: Key, f: impl FnOnce(&Composer) -> R) -> R
Runs f in a group identified by key. Slots and nodes that f creates belong to the
group.
Sourcepub fn cranpose_with_reuse<R>(
&self,
key: Key,
options: RecomposeOptions,
f: impl FnOnce(&Composer) -> R,
) -> R
pub fn cranpose_with_reuse<R>( &self, key: Key, options: RecomposeOptions, f: impl FnOnce(&Composer) -> R, ) -> R
Runs f in a group identified by key that is retained when it leaves the composition,
with the recompose options applied to its scope. A retained group returns with its state
and nodes when key is composed again.
Sourcepub fn with_key<K: Hash, R>(&self, key: &K, f: impl FnOnce(&Composer) -> R) -> R
pub fn with_key<K: Hash, R>(&self, key: &K, f: impl FnOnce(&Composer) -> R) -> R
Runs f in a group identified by the hash of key, so state and nodes follow the key when
siblings move. Compose’s key.
Sourcepub fn remember<T: 'static>(&self, init: impl FnOnce() -> T) -> Owned<T>
pub fn remember<T: 'static>(&self, init: impl FnOnce() -> T) -> Owned<T>
Returns the value init made on the first composition at this call site. Later compositions
return the same value until the call site leaves the composition.
Sourcepub fn use_value_slot<T: 'static>(
&self,
init: impl FnOnce() -> T,
) -> ValueSlotHandle<'_, T>
pub fn use_value_slot<T: 'static>( &self, init: impl FnOnce() -> T, ) -> ValueSlotHandle<'_, T>
Reserves the next slot at the call site for a T that init makes on the first
composition. Returns a handle for reading the value through with_slot_value.
Sourcepub fn with_slot_value<'pass, T: 'static, R>(
&'pass self,
handle: ValueSlotHandle<'pass, T>,
f: impl FnOnce(&T) -> R,
) -> R
pub fn with_slot_value<'pass, T: 'static, R>( &'pass self, handle: ValueSlotHandle<'pass, T>, f: impl FnOnce(&T) -> R, ) -> R
Runs f with a shared reference to the value in the slot that handle names.
Sourcepub fn with_slot_value_mut<'pass, T: 'static, R>(
&'pass self,
handle: ValueSlotHandle<'pass, T>,
f: impl FnOnce(&mut T) -> R,
) -> R
pub fn with_slot_value_mut<'pass, T: 'static, R>( &'pass self, handle: ValueSlotHandle<'pass, T>, f: impl FnOnce(&mut T) -> R, ) -> R
Runs f with a mutable reference to the value in the slot that handle names.
Sourcepub fn mutable_state_of<T: Clone + 'static>(
&self,
initial: T,
) -> MutableState<T>
pub fn mutable_state_of<T: Clone + 'static>( &self, initial: T, ) -> MutableState<T>
Creates a MutableState holding initial, tied to this composer’s runtime. It is not
remembered, so each call makes a new state.
Sourcepub fn mutable_state_list_of<T, I>(&self, values: I) -> SnapshotStateList<T>where
T: Clone + 'static,
I: IntoIterator<Item = T>,
pub fn mutable_state_list_of<T, I>(&self, values: I) -> SnapshotStateList<T>where
T: Clone + 'static,
I: IntoIterator<Item = T>,
Creates a snapshot-aware list holding values, tied to this composer’s runtime. It is not
remembered, so each call makes a new list.
Sourcepub fn mutable_state_map_of<K, V, I>(&self, pairs: I) -> SnapshotStateMap<K, V>
pub fn mutable_state_map_of<K, V, I>(&self, pairs: I) -> SnapshotStateMap<K, V>
Creates a snapshot-aware map holding pairs, tied to this composer’s runtime. It is not
remembered, so each call makes a new map.
Sourcepub fn read_composition_local<T: Clone + 'static>(
&self,
local: &CompositionLocal<T>,
) -> T
pub fn read_composition_local<T: Clone + 'static>( &self, local: &CompositionLocal<T>, ) -> T
Returns the value of local from the innermost enclosing provider, or the local’s default
value when no provider is in scope.
Sourcepub fn read_static_composition_local<T: Clone + 'static>(
&self,
local: &StaticCompositionLocal<T>,
) -> T
pub fn read_static_composition_local<T: Clone + 'static>( &self, local: &StaticCompositionLocal<T>, ) -> T
Returns the value of local from the innermost enclosing provider, or the local’s default
value when no provider is in scope.
Sourcepub fn current_recompose_scope(&self) -> Option<RecomposeScope>
pub fn current_recompose_scope(&self) -> Option<RecomposeScope>
Returns the recompose scope being composed, or None outside any scope.
Sourcepub fn enter_phase(&self, phase: Phase)
pub fn enter_phase(&self, phase: Phase)
Switches the composer to phase.
Sourcepub fn subcompose_measurement<R>(
&self,
state: &mut SubcomposeState,
slot_id: SlotId,
content: impl FnOnce(&Composer) -> R,
) -> (R, Vec<NodeId>)
pub fn subcompose_measurement<R>( &self, state: &mut SubcomposeState, slot_id: SlotId, content: impl FnOnce(&Composer) -> R, ) -> (R, Vec<NodeId>)
Composes content in the slot slot_id of state and returns its result with the ids of
the nodes it produced that have no parent. Panics outside the measure and layout phases.
Sourcepub fn subcompose_in<R>(
&self,
slots: &Rc<SlotsHost>,
root: Option<NodeId>,
f: impl FnOnce(&Composer) -> R,
) -> Result<R, NodeError>
pub fn subcompose_in<R>( &self, slots: &Rc<SlotsHost>, root: Option<NodeId>, f: impl FnOnce(&Composer) -> R, ) -> Result<R, NodeError>
Composes f as an independent pass over the separate slot table slots and applies its
node changes before returning. Top-level nodes from f attach under root, if any. The
pass sees the composition locals in scope at the call.
Sourcepub fn capture_composition_context(&self) -> CapturedCompositionContext
pub fn capture_composition_context(&self) -> CapturedCompositionContext
Captures the composition context at the current point so work composed in another slot host inherits both locals and source ownership.
A SubcomposeLayout captures this while it is being composed and replays
it while subcomposing off the measure pass, so content that is
subcomposed during layout observes the same composition locals as the
SubcomposeLayout call site — matching Jetpack Compose, where a
subcomposition inherits the composition locals of the layout that
created it rather than whatever happens to be in scope during measure
(which, after composition unwinds, no longer carries ancestor providers).
Sourcepub fn with_locals_changed<R>(
&self,
changed: bool,
f: impl FnOnce(&Composer) -> R,
) -> R
pub fn with_locals_changed<R>( &self, changed: bool, f: impl FnOnce(&Composer) -> R, ) -> R
Runs f as content under a static composition local that changed
when changed: every group it opens runs its body, as under the
provider of a changed static local.
Sourcepub fn subcompose_slot<R>(
&self,
slots: &Rc<SlotsHost>,
root: Option<NodeId>,
f: impl FnOnce(&Composer) -> R,
) -> Result<(R, Vec<RecomposeScope>), NodeError>
pub fn subcompose_slot<R>( &self, slots: &Rc<SlotsHost>, root: Option<NodeId>, f: impl FnOnce(&Composer) -> R, ) -> Result<(R, Vec<RecomposeScope>), NodeError>
Subcomposes content using an isolated SlotsHost without resetting it.
Unlike subcompose_in, this preserves existing slot state across calls,
allowing efficient reuse during measurement passes. This is critical for
lazy lists where items need stable slot positions.
Sourcepub fn subcompose_slot_with_context<R>(
&self,
slots: &Rc<SlotsHost>,
root: Option<NodeId>,
context: &CapturedCompositionContext,
f: impl FnOnce(&Composer) -> R,
) -> Result<(R, Vec<RecomposeScope>), NodeError>
pub fn subcompose_slot_with_context<R>( &self, slots: &Rc<SlotsHost>, root: Option<NodeId>, context: &CapturedCompositionContext, f: impl FnOnce(&Composer) -> R, ) -> Result<(R, Vec<RecomposeScope>), NodeError>
Like Composer::subcompose_slot, but uses a context captured at the
source composition site. This is required for measure-time composition,
where the source scope is no longer on the active stack.
Sourcepub fn skip_current_group(&self)
pub fn skip_current_group(&self)
Skips the currently open group without running it again. Its nodes and remembered values stay as the last composition left them.
Sourcepub fn runtime_handle(&self) -> RuntimeHandle
pub fn runtime_handle(&self) -> RuntimeHandle
Returns a handle to the runtime of this composer.
Sourcepub fn set_recompose_callback<F>(&self, callback: F)
pub fn set_recompose_callback<F>(&self, callback: F)
Registers callback as the code that recomposes the current scope when state it read
changes. Does nothing outside a recompose scope.
Sourcepub fn set_recompose_fn(&self, callback: fn(&Composer))
pub fn set_recompose_fn(&self, callback: fn(&Composer))
Like set_recompose_callback for a plain function pointer.
Sourcepub fn with_composition_locals<R>(
&self,
provided: impl IntoIterator<Item = ProvidedValue>,
site: Key,
f: impl FnOnce(&Composer) -> R,
) -> R
pub fn with_composition_locals<R>( &self, provided: impl IntoIterator<Item = ProvidedValue>, site: Key, f: impl FnOnce(&Composer) -> R, ) -> R
Runs f with provided in scope over the locals around it; of values
for one local, the last wins.
Source§impl Composer
impl Composer
Sourcepub fn use_state<T: Clone + 'static>(
&self,
init: impl FnOnce() -> T,
) -> MutableState<T>
pub fn use_state<T: Clone + 'static>( &self, init: impl FnOnce() -> T, ) -> MutableState<T>
Returns a MutableState holding the value init made on the first composition at this
call site. Later compositions return the same state, so its value survives recomposition.
Sourcepub fn emit_node<N: Node + 'static>(&self, init: impl FnOnce() -> N) -> NodeId
pub fn emit_node<N: Node + 'static>(&self, init: impl FnOnce() -> N) -> NodeId
Emits a node of type N as a child of the current parent and returns its id. The first
composition at this call site calls init to make the node. Later compositions reuse that
node and do not call init.
Sourcepub fn emit_recyclable_node<N: Node + 'static>(
&self,
init: impl FnOnce() -> N,
reset: impl FnOnce(&mut N),
) -> NodeId
pub fn emit_recyclable_node<N: Node + 'static>( &self, init: impl FnOnce() -> N, reset: impl FnOnce(&mut N), ) -> NodeId
Emits a node of type N as emit_node does, reusing a pooled node when one exists. A
pooled N is cleared by reset, and otherwise init makes a new node.
Sourcepub fn with_node_mut<N: Node + 'static, R>(
&self,
id: NodeId,
f: impl FnOnce(&mut N) -> R,
) -> Result<R, NodeError>
pub fn with_node_mut<N: Node + 'static, R>( &self, id: NodeId, f: impl FnOnce(&mut N) -> R, ) -> Result<R, NodeError>
Runs f on the node id as an N. Returns an error if the node does not exist or is not
an N.
Sourcepub fn push_parent(&self, id: NodeId)
pub fn push_parent(&self, id: NodeId)
Makes the node id the parent of the nodes emitted next. Each call needs a matching
pop_parent.
Sourcepub fn compose_no_children(&self, id: NodeId, holds_children: bool)
pub fn compose_no_children(&self, id: NodeId, holds_children: bool)
Composes nothing under node id, which holds children when
holds_children: the parent frame Composer::push_parent and
Composer::pop_parent would open and close around nothing is left
out where closing it would sync nothing, which is outside a
subcomposition for a node that holds no children.
Sourcepub fn pop_parent(&self)
pub fn pop_parent(&self)
Closes the parent opened by the matching push_parent and sets that node’s children to the
nodes emitted since.
Sourcepub fn apply_pending_commands(&self) -> Result<(), NodeError>
pub fn apply_pending_commands(&self) -> Result<(), NodeError>
Applies any pending applier commands and runtime updates.
This is useful during measure-time subcomposition to ensure newly created nodes are available for measurement before the full composition is committed.
Sourcepub fn register_side_effect(&self, effect: impl FnOnce() + 'static)
pub fn register_side_effect(&self, effect: impl FnOnce() + 'static)
Queues effect to run after this pass has applied its node changes.
Sourcepub fn take_side_effects(&self) -> Vec<Box<dyn FnOnce()>>
pub fn take_side_effects(&self) -> Vec<Box<dyn FnOnce()>>
Removes and returns the side effects queued during this pass.