Last active
May 23, 2022 11:28
-
-
Save zach-klippenstein/cbcfa3e1076ec0fa088d0bed87369080 to your computer and use it in GitHub Desktop.
Sample code for my "Implementing snapshot-aware data structures" blog post.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import androidx.compose.runtime.mutableStateOf | |
import kotlin.test.assertEquals | |
import org.junit.Test | |
class SnapshotStateObjectWalkthrough { | |
@Test | |
fun walkthrough() { | |
// Code not running in an explicit snapshot is | |
// considered to be in the "global snapshot". | |
val message = mutableStateOf("") | |
// Create a snapshot that is a child of the global snapshot. | |
val snapA = Snapshot.takeMutableSnapshot() | |
snapA.enter { | |
message.value += "Hello" | |
// Changes performed inside a snapshot are | |
// immediately visible within that snapshot. | |
assertEquals("Hello", message.value) | |
} | |
// Any changes performed in a snapshot are not visible | |
// to its parent snapshot or any other snapshots until the | |
// snapshot is applied. | |
assertEquals("", message.value) | |
// Create another snapshot. Since this is outside the | |
// snapA.enter, it's a child of the global snapshot, | |
// and isolated from snapA. | |
val snapB = Snapshot.takeMutableSnapshot() | |
snapB.enter { | |
message.value += "world" | |
assertEquals("world", message.value) | |
} | |
assertEquals("", message.value) | |
// Because we never disposed snapA, we can re-enter | |
// it and see the world as it was at the end of the last | |
// enter call. | |
snapA.enter { | |
message.value += " friend" | |
assertEquals("Hello friend", message.value) | |
} | |
// And still, nothing is visible outside the snapshot. | |
assertEquals("", message.value) | |
// Now we're done with snapA, so let's apply it… | |
snapA.apply() | |
// …and cleanup after it. | |
snapA.dispose() | |
// And now all its changes are visible to the parent, i.e. | |
// the global snapshot! | |
assertEquals("Hello friend", message.value) | |
// We don't care about snapB anymore, so let's | |
// just dispose it without applying. It will be as if it | |
// never existed, and none of the changes it made ever | |
// happened. | |
snapB.dispose() | |
// Create one more new snapshot. | |
val snapC = Snapshot.takeMutableSnapshot() | |
snapC.enter { | |
message.value = "goodbye" | |
} | |
snapC.apply() | |
snapC.dispose() | |
assertEquals("goodbye", message.value) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment