Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e5484dc5 authored by Steve Elliott's avatar Steve Elliott Committed by Automerger Merge Worker
Browse files

Merge "Add optional emitFirstEvent param to setChanges()" into tm-qpr-dev am:...

Merge "Add optional emitFirstEvent param to setChanges()" into tm-qpr-dev am: 6451a04d am: 272a3cf8

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



Change-Id: Iaa2b6a93fe70ada662ef4d2137b6a303cc910c7a
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 9bf08bf0 272a3cf8
Loading
Loading
Loading
Loading
+22 −3
Original line number Diff line number Diff line
@@ -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>(
+11 −0
Original line number Diff line number Diff line
@@ -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 {