Hi guys. I’m playing with Snapshot System. I tried...
# compose
f
Hi guys. I’m playing with Snapshot System. I tried to modify a mutable state in global snapshot, but the apply listener doesn’t get called back. Code in🧵
Here is my code:
Copy code
val globalWriteObserverHandler = Snapshot.registerGlobalWriteObserver {
  println("on global written")
  Snapshot.sendApplyNotifications()
}
val applyObserverHandler = Snapshot.registerApplyObserver { set, _ ->
  println("on applied - $set")
}
val count = mutableStateOf(0)
count.value = 1
globalWriteObserverHandler.dispose()
applyObserverHandler.dispose()
If I take a snapshot before the modification and dispose the snapshot immediately, then the apply listener can get called back when state is modified:
Copy code
...
val count = mutableStateOf(0)
// added this line
Snapshot.takeSnapshot().dispose()
count.value = 1
...
Dose anyone know the reason?
I found it’s due to the logic in
fun <T : StateRecord> T.overwritableRecord
.
Copy code
internal fun <T : StateRecord> T.overwritableRecord(
    state: StateObject,
    snapshot: Snapshot,
    candidate: T
): T {
    ...

    if (candidate.snapshotId == id) return candidate

    ...

    snapshot.recordModified(state)

    return newData
}
When candidate record is found, it returns, without calling
recordModified
. Is this expected? If yes, what the reason?
z
I’m guessing yea, because the snapshot system is designed only to let observers know if an object has been modified, not how many times it’s been modified, in a given snapshot. If an object is modified many times in a snapshot, there are probably major performance wins to this approach.
f
I see. It makes sense. But I still feel that the behavior is a little bit buggy in my first code snippet. I expect there would be at least one apply notification.
z
Look at the kdoc for initializeObjects and sendApplyNotifications in Snapshot.kt. Changes aren't recorded for brand new state objects until the snapshot is applied or initializeObjects is called.
f
initializeObjects
? I’m guessing you mean
notifyObjectsInitialized
. And it works. Thanks very much!
z
Yep, sorry