• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(ExperimentalTypeInference::class)
18 
19 package com.android.systemui.utils.coroutines.flow
20 
21 import kotlin.experimental.ExperimentalTypeInference
22 import kotlinx.coroutines.flow.Flow
23 import kotlinx.coroutines.flow.FlowCollector
24 import kotlinx.coroutines.flow.conflate
25 import kotlinx.coroutines.flow.flatMapLatest
26 import kotlinx.coroutines.flow.mapLatest
27 import kotlinx.coroutines.flow.transformLatest
28 
29 /**
30  * Returns a flow that emits elements from the original flow transformed by [transform] function.
31  * When the original flow emits a new value, computation of the [transform] block for previous value
32  * is cancelled.
33  *
34  * For example, the following flow:
35  * ```
36  * flow {
37  *     emit("a")
38  *     delay(100)
39  *     emit("b")
40  * }.mapLatest { value ->
41  *     println("Started computing $value")
42  *     delay(200)
43  *     "Computed $value"
44  * }
45  * ```
46  *
47  * will print "Started computing a" and "Started computing b", but the resulting flow will contain
48  * only "Computed b" value.
49  *
50  * This operator is [conflated][conflate] by default, and as such should be preferred over usage of
51  * [mapLatest], due to the latter's default configuration of using an internal buffer, negatively
52  * impacting system health.
53  *
54  * @see mapLatest
55  */
mapLatestConflatednull56 fun <T, R> Flow<T>.mapLatestConflated(@BuilderInference transform: suspend (T) -> R): Flow<R> =
57     mapLatest(transform).conflate()
58 
59 /**
60  * Returns a flow that switches to a new flow produced by [transform] function every time the
61  * original flow emits a value. When the original flow emits a new value, the previous flow produced
62  * by `transform` block is cancelled.
63  *
64  * For example, the following flow:
65  * ```
66  * flow {
67  *     emit("a")
68  *     delay(100)
69  *     emit("b")
70  * }.flatMapLatest { value ->
71  *     flow {
72  *         emit(value)
73  *         delay(200)
74  *         emit(value + "_last")
75  *     }
76  * }
77  * ```
78  *
79  * produces `a b b_last`
80  *
81  * This operator is [conflated][conflate] by default, and as such should be preferred over usage of
82  * [flatMapLatest], due to the latter's default configuration of using an internal buffer,
83  * negatively impacting system health.
84  *
85  * @see flatMapLatest
86  */
87 fun <T, R> Flow<T>.flatMapLatestConflated(
88     @BuilderInference transform: suspend (T) -> Flow<R>,
89 ): Flow<R> = flatMapLatest(transform).conflate()
90 
91 /**
92  * Returns a flow that produces element by [transform] function every time the original flow emits a
93  * value. When the original flow emits a new value, the previous `transform` block is cancelled,
94  * thus the name `transformLatest`.
95  *
96  * For example, the following flow:
97  * ```
98  * flow {
99  *     emit("a")
100  *     delay(100)
101  *     emit("b")
102  * }.transformLatest { value ->
103  *     emit(value)
104  *     delay(200)
105  *     emit(value + "_last")
106  * }
107  * ```
108  *
109  * produces `a b b_last`.
110  *
111  * This operator is [conflated][conflate] by default, and as such should be preferred over usage of
112  * [transformLatest], due to the latter's default configuration of using an internal buffer,
113  * negatively impacting system health.
114  *
115  * @see transformLatest
116  */
117 fun <T, R> Flow<T>.transformLatestConflated(
118     @BuilderInference transform: suspend FlowCollector<R>.(T) -> Unit,
119 ): Flow<R> = transformLatest(transform).conflate()
120