take Mutable Snapshot
Take a snapshot of the current value of all state objects that also allows the state to be changed and later atomically applied when MutableSnapshot.apply is called. The values are preserved until Snapshot.dispose is called on the result. The global state will either see all the changes made as one atomic change, when MutableSnapshot.apply is called, or none of the changes if the mutable state object is disposed before being applied.
The values in a snapshot can be modified by calling Snapshot.enter and then, in its lambda, modify any state object. The new values of the state objects will only become visible to the global state when MutableSnapshot.apply is called.
An active snapshot (after it is created but before Snapshot.dispose is called) requires resources to track the values in the snapshot. Once a snapshot is no longer needed it should disposed by calling Snapshot.dispose.
Leaving a snapshot active could cause hard to diagnose memory leaks as values are maintained by state objects for these unneeded snapshots. Take care to always call Snapshot.dispose on all snapshots when they are no longer needed.
A nested snapshot can be taken by calling Snapshot.takeNestedSnapshot, for a read-only snapshot, or MutableSnapshot.takeNestedMutableSnapshot for a snapshot that can be changed. Nested mutable snapshots are applied to the this, the parent snapshot, when their MutableSnapshot.apply is called. Their applied changes will be visible to in this snapshot but will not be visible other snapshots (including other nested snapshots) or the global state until this snapshot is applied by calling MutableSnapshot.apply.
Once MutableSnapshot.apply is called on this, the parent snapshot, all calls to MutableSnapshot.apply on an active nested snapshot will fail.
Changes to a mutable snapshot are isolated, using snapshot isolation, from all other snapshots. Their changes are only visible as global state or to new snapshots once MutableSnapshot.apply is called.
Applying a snapshot can fail if currently visible changes to the state object conflicts with a change made in the snapshot.
When in a mutable snapshot, takeMutableSnapshot creates a nested snapshot of the current mutable snapshot. If the current snapshot is read-only, an exception is thrown. The current snapshot is the result of calling currentSnapshot which is updated by calling Snapshot.enter which makes the Snapshot the current snapshot while in its lambda.
Composition uses mutable snapshots to allow changes made in a Composable functions to be temporarily isolated from the global state and is later applied to the global state when the composition is applied. If MutableSnapshot.apply fails applying this snapshot, the snapshot and the changes calculated during composition are disposed and a new composition is scheduled to be calculated again.
See also
Parameters
called when any state object is read in the lambda passed to Snapshot.enter or in the Snapshot.enter of any nested snapshots.
Composition, layout and draw use readObserver to implicitly subscribe to changes to state objects to know when to update.
called when a state object is created or just before it is written to the first time in the snapshot or a nested mutable snapshot. This might be called several times for the same object if nested mutable snapshots are created.
Composition uses writeObserver to track when a state object is modified during composition in order to invalidate the reads that have not yet occurred. This allows a single pass of composition for state objects that are written to before they are read (such as modifying the value of a dynamic ambient provider).