1 /*
<lambda>null2 * Copyright (C) 2023 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 package com.android.systemui.util.kotlin
18
19 import android.content.Context
20 import kotlinx.coroutines.flow.Flow
21 import kotlinx.coroutines.flow.combine
22 import kotlinx.coroutines.flow.filter
23 import kotlinx.coroutines.flow.map
24
25 class Utils {
26 companion object {
27 fun <A, B, C> toTriple(a: A, bc: Pair<B, C>) = Triple(a, bc.first, bc.second)
28
29 fun <A, B, C> toTriple(ab: Pair<A, B>, c: C) = Triple(ab.first, ab.second, c)
30
31 fun <A, B, C, D> toQuad(a: A, b: B, c: C, d: D) = Quad(a, b, c, d)
32
33 fun <A, B, C, D> toQuad(a: A, bcd: Triple<B, C, D>) =
34 Quad(a, bcd.first, bcd.second, bcd.third)
35 fun <A, B, C, D> toQuad(abc: Triple<A, B, C>, d: D) =
36 Quad(abc.first, abc.second, abc.third, d)
37
38 fun <A, B, C, D, E> toQuint(a: A, b: B, c: C, d: D, e: E) = Quint(a, b, c, d, e)
39
40 fun <A, B, C, D, E> toQuint(a: A, bcde: Quad<B, C, D, E>) =
41 Quint(a, bcde.first, bcde.second, bcde.third, bcde.fourth)
42
43 fun <A, B, C, D, E, F> toSextuple(a: A, bcdef: Quint<B, C, D, E, F>) =
44 Sextuple(a, bcdef.first, bcdef.second, bcdef.third, bcdef.fourth, bcdef.fifth)
45
46 fun <A, B, C, D, E, F, G> toSeptuple(a: A, bcdefg: Sextuple<B, C, D, E, F, G>) =
47 Septuple(
48 a,
49 bcdefg.first,
50 bcdefg.second,
51 bcdefg.third,
52 bcdefg.fourth,
53 bcdefg.fifth,
54 bcdefg.sixth
55 )
56
57 /**
58 * Samples the provided flow, performs a filter on the sampled value, then returns the
59 * original value.
60 */
61 fun <A, B> Flow<A>.sampleFilter(b: Flow<B>, predicate: (B) -> Boolean): Flow<A> {
62 return this.sample(b, ::Pair).filter { (_, b) -> predicate(b) }.map { (a, _) -> a }
63 }
64
65 /**
66 * Samples the provided flows, emitting a tuple of the original flow's value as well as each
67 * of the combined flows' values.
68 *
69 * Flow<A>.sample(Flow<B>, Flow<C>) -> (A, B, C)
70 */
71 fun <A, B, C> Flow<A>.sample(b: Flow<B>, c: Flow<C>): Flow<Triple<A, B, C>> {
72 return this.sample(combine(b, c, ::Pair), ::toTriple)
73 }
74
75 /**
76 * Samples the provided flows, emitting a tuple of the original flow's value as well as each
77 * of the combined flows' values.
78 *
79 * Flow<A>.sample(Flow<B>, Flow<C>, Flow<D>) -> (A, B, C, D)
80 */
81 fun <A, B, C, D> Flow<A>.sample(
82 b: Flow<B>,
83 c: Flow<C>,
84 d: Flow<D>
85 ): Flow<Quad<A, B, C, D>> {
86 return this.sample(combine(b, c, d, ::Triple), ::toQuad)
87 }
88
89 /**
90 * Samples the provided flows, emitting a tuple of the original flow's value as well as each
91 * of the combined flows' values.
92 *
93 * Flow<A>.sample(Flow<B>, Flow<C>, Flow<D>, Flow<E>) -> (A, B, C, D, E)
94 */
95 fun <A, B, C, D, E> Flow<A>.sample(
96 b: Flow<B>,
97 c: Flow<C>,
98 d: Flow<D>,
99 e: Flow<E>,
100 ): Flow<Quint<A, B, C, D, E>> {
101 return this.sample(combine(b, c, d, e, ::Quad), ::toQuint)
102 }
103
104 /**
105 * Samples the provided flows, emitting a tuple of the original flow's value as well as each
106 * of the combined flows' values.
107 *
108 * Flow<A>.sample(Flow<B>, Flow<C>, Flow<D>, Flow<E>, Flow<F>) -> (A, B, C, D, E, F)
109 */
110 fun <A, B, C, D, E, F> Flow<A>.sample(
111 b: Flow<B>,
112 c: Flow<C>,
113 d: Flow<D>,
114 e: Flow<E>,
115 f: Flow<F>,
116 ): Flow<Sextuple<A, B, C, D, E, F>> {
117 return this.sample(combine(b, c, d, e, f, ::Quint), ::toSextuple)
118 }
119
120 /**
121 * Samples the provided flows, emitting a tuple of the original flow's value as well as each
122 * of the combined flows' values.
123 *
124 * Flow<A>.sample(Flow<B>, Flow<C>, Flow<D>, Flow<E>, Flow<F>, Flow<G>) -> (A, B, C, D, E,
125 * F, G)
126 */
127 fun <A, B, C, D, E, F, G> Flow<A>.sample(
128 b: Flow<B>,
129 c: Flow<C>,
130 d: Flow<D>,
131 e: Flow<E>,
132 f: Flow<F>,
133 g: Flow<G>,
134 ): Flow<Septuple<A, B, C, D, E, F, G>> {
135 return this.sample(combine(b, c, d, e, f, g, ::Sextuple), ::toSeptuple)
136 }
137 }
138 }
139
140 data class Quad<A, B, C, D>(val first: A, val second: B, val third: C, val fourth: D)
141
142 data class Quint<A, B, C, D, E>(
143 val first: A,
144 val second: B,
145 val third: C,
146 val fourth: D,
147 val fifth: E
148 )
149
150 data class Sextuple<A, B, C, D, E, F>(
151 val first: A,
152 val second: B,
153 val third: C,
154 val fourth: D,
155 val fifth: E,
156 val sixth: F,
157 )
158
159 data class Septuple<A, B, C, D, E, F, G>(
160 val first: A,
161 val second: B,
162 val third: C,
163 val fourth: D,
164 val fifth: E,
165 val sixth: F,
166 val seventh: G,
167 )
168
toPxnull169 fun Int.toPx(context: Context): Int {
170 return (this * context.resources.displayMetrics.density).toInt()
171 }
172
toDpnull173 fun Int.toDp(context: Context): Int {
174 return (this / context.resources.displayMetrics.density).toInt()
175 }
176