[kairos] annotate combinators as experimental
Flag: EXEMPT unused
Test: atest kairos-tests
Change-Id: I31b82c5cb7028626da6b07dea1b4accc1bbe77ed
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/Combinators.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/Combinators.kt
index 17e407e..ae9b8c8 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/Combinators.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/Combinators.kt
@@ -28,15 +28,18 @@
* Returns a [TFlow] that emits the value sampled from the [Transactional] produced by each emission
* of the original [TFlow], within the same transaction of the original emission.
*/
+@ExperimentalFrpApi
fun <A> TFlow<Transactional<A>>.sampleTransactionals(): TFlow<A> = map { it.sample() }
/** @see FrpTransactionScope.sample */
+@ExperimentalFrpApi
fun <A, B, C> TFlow<A>.sample(
state: TState<B>,
transform: suspend FrpTransactionScope.(A, B) -> C,
): TFlow<C> = map { transform(it, state.sample()) }
/** @see FrpTransactionScope.sample */
+@ExperimentalFrpApi
fun <A, B, C> TFlow<A>.sample(
transactional: Transactional<B>,
transform: suspend FrpTransactionScope.(A, B) -> C,
@@ -51,6 +54,7 @@
*
* @see sample
*/
+@ExperimentalFrpApi
fun <A, B, C> TFlow<A>.samplePromptly(
state: TState<B>,
transform: suspend FrpTransactionScope.(A, B) -> C,
@@ -74,6 +78,7 @@
* Returns a cold [Flow] that, when collected, emits from this [TFlow]. [network] is needed to
* transactionally connect to / disconnect from the [TFlow] when collection starts/stops.
*/
+@ExperimentalFrpApi
fun <A> TFlow<A>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
channelFlow { network.activateSpec { observe { trySend(it) } } }.conflate()
@@ -81,6 +86,7 @@
* Returns a cold [Flow] that, when collected, emits from this [TState]. [network] is needed to
* transactionally connect to / disconnect from the [TState] when collection starts/stops.
*/
+@ExperimentalFrpApi
fun <A> TState<A>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
channelFlow { network.activateSpec { observe { trySend(it) } } }.conflate()
@@ -90,6 +96,7 @@
*
* When collection is cancelled, so is the [FrpSpec]. This means all ongoing work is cleaned up.
*/
+@ExperimentalFrpApi
@JvmName("flowSpecToColdConflatedFlow")
fun <A> FrpSpec<TFlow<A>>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
channelFlow { network.activateSpec { applySpec().observe { trySend(it) } } }.conflate()
@@ -100,6 +107,7 @@
*
* When collection is cancelled, so is the [FrpSpec]. This means all ongoing work is cleaned up.
*/
+@ExperimentalFrpApi
@JvmName("stateSpecToColdConflatedFlow")
fun <A> FrpSpec<TState<A>>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
channelFlow { network.activateSpec { applySpec().observe { trySend(it) } } }.conflate()
@@ -108,6 +116,7 @@
* Returns a cold [Flow] that, when collected, applies this [Transactional] in a new transaction in
* this [network], and then emits from the returned [TFlow].
*/
+@ExperimentalFrpApi
@JvmName("transactionalFlowToColdConflatedFlow")
fun <A> Transactional<TFlow<A>>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
channelFlow { network.activateSpec { sample().observe { trySend(it) } } }.conflate()
@@ -116,6 +125,7 @@
* Returns a cold [Flow] that, when collected, applies this [Transactional] in a new transaction in
* this [network], and then emits from the returned [TState].
*/
+@ExperimentalFrpApi
@JvmName("transactionalStateToColdConflatedFlow")
fun <A> Transactional<TState<A>>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
channelFlow { network.activateSpec { sample().observe { trySend(it) } } }.conflate()
@@ -126,6 +136,7 @@
*
* When collection is cancelled, so is the [FrpStateful]. This means all ongoing work is cleaned up.
*/
+@ExperimentalFrpApi
@JvmName("statefulFlowToColdConflatedFlow")
fun <A> FrpStateful<TFlow<A>>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
channelFlow { network.activateSpec { applyStateful().observe { trySend(it) } } }.conflate()
@@ -136,11 +147,13 @@
*
* When collection is cancelled, so is the [FrpStateful]. This means all ongoing work is cleaned up.
*/
+@ExperimentalFrpApi
@JvmName("statefulStateToColdConflatedFlow")
fun <A> FrpStateful<TState<A>>.toColdConflatedFlow(network: FrpNetwork): Flow<A> =
channelFlow { network.activateSpec { applyStateful().observe { trySend(it) } } }.conflate()
/** Return a [TFlow] that emits from the original [TFlow] only when [state] is `true`. */
+@ExperimentalFrpApi
fun <A> TFlow<A>.filter(state: TState<Boolean>): TFlow<A> = filter { state.sample() }
private fun Iterable<Boolean>.allTrue() = all { it }
@@ -148,13 +161,15 @@
private fun Iterable<Boolean>.anyTrue() = any { it }
/** Returns a [TState] that is `true` only when all of [states] are `true`. */
+@ExperimentalFrpApi
fun allOf(vararg states: TState<Boolean>): TState<Boolean> = combine(*states) { it.allTrue() }
/** Returns a [TState] that is `true` when any of [states] are `true`. */
+@ExperimentalFrpApi
fun anyOf(vararg states: TState<Boolean>): TState<Boolean> = combine(*states) { it.anyTrue() }
/** Returns a [TState] containing the inverse of the Boolean held by the original [TState]. */
-fun not(state: TState<Boolean>): TState<Boolean> = state.mapCheapUnsafe { !it }
+@ExperimentalFrpApi fun not(state: TState<Boolean>): TState<Boolean> = state.mapCheapUnsafe { !it }
/**
* Represents a modal FRP sub-network.
@@ -168,6 +183,7 @@
*
* @see FrpStatefulMode
*/
+@ExperimentalFrpApi
fun interface FrpBuildMode<out A> {
/**
* Invoked when this mode is enabled. Returns a value and a [TFlow] that signals a switch to a
@@ -183,6 +199,7 @@
*
* @see FrpBuildMode
*/
+@ExperimentalFrpApi
val <A> FrpBuildMode<A>.compiledFrpSpec: FrpSpec<TState<A>>
get() = frpSpec {
var modeChangeEvents by TFlowLoop<FrpBuildMode<A>>()
@@ -206,6 +223,7 @@
*
* @see FrpBuildMode
*/
+@ExperimentalFrpApi
fun interface FrpStatefulMode<out A> {
/**
* Invoked when this mode is enabled. Returns a value and a [TFlow] that signals a switch to a
@@ -221,6 +239,7 @@
*
* @see FrpBuildMode
*/
+@ExperimentalFrpApi
val <A> FrpStatefulMode<A>.compiledStateful: FrpStateful<TState<A>>
get() = statefully {
var modeChangeEvents by TFlowLoop<FrpStatefulMode<A>>()
@@ -237,6 +256,7 @@
* Runs [spec] in this [FrpBuildScope], and then re-runs it whenever [rebuildSignal] emits. Returns
* a [TState] that holds the result of the currently-active [FrpSpec].
*/
+@ExperimentalFrpApi
fun <A> FrpBuildScope.rebuildOn(rebuildSignal: TFlow<*>, spec: FrpSpec<A>): TState<A> =
rebuildSignal.map { spec }.holdLatestSpec(spec)
@@ -248,5 +268,6 @@
* stateChanges.map { WithPrev(previousValue = sample(), newValue = it) }
* ```
*/
+@ExperimentalFrpApi
val <A> TState<A>.transitions: TFlow<WithPrev<A, A>>
get() = stateChanges.map { WithPrev(previousValue = sample(), newValue = it) }