louiscad
08/20/2018, 8:22 AMchannelA: Channel<A>
and channelB: Channel<B>
, I want to call a method like update(a: A, b: B)
each time I get a value from any channel, that is, if I receive from channelA
, I want it to be called with the new A
value, and the same B
value as previously received.
Each time I have a use case for it, I feel like I'm writing disposable/throwaway code that is a bit error-prone and quite boilerplate-y. If you have any clue about a solution to do it right once for all, in a kind of generic way, please tell!
Bonus points if your solution can also work with other callbacks and not just Channel
gildor
08/20/2018, 8:22 AMmerge
operator would help? Just merge multiple channels to onelouiscad
08/20/2018, 8:24 AMChannel
(I've searched through autocompletion, and I only found zip
which does not do what I want as it needs a new value from each channel)julioyg
08/20/2018, 8:25 AMlouiscad
08/20/2018, 8:27 AMPair
, Triple
or other grouping objects, if this is possiblegildor
08/20/2018, 8:29 AMfun <T> merge(vararg channels: ReceiveChannel<T>) = produce {
for (c in channels) {
launch(coroutineContext) {
for (v in c) {
send(v)
}
}
}
}
(just a draft, not tested, probably can be rewritten with select instead)louiscad
08/20/2018, 8:31 AMlouiscad
08/20/2018, 8:34 AMlouiscad
08/20/2018, 8:37 AMfun <T> merge(vararg channels: ReceiveChannel<T>) = produce {
try {
channels.map { channel ->
launch(coroutineContext) {
for (e in channel) send(e)
}
}.joinAll()
} finally {
channels.forEach { it.cancel() }
}
}
gildor
08/20/2018, 8:39 AMgildor
08/20/2018, 8:40 AMyou lose type informations if you merge channels of different typesYou can use wrapper over your data or just Any
gildor
08/20/2018, 8:40 AMis not conflatedYou can use conflated channel under the hood, but it cannot be just an operator anymore, but probably class implementation detail
louiscad
08/20/2018, 8:42 AMconsumesAll
seems less efficient that a simple forEach
in this casewithoutclass
08/20/2018, 9:23 AMwithoutclass
08/20/2018, 9:24 AMlouiscad
08/20/2018, 2:50 PMbj0
08/20/2018, 5:26 PMlouiscad
08/20/2018, 6:54 PMbj0
08/20/2018, 7:04 PMbj0
08/20/2018, 7:06 PMselect
on channels -> update
on returned itemlouiscad
08/21/2018, 12:03 AMconflateAll
is called (on each update from any callback/channel)bj0
08/21/2018, 12:05 AMselect
would take care of the 'get a value from any channel' partDaniel Tam
08/21/2018, 6:48 AMlouiscad
08/21/2018, 7:28 AMlouiscad
08/21/2018, 7:34 AMcombineLatest
seems to work for only 2 `Observable`s, while my ConflatedValues
class works for any number of properties/callbacks/channels