blob: 30cbbc5d6f9478dc27d224ef7005163305b3080a [file] [log] [blame]
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001/*
2 * Copyright 2016-2017 JetBrains s.r.o.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// This file was automatically generated from coroutines-guide.md by Knit tool. Do not edit.
Roman Elizarova9687a32018-06-29 17:28:38 +030018package kotlinx.coroutines.experimental.guide.select05
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030019
20import kotlinx.coroutines.experimental.*
Roman Elizarov96695782017-10-01 10:48:15 -070021import kotlinx.coroutines.experimental.channels.*
22import kotlinx.coroutines.experimental.selects.*
Roman Elizarov9fe5f462018-02-21 19:05:52 +030023import kotlin.coroutines.experimental.*
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030024
Roman Elizarov66f018c2017-09-29 21:39:03 +030025fun switchMapDeferreds(input: ReceiveChannel<Deferred<String>>) = produce<String> {
Roman Elizarova84730b2017-02-22 11:58:50 +030026 var current = input.receive() // start with first received deferred value
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030027 while (isActive) { // loop while not cancelled/closed
28 val next = select<Deferred<String>?> { // return next deferred value from this select or null
29 input.onReceiveOrNull { update ->
30 update // replaces next value to wait
31 }
32 current.onAwait { value ->
33 send(value) // send value that current deferred has produced
34 input.receiveOrNull() // and use the next deferred from the input channel
35 }
36 }
37 if (next == null) {
38 println("Channel was closed")
39 break // out of loop
40 } else {
41 current = next
42 }
43 }
44}
45
Roman Elizarov66f018c2017-09-29 21:39:03 +030046fun asyncString(str: String, time: Long) = async {
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030047 delay(time)
48 str
49}
50
51fun main(args: Array<String>) = runBlocking<Unit> {
52 val chan = Channel<Deferred<String>>() // the channel for test
Roman Elizarov43e3af72017-07-21 16:01:31 +030053 launch(coroutineContext) { // launch printing coroutine
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030054 for (s in switchMapDeferreds(chan))
55 println(s) // print each received string
56 }
57 chan.send(asyncString("BEGIN", 100))
58 delay(200) // enough time for "BEGIN" to be produced
59 chan.send(asyncString("Slow", 500))
Roman Elizarova84730b2017-02-22 11:58:50 +030060 delay(100) // not enough time to produce slow
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030061 chan.send(asyncString("Replace", 100))
Roman Elizarova84730b2017-02-22 11:58:50 +030062 delay(500) // give it time before the last one
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030063 chan.send(asyncString("END", 500))
64 delay(1000) // give it time to process
Roman Elizarova84730b2017-02-22 11:58:50 +030065 chan.close() // close the channel ...
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030066 delay(500) // and wait some time to let it finish
67}