InitialState

@ThreadSafe
class InitialState

The InitialStateContainer is a lookaside table used by a ComponentTree to create initial states for Components. The idea is that the onCreateInitialState result for each component will be cached and stored here so that we can guarantee it's not called multiple times on multiple threads. We keep the initial states cached as long as there is a layout happening for the ComponentTree. As soon as we detect that all in-flights layout have terminated we can clean up the initial states cache.

Locking discipline, as numbered invariants:

  • INV-1 (single monitor): every read or write of a Slot's contents happens inside synchronized(slot.lock) for the slot returned by this invocation's slotFor.

  • INV-2 (fetch-once): each public method calls slotFor exactly once, holds the result in a local, and never re-reads slots after acquiring the lock. Without this, a drain between the vend and the lock acquisition would let two threads hold different monitors over the same logical key.

  • INV-3 (co-drain): monitor and data are allocated together (Slot) and discarded together (slots = null), so a drain cannot go partial. Any future per-key cache belongs inside Slot, never beside it. A thread still holding a pre-drain Slot keeps writing to it and its seed is discarded rather than resurrected into the new epoch -- safe only because a registered StateHandler keeps pendingStateHandlers non-empty and so prevents the drain.

Constructors

Link copied to clipboard
constructor()

Functions

Link copied to clipboard
Link copied to clipboard
fun <T> getOrCreateInitialKStateByHookKey(key: GlobalKey, hookKey: HookKey, deps: Array<*>, initializer: HookInitializer<T>, componentName: String): ComponentState<KStateContainer>

If an initial state for this component has already been created just return it, otherwise execute the initializer and cache the result. Uses HookKey-based identity instead of sequential index. The state is stored in a map-based KStateContainer.

Link copied to clipboard

A snapshot of the hook-identity seeds cached for key, keyed by HookKey; empty when nothing has been seeded for key.

Link copied to clipboard

True when nothing is cached for any key, in any storage.

Link copied to clipboard
fun <T> peekOrSeedInitialKStateByHookKey(key: GlobalKey, hookKey: HookKey, deps: Array<*>, initializer: HookInitializer<T>, componentName: String): CachedValue

Looks up the initial value for hookKey in the lookaside cache, with a deps-equivalence guard.

Link copied to clipboard

Called when the ComponentTree creates a new StateHandler for a new layout computation. We keep track of this new StateHandler so that we know that we need to wait for this layout computation to finish before we can clear the initial states map.

Link copied to clipboard

Called when a resolve or layout computation finishes and its result has been committed or discarded. Removes the StateHandler from the pending set and clears the cached initial states if no other computations are in-flight.