https://kotlinlang.org logo
Title
t

Tower Guidev2

06/16/2021, 8:13 AM
Hi, I am investigating
merge(flow1, flow2, flow3...)
and have the following use case...
sealed class State {
    object Resting : State()
    object Working : State()
}


fun main() = runBlocking {

    backgroundStartsFirst()

}

@OptIn(ExperimentalCoroutinesApi::class)
suspend fun backgroundStartsFirst() {

    val backgroundFlow = flow {
        emit(State.Resting)
        delay(1000)

        emit(State.Working)
        delay(10000)

        emit(State.Resting)
    }


    val foregroundFlow = flow {
        emit(State.Resting)
        delay(2000)

        emit(State.Working)
        delay(1000)

        emit(State.Resting)
    }

    val workingCount = AtomicInteger(0)

    merge(backgroundFlow, foregroundFlow)
        .collect {

            when (it) {
                State.Working -> {
                    println("SOME ARE WORKING")
                    workingCount.incrementAndGet()
                }
                State.Resting -> {
                    println("SOME ARE RESTING")
                    if (workingCount.get() > 0) workingCount.decrementAndGet()
                }
            }
            if (workingCount.get() == 0) println("\tWE ARE ALL RESTING")
        }
}
Each flow can "report" thats its either
Resting
or
Working
. Each flow is completely independent of all other flows. When atleast one flows latest "report" was
Working
my merged state must be
Working
... Once all Flows latest report is
Resting
my merged state must be
Resting
Currently I have employed a WorkingCount to establish whether or not there is a
Working
Flow. I feel there must be a better solution than employing an AtomicCounter Is There? 🤔
w

wasyl

06/16/2021, 8:49 AM
You can use
combine
to get a new emission every time one of the combined flows emits:
val isRestingFlow = combine(flow1, flow2) { v1, v2 -> v1 is Resting && v2 is Resting }
t

Tower Guidev2

06/16/2021, 9:07 AM
@wasyl nice,
combine
is a clean solution, thanks