Merge "Make pairwise() only subscribe to upstream once" into tm-qpr-dev am: a117bbe3f2

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19827976

Change-Id: I9ab32af500d6a177acf94fb517c598fe8c85a3bc
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Steve Elliott
2022-09-08 21:26:43 +00:00
committed by Automerger Merge Worker

View File

@@ -17,10 +17,10 @@
package com.android.systemui.util.kotlin package com.android.systemui.util.kotlin
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.zip
/** /**
* Returns a new [Flow] that combines the two most recent emissions from [this] using [transform]. * Returns a new [Flow] that combines the two most recent emissions from [this] using [transform].
@@ -29,15 +29,16 @@ import kotlinx.coroutines.flow.zip
* *
* Useful for code that needs to compare the current value to the previous value. * Useful for code that needs to compare the current value to the previous value.
*/ */
fun <T, R> Flow<T>.pairwiseBy(transform: suspend (old: T, new: T) -> R): Flow<R> { fun <T, R> Flow<T>.pairwiseBy(transform: suspend (old: T, new: T) -> R): Flow<R> = flow {
// same as current flow, but with the very first event skipped val noVal = Any()
val nextEvents = drop(1) var previousValue: Any? = noVal
// zip current flow and nextEvents; transform will receive a pair of old and new value. This collect { newVal ->
// works because zip will suppress emissions until both flows have emitted something; since in if (previousValue != noVal) {
// this case both flows are emitting at the same rate, but the current flow just has one extra @Suppress("UNCHECKED_CAST")
// thing emitted at the start, the effect is that zip will cache the most recent value while emit(transform(previousValue as T, newVal))
// waiting for the next emission from nextEvents. }
return zip(nextEvents, transform) previousValue = newVal
}
} }
/** /**