summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Steve Elliott <steell@google.com> 2022-09-08 20:44:45 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-09-08 20:44:45 +0000
commit6451a04d78dfb7b7d0c8210b66f37004238b524c (patch)
tree85c6046367683521add00bfc1cad472387464f55
parent3a24aba20e0f48160d257f8c65265bb62a4c0781 (diff)
parent60417deba0688d5904651a7401aaa3e95d603f4e (diff)
Merge "Add optional emitFirstEvent param to setChanges()" into tm-qpr-dev
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt25
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt11
2 files changed, 33 insertions, 3 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
index 7baebf4ef600..729fdfeb2ffb 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
@@ -74,10 +74,19 @@ data class WithPrev<T>(val previousValue: T, val newValue: T)
/**
* Returns a new [Flow] that combines the [Set] changes between each emission from [this] using
* [transform].
+ *
+ * If [emitFirstEvent] is `true`, then the first [Set] emitted from the upstream [Flow] will cause
+ * a change event to be emitted that contains no removals, and all elements from that first [Set]
+ * as additions.
+ *
+ * If [emitFirstEvent] is `false`, then the first emission is ignored and no changes are emitted
+ * until a second [Set] has been emitted from the upstream [Flow].
*/
fun <T, R> Flow<Set<T>>.setChangesBy(
transform: suspend (removed: Set<T>, added: Set<T>) -> R,
-): Flow<R> = onStart { emit(emptySet()) }.distinctUntilChanged()
+ emitFirstEvent: Boolean = true,
+): Flow<R> = (if (emitFirstEvent) onStart { emit(emptySet()) } else this)
+ .distinctUntilChanged()
.pairwiseBy { old: Set<T>, new: Set<T> ->
// If an element was present in the old set, but not the new one, then it was removed
val removed = old - new
@@ -86,8 +95,18 @@ fun <T, R> Flow<Set<T>>.setChangesBy(
transform(removed, added)
}
-/** Returns a new [Flow] that produces the [Set] changes between each emission from [this]. */
-fun <T> Flow<Set<T>>.setChanges(): Flow<SetChanges<T>> = setChangesBy(::SetChanges)
+/**
+ * Returns a new [Flow] that produces the [Set] changes between each emission from [this].
+ *
+ * If [emitFirstEvent] is `true`, then the first [Set] emitted from the upstream [Flow] will cause
+ * a change event to be emitted that contains no removals, and all elements from that first [Set]
+ * as additions.
+ *
+ * If [emitFirstEvent] is `false`, then the first emission is ignored and no changes are emitted
+ * until a second [Set] has been emitted from the upstream [Flow].
+ */
+fun <T> Flow<Set<T>>.setChanges(emitFirstEvent: Boolean = true): Flow<SetChanges<T>> =
+ setChangesBy(::SetChanges, emitFirstEvent)
/** Contains the difference in elements between two [Set]s. */
data class SetChanges<T>(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt b/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
index 092e82c526e3..460b71febc24 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
@@ -127,6 +127,17 @@ class SetChangesFlowTest : SysuiTestCase() {
)
)
}
+
+ @Test
+ fun dontEmitFirstEvent() = runBlocking {
+ assertThatFlow(flowOf(setOf(1, 2), setOf(2, 3)).setChanges(emitFirstEvent = false))
+ .emitsExactly(
+ SetChanges(
+ removed = setOf(1),
+ added = setOf(3),
+ )
+ )
+ }
}
private fun <T> assertThatFlow(flow: Flow<T>) = object {