Skip to main content

SubcomposeState

Struct SubcomposeState 

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

Tracks the state of nodes produced by subcomposition, enabling reuse between measurement passes.

Implementations§

Source§

impl SubcomposeState

Source

pub fn new(policy: Box<dyn SlotReusePolicy>) -> Self

Creates a new SubcomposeState using the supplied reuse policy.

Source

pub fn set_policy(&mut self, policy: Box<dyn SlotReusePolicy>)

Sets the policy used for future reuse decisions.

Source

pub fn set_reusable_pool_limits(&mut self, per_type: usize, untyped: usize)

Source

pub fn register_content_type(&mut self, slot_id: SlotId, content_type: u64)

Registers a content type for a slot.

Stores the content type locally for efficient pool-based reuse lookup, and also delegates to the policy for compatibility checking.

Call this before subcomposing an item to enable content-type-aware slot reuse.

Source

pub fn update_content_type( &mut self, slot_id: SlotId, content_type: Option<u64>, )

Updates the content type for a slot, handling optional content types.

If content_type is Some(type), registers the type for the slot. If content_type is None, removes any previously registered type. This ensures stale types don’t drive incorrect reuse.

Source

pub fn get_content_type(&self, slot_id: SlotId) -> Option<u64>

Returns the content type for a slot, if registered.

Source

pub fn begin_pass(&mut self)

Starts a new subcompose pass.

Call this before subcomposing the current frame so the state can track which slots are active and dispose the inactive ones later.

Source

pub fn active_slot_cursor(&self) -> usize

Returns the current active slot cursor for the in-progress pass.

Source

pub fn restore_active_slot_cursor(&mut self, cursor: usize)

Restores the active slot cursor for work that should not become part of the rendered active set, such as lazy-list prefetch measurement.

Source

pub fn recycle_active_slot(&mut self, slot_id: SlotId) -> Vec<NodeId>

Moves an active slot out of the rendered set and into the reusable pool.

Source

pub fn recycle_prefetched_active_slot(&mut self, slot_id: SlotId) -> Vec<NodeId>

Source

pub fn recycle_active_slots_where( &mut self, predicate: impl FnMut(SlotId) -> bool, ) -> Vec<NodeId>

Source

pub fn finish_pass(&mut self) -> Vec<NodeId>

Finishes a subcompose pass, disposing slots that were not used.

Source

pub fn get_or_create_slots(&mut self, slot_id: SlotId) -> Rc<SlotsHost>

Returns the SlotsHost for the given slot ID, creating a new one if it doesn’t exist. Each slot gets its own isolated slot table, avoiding cursor-based conflicts when items are subcomposed in different orders.

Source

pub fn callback_holder(&mut self, slot_id: SlotId) -> CallbackHolder

Returns the latest callback holder for the given slot, creating one if needed.

Source

pub fn has_pending_precompositions(&self, slot_id: SlotId) -> bool

Whether precomposed nodes are waiting to be consumed for this slot. A pending precomposition means the retained mapping is about to be superseded, so clean-slot reuse must reject and compose.

Source

pub fn retained_capture_key_matches<K: PartialEq + 'static>( &self, slot_id: SlotId, key: &K, ) -> bool

Whether the slot’s stored capture key equals key. A missing key never matches: a slot must compose at least once under the key discipline before it may skip.

Source

pub fn store_retained_capture_key<K: PartialEq + 'static>( &mut self, slot_id: SlotId, key: K, )

Records the capture key the slot is being composed under.

Source

pub fn register_active( &mut self, slot_id: SlotId, node_ids: &[NodeId], scopes: &[RecomposeScope], )

Records that the nodes in node_ids are currently rendering the provided slot_id.

Source

pub fn register_precomposed(&mut self, slot_id: SlotId, node_id: NodeId)

Stores a precomposed node for the provided slot. Precomposed nodes stay detached from the tree until they are activated by register_active.

Source

pub fn take_node_from_reusables( &mut self, slot_id: SlotId, ) -> Option<(NodeId, bool)>

Returns the node that previously rendered this slot, if it is still considered reusable, and whether it was REBOUND — taken from another slot, so its retained subtree is about to show different content. An exact-slot reactivation hands the same item its own subtree back and is not a rebinding.

Lookup order:

  1. Exact slot match in the appropriate pool (not a rebinding)
  2. Any policy-compatible node from the same content-type pool
  3. Fallback to untyped pool with policy compatibility check
Source

pub fn dispose_or_reuse_starting_from_index( &mut self, start_index: usize, ) -> Vec<NodeId>

Moves active slots starting from start_index to the reusable bucket. Returns the list of node ids that were DISPOSED (not just moved to reusable). Nodes that exceed max_reusable_per_type are disposed instead of cached.

Source

pub fn reusable(&self) -> Vec<NodeId>

Returns a snapshot of currently reusable nodes.

Source

pub fn active_slots_count(&self) -> usize

Returns the number of slots currently active (in use during this pass).

This reflects the slots that were activated via register_active() during the current measurement pass.

Source

pub fn reusable_slots_count(&self) -> usize

Returns the number of reusable slots in the pool.

These are slots that were previously active but are now available for reuse by compatible content types.

Source

pub fn invalidate_scopes(&self)

Invalidates all tracked subcomposition scopes.

Hosts should call this when parent-captured inputs change without directly invalidating the child scopes themselves. The next subcompose pass will then re-run active slot content instead of skipping with stale captures. Invalidating scopes alone is not a reliable “recompose on next measure” signal: the recomposer drains invalid scopes before measure runs, re-executing the RETAINED slot callbacks — parent-captured values baked into a replaced closure never flow in, yet the scopes come back valid. The generation bump is the unlaunderable half: only a measure-time compose of the slot brings it current, so clean-slot reuse stays blocked until the new content actually landed.

Source

pub fn bump_content_generation(&self)

Advances the content generation without invalidating scopes: every slot must re-compose once before clean-slot reuse may skip it again. Called when the owning node leaves its parent — a retained subtree that comes back from the reuse pool restarts its effects only if its slots actually recompose, and scope flags carry no durable trace of the detach (deactivation walks stop at nested slot-host boundaries).

Source

pub fn slot_content_generation_current( &self, slot_id: SlotId, owner_epoch: u64, ) -> bool

Whether the slot last composed under the current content generation and owner-chain deactivation epoch. False after any Self::invalidate_scopes, and false after any composition up the owner chain was deactivated, until a measure-time compose of this slot runs.

Source

pub fn mark_slot_composed_current(&mut self, slot_id: SlotId, owner_epoch: u64)

Records that the slot just composed under the current generation and the given owner-chain deactivation epoch.

Source

pub fn was_last_slot_reused(&self) -> Option<bool>

Returns whether the last slot registered via Self::register_active was reused.

Returns Some(true) if the slot already existed (was reused from pool or was recomposed), Some(false) if it was newly created, or None if no slot has been registered yet this pass.

This is useful for tracking composition statistics in lazy layouts.

Source

pub fn precomposed(&self) -> &HashMap<SlotId, Vec<NodeId>>

Returns a snapshot of precomposed nodes.

Source

pub fn drain_inactive_precomposed(&mut self) -> Vec<NodeId>

Removes any precomposed nodes whose slots were not activated during the current pass and returns their identifiers for disposal.

Trait Implementations§

Source§

impl Debug for SubcomposeState

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for SubcomposeState

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

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, 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.