dimsuz
12/16/2021, 5:39 PMfun main() {
var state by mutableStateOf(value = "30")
application {
Window {
Button(onClick = { state = "1"; state = "2"}) {
println("got $state")
Text(state)
}
}
}
}
Debugger shows that shapshot system sees all values, but recompositionRunner
never receives the "1" value. Are there some optimizations in Snapshot.apply
method maybe? What should one do to receive all state updates (or is this impossible/wrong)?Zach Klippenstein (he/him) [MOD]
12/16/2021, 8:15 PMdimsuz
12/16/2021, 8:46 PM***o
-> oooo
while state goes
digits = [1,1,1,0]
digits = [1,1,1,1]
digits = [0,0,0,0]
last two get "conflated" because, as you've explained they fit into one frame update. While we would like that user would see all three states rendered, including the fully filled one.
I wonder what would the correct solution be here. We could always add some arbitrary delay, but this doesn't feel right.Alex Vanyo
12/16/2021, 9:47 PMwe would like that user would see all three states rendered, including the fully filled one.How long would you want the user to see the fully filled state?
Zach Klippenstein (he/him) [MOD]
12/16/2021, 10:11 PMAlex Vanyo
12/16/2021, 10:14 PMdimsuz
12/16/2021, 10:14 PMwhat happens if they enter the first digit of the pincode after just 200msright! I've also thought in this direction, that if this has to be a delay, it has to be "smart" 🙂
Alex Vanyo
12/16/2021, 10:29 PMclass PasscodeState {
var firstDigit by mutableStateOf(false)
private set
var secondDigit by mutableStateOf(false)
private set
var thirdDigit by mutableStateOf(false)
private set
var fourthDigit by mutableStateOf(false)
private set
private val mutatorMutex = MutatorMutex()
suspend fun inputDigit() {
mutatorMutex.mutate {
if (!firstDigit) {
firstDigit = true
} else if (!secondDigit) {
secondDigit = true
} else if (!thirdDigit) {
thirdDigit = true
} else {
fourthDigit = true
try {
delay(500)
} finally {
firstDigit = false
secondDigit = false
thirdDigit = false
fourthDigit = false
}
}
}
}
}
block
passed to MutatorMutex.mutate
running at a time. Just like a normal mutex, it is guarding setting any of the digit state.
MutatorMutex
also has the feature that a second call while there is an existing one running will cancel the old call (the priority controls exactly when).
So in this case, when we set the fourth digit to true, we plan to reset them all after 500 milliseconds. If another input comes in earlier, the finally
triggers first, resetting the state, before the new input runs and sets the firstDigit
to true
again.Adam Powell
12/16/2021, 10:37 PMInteractionState
API came up - we modeled that as an event stream designed to reduce state specifically to enable this sort of thing; lingering pressed states, etc. though we aren't leveraging a whole lot of it todaydimsuz
12/16/2021, 11:36 PMMuatatorMutex
, will study it; and that "finally" trick is cool.
Yeah, suspend functions are the state machines underneath, aren't they 🙂 I guess first we learn to "forget" this abstraction, but then we learn about it on kind-of a new layer.