https://kotlinlang.org logo
Title
a

agta1991

03/05/2020, 11:41 AM
Hi, has anyone came across InvalidMutabilityExceptions when using Flow combine operators on native targets? I'm using the 1.3.3-native-mt version.
e

elizarov

03/05/2020, 11:47 AM
a

agta1991

03/05/2020, 1:27 PM
are there any useable workarounds for this, or we have to wait for the fix?
e

elizarov

03/05/2020, 1:27 PM
None that I know of.
a

agta1991

03/05/2020, 1:32 PM
Or just some kind of hacking with channels and maybe atomicfu like this:
fun <T1, T2, R : Any> combineLatest(flow1: Flow<T1>, flow2: Flow<T2>, block: suspend (T1, T2) -> R): Flow<R> =
    channelFlow {
        val latest = atomic<Pair<Data<T1?>, Data<T2?>>>(Data.NotAvailable to Data.NotAvailable)

        launch {
            flow1.collect { value ->
                val (t1, t2) = latest.updateAndGet { (_, t2) -> Data.Available(value) to t2 }

                if (t1 is Data.Available && t2 is Data.Available) {
                    if (t1.value != null && t2.value != null) {
                        send(block(t1.value, t2.value))
                    }
                }
            }
        }

        launch {
            flow2.collect { value ->
                val (t1, t2) = latest.updateAndGet { (t1, _) -> t1 to Data.Available(value) }

                if (t1 is Data.Available && t2 is Data.Available) {
                    if (t1.value != null && t2.value != null) {
                        send(block(t1.value, t2.value))
                    }
                }
            }
        }
    }


sealed class Data<out T> {
    data class Available<out T>(val value: T) : Data<T>()
    object NotAvailable : Data<Nothing>()
}