Alexander Maryanovsky
02/19/2022, 2:29 PMWindowState.position
of type WindowPosition
and WindowStateImpl
implements it as
override var position by mutableStateOf(position)
but from just looking at the WindowState
interface, there’s no way for you to know that position
can be observed.
Wouldn’t it better if the type of WindowState.position
was MutableState<WindowPosition>
?Adam Powell
02/19/2022, 2:32 PM[Mutable]State<T>
Adam Powell
02/19/2022, 2:33 PMAdam Powell
02/19/2022, 2:36 PMAlexander Maryanovsky
02/19/2022, 2:47 PMWindowState.position
was implemented as a regular property, things would break.Alexander Maryanovsky
02/19/2022, 2:48 PMAdam Powell
02/19/2022, 3:27 PM@Stable
Adam Powell
02/19/2022, 3:28 PM@Stable
or the compose-compiler plugin. Composition cares about @Stable
, and if any stable type can visibly change, it must invalidate via the snapshot mechanism when it does.Alexander Maryanovsky
02/19/2022, 3:35 PMAdam Powell
02/19/2022, 3:38 PMAdam Powell
02/19/2022, 3:39 PMWindowState
to call out in their documentation if their properties are snapshot-observable, but with compose it's more of a baseline assumption.Adam Powell
02/19/2022, 3:40 PMAdam Powell
02/19/2022, 3:40 PMAdam Powell
02/19/2022, 3:43 PMAdam Powell
02/19/2022, 3:43 PMIn the small, checked exceptions are very enticing. With a little example, you can show that you've actually checked that you caught the, and isn't that great? Well, that's fine when you're just calling one API. The trouble begins when you start building big systems where you're talking to four or five different subsystems. Each subsystem throws four to ten exceptions. Now, each time you walk up the ladder of aggregation, you have this exponential hierarchy below you of exceptions you have to deal with. You end up having to declare 40 exceptions that you might throw. And once you aggregate that with another subsystem you've got 80 exceptions in your throws clause. It just balloons out of control.FileNotFoundException
Alexander Maryanovsky
02/19/2022, 3:44 PMAdam Powell
02/19/2022, 3:45 PMThey're great in theory, but they're just too cumbersome in practice.Yes, exactly. Snapshots assert that the same is true of explicit state invalidation.
Adam Powell
02/19/2022, 3:47 PMAlexander Maryanovsky
02/19/2022, 3:47 PMAlexander Maryanovsky
02/19/2022, 3:48 PMAdam Powell
02/19/2022, 3:48 PMAlexander Maryanovsky
02/19/2022, 3:50 PMAdam Powell
02/19/2022, 3:50 PMAdam Powell
02/19/2022, 3:50 PMAlexander Maryanovsky
02/19/2022, 3:51 PMAdam Powell
02/19/2022, 3:52 PMAdam Powell
02/19/2022, 3:52 PMAlexander Maryanovsky
02/19/2022, 3:53 PMAlexander Maryanovsky
02/19/2022, 3:56 PMAdam Powell
02/19/2022, 4:01 PMAdam Powell
02/19/2022, 4:04 PMmutableStateOf<Float>
and similar.Adam Powell
02/19/2022, 4:08 PMAdam Powell
02/19/2022, 4:10 PMprivate var state by mutableStateOf(MyInternalState(a, b, c...))
and individual public properties might do something like
val a: A
get() = state.a
Adam Powell
02/19/2022, 4:12 PMAdam Powell
02/19/2022, 4:13 PMAdam Powell
02/19/2022, 4:15 PMval isLoggedIn: Boolean
get() = myRepository.user != null && authDelegate.token.isValid
or anything of the sortAdam Powell
02/19/2022, 4:16 PMAlexander Maryanovsky
02/19/2022, 4:19 PMAlexander Maryanovsky
02/19/2022, 4:20 PMAdam Powell
02/19/2022, 4:20 PMAlexander Maryanovsky
02/19/2022, 4:20 PMAdam Powell
02/19/2022, 4:20 PMAdam Powell
02/19/2022, 4:21 PMAlexander Maryanovsky
02/19/2022, 4:22 PMAdam Powell
02/19/2022, 4:22 PMAdam Powell
02/19/2022, 4:22 PMAdam Powell
02/19/2022, 4:23 PMAdam Powell
02/19/2022, 4:23 PMSnapshot.takeMutableSnapshot
Adam Powell
02/19/2022, 4:24 PMAdam Powell
02/19/2022, 4:24 PMAdam Powell
02/19/2022, 4:25 PMAdam Powell
02/19/2022, 4:25 PMAlexander Maryanovsky
02/19/2022, 4:26 PMwindow.state.position.x
and when I compile state
is a State and position
is immutable and then the library changes and state
is immutable and position
is a State, I need to recompile, no?Adam Powell
02/19/2022, 4:27 PMAdam Powell
02/19/2022, 4:27 PMwindow.state.position.x
is a call to a kotlin property getter method; that doesn't change.Adam Powell
02/19/2022, 4:27 PMAdam Powell
02/19/2022, 4:28 PMvar x: Int
private set
to
val x: Int
get() = position.x
private var position = Offset(0, 0)
Adam Powell
02/19/2022, 4:28 PMAlexander Maryanovsky
02/19/2022, 4:32 PMAdam Powell
02/19/2022, 4:35 PMAdam Powell
02/19/2022, 4:37 PMsnapshotFlow
here might help show how it works: https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/[…]oidx/compose/runtime/SnapshotFlow.kt;l=110?q=snapshotFlow&sq=Adam Powell
02/19/2022, 4:37 PMAdam Powell
02/19/2022, 4:38 PMcompose-runtime
, and do not include anything related to the compose-compiler
plugin, you can still use snapshotFlow
to listen for changes and Snapshot.withMutableSnapshot {}
to publish changesAdam Powell
02/19/2022, 4:42 PMAdam Powell
02/19/2022, 4:42 PMMutableState.value
's getterAdam Powell
02/19/2022, 4:43 PMreadable
utility method: https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/[…]x/compose/runtime/snapshots/Snapshot.kt;l=1638?q=overwritableAdam Powell
02/19/2022, 4:43 PMAlexander Maryanovsky
02/19/2022, 4:43 PM