Travis Griggs
02/27/2024, 7:40 PMval activeRun by remember { derivedStateOf { plans.soonestRun(region.valve) as? ValveRunActive } }
But the ValveActiveRun object can compute "isExpired" quickly. So I'd like to somehow wire that in so that when someone accesses activeRun, it's checking whether the cachedValue.isExpired and if so, recomputing soonestRun() even though none of the touched mutable states inside the computation have changed.Alex Vanyo
02/27/2024, 7:47 PMsoonestRun()
calculation probably calls into some sort of now()
method to get the current time. Can you turn that source for time into a piece of snapshot state that is an input to the method?Travis Griggs
02/27/2024, 8:16 PMChuck Jazdzewski [G]
02/27/2024, 8:58 PMmutableStateOf
that represents a serial number of the values of soonestRun(region.value)
that is read in the derivedStateOf
but is not directly part of the result. Changing this serial number will cause the derivedStateOf
to be recalculated the next time is is read. That is, whenver isExprired
might have changed, increment the serial number. This will cause isExprired
to be checked again. This corresponds roughtly to isExpried
which would then be val isExpried get() = currentSerialNumber != lastSerialNumber
if it is needed.Travis Griggs
02/28/2024, 6:06 PMChuck Jazdzewski [G]
02/28/2024, 6:56 PMderivedStateOf
so I also want to make sure we don't break your case.Travis Griggs
02/28/2024, 7:48 PMvar expiryTrigger =
remember { mutableIntStateOf(1) } // "flip flop" state that we can use to invalidate the memoized soonestRun computation when it's no longer valid
val soonestRun: ValveRunDisposition? by remember {
derivedStateOf {
expiryTrigger.value // access this simply to create a dependency on expiryTrigger
plans.soonestRun(region.valve)
}
}
val activeRun: ValveRunActive? by remember {
derivedStateOf {
if (soonestRun?.isValid(atNow = currentTime.value) == false) {
expiryTrigger.value *= -1
}
soonestRun as? ValveRunActive
}
}
My initial attempt, I used the expiryTrigger as a key to the remember(...)
for soonestRun
, but that didn't cause it to invalidate. Had to do the access inside. I'm not sure I understand why that isAlex Vanyo
02/28/2024, 9:20 PMcurrentTime.value
backed by snapshot-state? mutableStateOf
or similar?expiryTrigger
is a bit suspicious - I’m wondering if you could mold the logic into something like
val currentInterval by remember {
derivedStateOf {
computeInterval(currentTime.value)
}
}
val activeRun by remember {
derivedStateOf {
plans.soonestRun(currentInterval, region.valve)
}
}
Travis Griggs
02/28/2024, 10:17 PM