Uli Bubenheimer
05/22/2022, 8:10 PMFrancesc
05/22/2022, 8:39 PMUli Bubenheimer
05/22/2022, 8:42 PMFrancesc
05/22/2022, 8:44 PMUli Bubenheimer
05/22/2022, 8:50 PMsnapshotFlow { mySnapShotStateList }
evaluates its lambda block upon a state change of mySnapshotStateList
, which occurs whenever there is a list update, but it does not emit, because the list object remains the same, and is equal to itself, of course.Adam Powell
05/22/2022, 11:09 PMAdam Powell
05/22/2022, 11:20 PMUli Bubenheimer
05/23/2022, 12:29 AMval intState = mutableStateOf(1)
and over time change state to 2, then 3, snapshotFlow { intState.value }
may only emit 1 and 3, or 2 and 3, or just 3. This is how I understand the difference between change events and snapshot state.Uli Bubenheimer
05/23/2022, 12:36 AMval snapshotStateList = mutableStateListOf<Int>()
and keep adding elements to the list, then snapshotFlow { snapshotStateList }
will never emit more than once, even though snapshot state keeps changing. This behavior is not useful.Uli Bubenheimer
05/23/2022, 12:40 AMval intState = mutableStateOf(1)
and over time keep "updating" the state with 1, snapshotFlow { intState.value }
does nothing at all, after the initial emit, because snapshot state never actually changes.Uli Bubenheimer
05/23/2022, 12:44 AMsnapshotFlow
relates to change events. It just seems like an additional filter that a flow consumer could choose to add or not add.Uli Bubenheimer
05/23/2022, 1:19 AMintState
changes back to 1, after 3, snapshotFlow
without an equals check could end up emitting a sequence of '1', '1', (the state object is cycling through 1,2,3,1) which does not make sense when one expects state output.Uli Bubenheimer
05/23/2022, 1:27 AMsnapshotFlow
is intended to emit something that behaves like a state, even though the output is not actually a state, just some derivative. Seems weird.Uli Bubenheimer
05/23/2022, 1:32 AMderivedStateOf
as a flow I suppose?Adam Powell
05/23/2022, 1:34 AMWhen I haveand keep adding elements to the list, thenval snapshotStateList = mutableStateListOf<Int>()
will never emit more than once, even though snapshot state keeps changing.snapshotFlow { snapshotStateList }
snapshotStateList
is just a reference to an object. It only emits once because there is only ever one thing to emit: the reference to the single list. This snapshotFlow
hasn't accessed any snapshot state to observe new values ofAdam Powell
05/23/2022, 1:36 AMsnapshotFlow
block, there are no reads of snapshot objects to monitor for changesAdam Powell
05/23/2022, 1:39 AMval inner = MutableStateFlow(1)
val outer = MutableStateFlow(inner)
launch {
outer.collect {
println(it.value)
}
}
inner.value = 2
outer.value = inner
the launched collector wouldn't see a change eitherUli Bubenheimer
05/23/2022, 1:41 AMsnapshotFlow
keeps confusing me in this fashion.Adam Powell
05/23/2022, 1:42 AMdistinctUntilChanged
-style behavior, two examples of why doing otherwise for the example would be undesirable:Adam Powell
05/23/2022, 1:45 AMsnapshotFlow {}
maintains a consistent snapshot within its block where all snapshot reads see an atomically consistent state across objects. As soon as you emit another snapshot state object from it, those objects are no longer guaranteed to hold the same values they did when the block was running. Depending on buffering, dispatch, and other flow operator behavior, the point where the emit runs no longer correlates to a single atomic state of the data that represents when snapshotFlow
noticed a changeAdam Powell
05/23/2022, 1:46 AMUli Bubenheimer
05/23/2022, 2:13 AMAdam Powell
05/23/2022, 2:17 AMUli Bubenheimer
05/23/2022, 2:17 AMAdam Powell
05/23/2022, 2:18 AMsnapshotFlow does not actually give me access to the snapshot stateI'm not sure what you mean by this
Uli Bubenheimer
05/23/2022, 2:19 AMUli Bubenheimer
05/23/2022, 2:19 AMAdam Powell
05/23/2022, 2:22 AMsnapshotFlow
block rather than try to process the snapshot state objects themselves downstream. snapshotFlow
is a translation edge between snapshots => flowsUli Bubenheimer
05/23/2022, 2:24 AMUli Bubenheimer
05/23/2022, 2:25 AMAdam Powell
05/23/2022, 2:30 AMsnapshotFlow
block itself may not be as prohibitive as it seems. As for the copy, unfortunately since kotlin's Iterable.toList()
is an extension and not something we could override in SnapshotStateList
itself we can't really hand over the underlying persistent list at that snapshotAdam Powell
05/23/2022, 2:31 AM[Mutable]List
reference)Uli Bubenheimer
05/23/2022, 2:31 AMUli Bubenheimer
05/23/2022, 2:36 AMUli Bubenheimer
05/23/2022, 2:41 AMAdam Powell
05/23/2022, 2:49 AMsnapshotFlow {}.flowOn(...)
you'll get the same kinds of results you would anywhere else. Snapshots and snapshotFlow
aren't dependent on composition in any wayAdam Powell
05/23/2022, 2:49 AMsnapshotFlow
block to run wherever you flowOn
to)Uli Bubenheimer
05/23/2022, 2:52 AMAdam Powell
05/23/2022, 2:53 AMAdam Powell
05/23/2022, 2:54 AMUli Bubenheimer
05/23/2022, 2:54 AMUli Bubenheimer
05/23/2022, 3:01 AMUli Bubenheimer
05/23/2022, 3:07 AMUli Bubenheimer
05/23/2022, 1:52 PMList
? List
can be anything, so having it be a private PersistentList implementation underneath seems alright to me. You said that a toList()
extension function would not be feasible, but is there an issue with adding a custom method to SnapshotStateList like this? If PersistentList
ever goes stable then the API could be changed around a bit, deprecating the original custom method/property. I can add something in the issuetracker if you think this could possibly see the light of day. This would make it usable in a similar way as MutableState<List>
.Adam Powell
05/23/2022, 2:12 PMUli Bubenheimer
05/23/2022, 3:17 PM