louiscad
05/11/2022, 4:37 PMStateFlow
to another StateFlow
with a synchronous operation (it's quite cheap, it's only one object allocation), and I didn't want to have to link it to a CoroutineScope
this time, so I wrote this mapSync
extension function, which you can criticize, and copy at will.
I'm using it in a single-thread context, but I think it'd work just fine in multi-thread so long as the mapping operation is cheap and doesn't cause heavy recomputations on concurrent accesses.
import kotlinx.coroutines.flow.*
fun <T, R> StateFlow<T>.mapSync(transform: (T) -> R): StateFlow<R> = object : StateFlow<R> {
override val replayCache: List<R> get() = listOf(value)
override suspend fun collect(collector: FlowCollector<R>): Nothing {
this@mapSync.collect {
collector.emit(transform(it))
}
}
private var lastUpstreamValue = this@mapSync.value
override var value: R = transform(lastUpstreamValue)
private set
get() {
val currentUpstreamValue: T = this@mapSync.value
if (currentUpstreamValue == lastUpstreamValue) return field
field = transform(currentUpstreamValue)
lastUpstreamValue = currentUpstreamValue
return field
}
}
I hope it's helpful to some of you!Robert Jaros
05/11/2022, 4:49 PMStateFlow
interface is still not stable for inheritance, isn't it?louiscad
05/11/2022, 5:23 PMRick Clephas
05/11/2022, 7:45 PM