https://kotlinlang.org logo
Title
l

louiscad

11/05/2018, 9:36 AM
Hi, I want to use the
select
clause to select between two user inputs (two button clicks). Should I implement the select clause myself in an extension function, or should I transform the button clicks to a channel, and then use the already existing select clause implementations?
g

gildor

11/05/2018, 9:39 AM
Channel implementation would be probably more heavyweight than just 2 callbacks, but at least it already works
g

groostav

11/05/2018, 9:40 AM
@gildor heavyweight handling button clicks? how many million clicks per second do you need?
d

Dominaezzz

11/05/2018, 9:40 AM
I'd say use an extension function. Channel would be be overkill.
l

louiscad

11/05/2018, 9:41 AM
Is anyone aware of a digest example on how to make a select clause implementation? The Channel implementation is a lot of code for me to see clearly how I should do it
g

gildor

11/05/2018, 9:42 AM
Each channel creates more objects and each callback handling involves allocations and atomic usages, because channel is multi-thread abstraction Of course, on practice you will not see difference, my point that just for 2 callbacks you can provide more efficient and simple implementation
l

louiscad

11/05/2018, 9:43 AM
BTW, performance doesn't need to be optimal in my case, it's an internal TornadoFx app that needs to register some devices
g

gildor

11/05/2018, 9:43 AM
@louiscad Depends on API which you want to get, I don’t see why you need coroutines in this case
in general, just subscribe on both callbacks and call another callback, nothing trickt
l

louiscad

11/05/2018, 9:44 AM
It's not that I need coroutines, but I want to make the whole code sequential. I have a
UserAction
sealed class hierarchy that I want to return from a suspend function implemented in the UI code
g

gildor

11/05/2018, 9:45 AM
fun onClick(v1: View, v2: View, onClick: (View) -> Unit) {
    v1.setOnClickListener {
        onClick(it)
    }
    v2.setOnClickListener { 
        onClick(it)
    }
}
If you want to use coroutines, use
suspendCoroutine
instead of onClick lambda
l

louiscad

11/05/2018, 9:48 AM
You're right,
suspendCoroutine
may be enough for my use case, I was over-complicating things. Thanks for your insight!
d

Dominaezzz

11/05/2018, 9:48 AM
Instead of a channel, why not use a Deferred.
g

gildor

11/05/2018, 9:49 AM
Something like this:
suspend fun awaitClick(v1: View, v2: View): View {
    return suspendCancellableCoroutine { cont ->
        val onClick: (View) -> Unit = {
            cont.resume(it)
        }
        // Not sure about this part, but probably make sense
        cont.invokeOnCancellation {
            v1.setOnClickListener(null)
            v2.setOnClickListener(null)
        }
        v1.setOnClickListener(onClick)
        v2.setOnClickListener(onClick)
    }
}
👍 1
Or even:
suspend fun List<View>.awaitClick(): View {
    return suspendCancellableCoroutine { cont ->
        val onClick: (View) -> Unit = {
            cont.resume(it)
        }
        // Not sure about this part, but probably make sense
        cont.invokeOnCancellation {
            forEach { view -> 
                  view.setOnClickListener(null)
            }
        }
        forEach { view ->
            view.setOnClickListener(onClick)
        }
    }
}
👍 1
l

louiscad

11/05/2018, 9:51 AM
It's a bit more complex still, as I want to disabled the buttons as soon as one is clicked, plus the user may abandon something that happens next, where I'd need to enable back both buttons and wait for click on one again, but I think I'll figure it out.
g

gildor

11/05/2018, 9:52 AM
Still can be handled using the same approach
l

louiscad

11/05/2018, 9:52 AM
Yes, that's why I put a thumbs up on your snippet
👍 1
g

gildor

11/05/2018, 9:53 AM
sorry. fixed example with
List<View>
l

louiscad

11/05/2018, 9:53 AM
I saw the mistake for this one haha 😉
🙈 1
z

Zach Klippenstein (he/him) [MOD]

11/05/2018, 5:55 PM
@louiscad if you're still looking for a simpler select clause implementation, I wrote a gist a while back: https://gist.github.com/zach-klippenstein/fa4366388295282fa409c5085abada23
👍 1
l

louiscad

11/05/2018, 6:44 PM
Thank you @Zach Klippenstein (he/him) [MOD], while I could do without select clause thanks to Andrey's help, it's still interesting, and it may help for future use cases! 👍
👍 1