How would you all expose state stored inside of an...
# coroutines
s
How would you all expose state stored inside of an Actor? Ideally, I’d be able to observe changes to variables inside the Actor from other classes. I’ve got this implemented already in Android using LiveData, but it’s a bit hacky
g
Actor class can expose ReceiveChannel (open connection on BroadcastChannel
s
In this case, I have an Actor inside of an Android ViewModel that takes in sealed class Events and computes the next UI State. I need some way to communicate these state changes to my Fragment/Activity
w
You need two channels for that type of thing. For our ViewModel conversion, the VM owns both receiving channels from the View and sending channels to the view. Have your actor take the channel that communicates back to your activity as an argument and then pump the event objects down it for the activity to listen for.
We’re doing nearly this exact thing in a production app right now, except without actors
s
Copy code
import kotlinx.coroutines.experimental.channels.*
import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.runBlocking

fun main(args: Array<String>)  = runBlocking<Unit> {
    // Create the listener
    val listener = ConflatedBroadcastChannel<Int>()

    // Create the actor
    val actor = counterActor(listener)

    // Send some events
    launch{
        repeat(5) {
            actor.send(Event.Increment)
            delay(250)
        }
        repeat(5) {
            actor.send(Event.Decrement)
            delay(250)
        }
        actor.close()
    }

    // Print out the counter
    for (i in listener.openSubscription()) {
        println("The counter is $i")
    }
}

fun counterActor(counterReceiver: SendChannel<Int>) = actor<Event> {
    var counter = 0
    for (msg in channel) {
        counter = when (msg) {
            is Event.Increment -> counter + 1
            is Event.Decrement -> counter - 1
        }.also {
            counterReceiver.send(it)
        }
    }
    counterReceiver.close()
}

sealed class Event {
    object Increment: Event()
    object Decrement: Event()
}
Thanks for the tip, @withoutclass! I’ve got the above proof of concept built out.
w
👍