1 /*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 @file:OptIn(ExperimentalCoroutinesApi::class, ExperimentalTypeInference::class)
18
19 package com.android.systemui.utils.coroutines.flow
20
21 import kotlin.experimental.ExperimentalTypeInference
22 import kotlinx.coroutines.ExperimentalCoroutinesApi
23 import kotlinx.coroutines.flow.Flow
24 import kotlinx.coroutines.flow.FlowCollector
25 import kotlinx.coroutines.flow.conflate
26 import kotlinx.coroutines.flow.flatMapLatest
27 import kotlinx.coroutines.flow.mapLatest
28 import kotlinx.coroutines.flow.transformLatest
29
30 /**
31 * Returns a flow that emits elements from the original flow transformed by [transform] function.
32 * When the original flow emits a new value, computation of the [transform] block for previous value
33 * is cancelled.
34 *
35 * For example, the following flow:
36 * ```
37 * flow {
38 * emit("a")
39 * delay(100)
40 * emit("b")
41 * }.mapLatest { value ->
42 * println("Started computing $value")
43 * delay(200)
44 * "Computed $value"
45 * }
46 * ```
47 *
48 * will print "Started computing a" and "Started computing b", but the resulting flow will contain
49 * only "Computed b" value.
50 *
51 * This operator is [conflated][conflate] by default, and as such should be preferred over usage of
52 * [mapLatest], due to the latter's default configuration of using an internal buffer, negatively
53 * impacting system health.
54 *
55 * @see mapLatest
56 */
mapLatestConflatednull57 fun <T, R> Flow<T>.mapLatestConflated(@BuilderInference transform: suspend (T) -> R): Flow<R> =
58 mapLatest(transform).conflate()
59
60 /**
61 * Returns a flow that switches to a new flow produced by [transform] function every time the
62 * original flow emits a value. When the original flow emits a new value, the previous flow produced
63 * by `transform` block is cancelled.
64 *
65 * For example, the following flow:
66 * ```
67 * flow {
68 * emit("a")
69 * delay(100)
70 * emit("b")
71 * }.flatMapLatest { value ->
72 * flow {
73 * emit(value)
74 * delay(200)
75 * emit(value + "_last")
76 * }
77 * }
78 * ```
79 *
80 * produces `a b b_last`
81 *
82 * This operator is [conflated][conflate] by default, and as such should be preferred over usage of
83 * [flatMapLatest], due to the latter's default configuration of using an internal buffer,
84 * negatively impacting system health.
85 *
86 * @see flatMapLatest
87 */
88 fun <T, R> Flow<T>.flatMapLatestConflated(
89 @BuilderInference transform: suspend (T) -> Flow<R>,
90 ): Flow<R> = flatMapLatest(transform).conflate()
91
92 /**
93 * Returns a flow that produces element by [transform] function every time the original flow emits a
94 * value. When the original flow emits a new value, the previous `transform` block is cancelled,
95 * thus the name `transformLatest`.
96 *
97 * For example, the following flow:
98 * ```
99 * flow {
100 * emit("a")
101 * delay(100)
102 * emit("b")
103 * }.transformLatest { value ->
104 * emit(value)
105 * delay(200)
106 * emit(value + "_last")
107 * }
108 * ```
109 *
110 * produces `a b b_last`.
111 *
112 * This operator is [conflated][conflate] by default, and as such should be preferred over usage of
113 * [transformLatest], due to the latter's default configuration of using an internal buffer,
114 * negatively impacting system health.
115 *
116 * @see transformLatest
117 */
118 fun <T, R> Flow<T>.transformLatestConflated(
119 @BuilderInference transform: suspend FlowCollector<R>.(T) -> Unit,
120 ): Flow<R> = transformLatest(transform).conflate()
121