blob: fa7ae7a3e5adc2caf41e08c629a71caf87db6790 [file] [log] [blame]
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001/*
Roman Elizarov1f74a2d2018-06-29 19:19:45 +03002 * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03003 */
4
5// This file was automatically generated from coroutines-guide.md by Knit tool. Do not edit.
Roman Elizarova9687a32018-06-29 17:28:38 +03006package kotlinx.coroutines.experimental.guide.select05
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03007
8import kotlinx.coroutines.experimental.*
Roman Elizarov96695782017-10-01 10:48:15 -07009import kotlinx.coroutines.experimental.channels.*
10import kotlinx.coroutines.experimental.selects.*
Roman Elizarov9fe5f462018-02-21 19:05:52 +030011import kotlin.coroutines.experimental.*
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030012
Roman Elizarov66f018c2017-09-29 21:39:03 +030013fun switchMapDeferreds(input: ReceiveChannel<Deferred<String>>) = produce<String> {
Roman Elizarova84730b2017-02-22 11:58:50 +030014 var current = input.receive() // start with first received deferred value
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030015 while (isActive) { // loop while not cancelled/closed
16 val next = select<Deferred<String>?> { // return next deferred value from this select or null
17 input.onReceiveOrNull { update ->
18 update // replaces next value to wait
19 }
20 current.onAwait { value ->
21 send(value) // send value that current deferred has produced
22 input.receiveOrNull() // and use the next deferred from the input channel
23 }
24 }
25 if (next == null) {
26 println("Channel was closed")
27 break // out of loop
28 } else {
29 current = next
30 }
31 }
32}
33
Roman Elizarov66f018c2017-09-29 21:39:03 +030034fun asyncString(str: String, time: Long) = async {
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030035 delay(time)
36 str
37}
38
39fun main(args: Array<String>) = runBlocking<Unit> {
40 val chan = Channel<Deferred<String>>() // the channel for test
Roman Elizarov43e3af72017-07-21 16:01:31 +030041 launch(coroutineContext) { // launch printing coroutine
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030042 for (s in switchMapDeferreds(chan))
43 println(s) // print each received string
44 }
45 chan.send(asyncString("BEGIN", 100))
46 delay(200) // enough time for "BEGIN" to be produced
47 chan.send(asyncString("Slow", 500))
Roman Elizarova84730b2017-02-22 11:58:50 +030048 delay(100) // not enough time to produce slow
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030049 chan.send(asyncString("Replace", 100))
Roman Elizarova84730b2017-02-22 11:58:50 +030050 delay(500) // give it time before the last one
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030051 chan.send(asyncString("END", 500))
52 delay(1000) // give it time to process
Roman Elizarova84730b2017-02-22 11:58:50 +030053 chan.close() // close the channel ...
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030054 delay(500) // and wait some time to let it finish
55}