Slides from Amanda Hinchman's and Jossi Wolf's talk "A Hitchhiker's Guide to Compose" given at Droidcon Berlin 2021. Make sure to check out 2022's updated version on our profiles!
a video game: it represents the state of your entire program at a single point in history." #hg2compose https://dev.to/zachklipp/introduction-to-the-compose-snapshot-system-19cn - "Introduction to the Compose Snapshot System" by Zach Klippenstein Snapshots 📸 (and dogs🐕) @mvndy_hd @jossiwolf
MutableState<T> : State<T> { override var value: T operator fun component1(): T operator fun component2(): (T) -> Unit } package androidx.compose.runtime @mvndy_hd @jossiwolf
the [snapshot]. * It is assumed that [this] is the first record of [state] */ fun <T : StateRecord> T.readable(state: StateObject, snapshot: Snapshot): T { // invoke the observer associated with the current snapshot. snapshot.readObserver ?. invoke(state) return readable(this, snapshot.id, snapshot.invalid) ?: readError() } package androidx.compose.runtime @mvndy_hd @jossiwolf
the [snapshot]. * It is assumed that [this] is the first record of [state] */ fun <T : StateRecord> T.readable(state: StateObject, snapshot: Snapshot): T { // invoke the observer associated with the current snapshot. snapshot.readObserver ?. invoke(state) return readable(this, snapshot.id, snapshot.invalid) ?: readError() } package androidx.compose.runtime @mvndy_hd @jossiwolf
} HelloWorld(greeting = name.value) } @Composable fun HelloWorld(greeting: String) { println("Hello, $greeting!") } #hg2compose S N A P S H O T @mvndy_hd @jossiwolf
- Generates tokens to create an AST - PSI lays over AST Resolution Codegen Resolution performed on AST tree - PSI gets enhanced with descriptors - Symbol table generated; associated node w/ descriptor via BindingTrace Frontend Backend - Takes optimized IR and performs more analysis, transformations + optimisations speci fi c to target CPU architecture - Multithreading Machine-Dependent Optimisations IR Transform Compiler Analysis Middle End “Lower” - Performs optimisations on IR - Removes dead code - Refactors the code - Improves performance - Analyzes IR for data needed to create - Call graph - Control- fl ow graph < > Bytecode Target Program FUN BLOCK_BODY CALL VAR IR Unoptimized IR Codegen IR to Bytecode Optimized IR FUN BLOCK_BODY CALL VAR IR Backend The Kotlin compiler @mvndy_hd @jossiwolf
- Generates tokens to create an AST - PSI lays over AST Resolution Codegen Resolution performed on AST tree - PSI gets enhanced with descriptors - Symbol table generated; associated node w/ descriptor via BindingTrace Frontend Backend - Takes optimized IR and performs more analysis, transformations + optimisations speci fi c to target CPU architecture - Multithreading Machine-Dependent Optimisations IR Transformations Compiler Analysis Middle End “Lower” - Performs optimisations on IR - Removes dead code - Refactors the code - Improves performance - Analyzes IR for data needed to create - Call graph - Control- fl ow graph < > Bytecode Target Program FUN BLOCK_BODY CALL VAR IR Unoptimized IR Codegen IR to Bytecode Optimized IR FUN BLOCK_BODY CALL VAR IR Backend Compose compiler plugin Backend - Takes optimized IR and performs more analysis, transformations + optimisations speci fi c to target CPU architecture - Multithreading Machine-Dependent Optimisations IR Transform Compiler Analysis Middle End “Lower” - Performs optimisations on IR - Removes dead code - Refactors the code - Improves performance - Analyzes IR for data needed to create - Call graph - Control- fl ow graph < > Bytecode Target Program FUN BLOCK_BODY CALL VAR IR Unoptimized IR Codegen IR to Bytecode Optimized IR FUN BLOCK_BODY CALL VAR IR Backend @mvndy_hd @jossiwolf
- Generates tokens to create an AST - PSI lays over AST Resolution Codegen Semantic Analysis performed on AST - PSI gets enhanced with descriptors - Symbol table generated; associated node w/ descriptor via BindingTrace Kotlin Compiler Frontend @mvndy_hd @jossiwolf
- Generates tokens to create an AST - PSI lays over AST Resolution Codegen Semantic Analysis performed on AST - PSI gets enhanced with descriptors - Symbol table generated; associated node w/ descriptor via BindingTrace Kotlin Compiler Frontend @mvndy_hd @jossiwolf
- Generates tokens to create an AST - PSI lays over AST Resolution Codegen Semantic Analysis performed on AST - PSI gets enhanced with descriptors - Symbol table generated; associated node w/ descriptor via BindingTrace Kotlin Compiler Frontend @mvndy_hd @jossiwolf
Performs optimisations on IR - Removes dead code - Refactors the code - Improves performance - Analyzes IR for data needed to create - Call graph - Control- fl ow graph Backend - Takes optimized IR and performs more analysis, transformations + optimisations speci fi c to target CPU architecture - Multithreading func() Optimized IR < > Bytecode Target Program @mvndy_hd @jossiwolf
Performs optimisations on IR - Removes dead code - Refactors the code - Improves performance - Analyzes IR for data needed to create - Call graph - Control- fl ow graph Backend - Takes optimized IR and performs more analysis, transformations + optimisations speci fi c to target CPU architecture - Multithreading func() Optimized IR < > Bytecode Target Program @mvndy_hd @jossiwolf
Bob!” var name by remember { mutableStateOf("Bob") } Slot Table by Example @Composable fun Greeting(greeting: String) { Text("Hello, $greeting!”) } Greeting(name) @mvndy_hd @jossiwolf
Jossi!” var name by remember { mutableStateOf("Bob") } @Composable fun Greeting(greeting: String) { Text("Hello, $greeting!”) } Greeting(name) name = "Jossi" Slot Table by Example @mvndy_hd @jossiwolf
onBeginChanges() {} fun onEndChanges() {} fun down(node: N) fun up() fun insertTopDown(index: Int, instance: N) fun insertBottomUp(index: Int, instance: N) fun remove(index: Int, count: Int) fun move(from: Int, to: Int, count: Int) fun clear() }