blob: 1a4d2cdfe9dcb7905139391dd70ab5c49e295fca [file] [log] [blame]
Konrad Kamiński5d273a92017-04-26 17:18:41 +02001/*
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
17package kotlinx.coroutines.experimental.rx1
18
19import rx.Scheduler
20import kotlinx.coroutines.experimental.CancellableContinuation
21import kotlinx.coroutines.experimental.CoroutineDispatcher
22import kotlinx.coroutines.experimental.Delay
23import kotlinx.coroutines.experimental.DisposableHandle
24import rx.Subscription
25import java.util.concurrent.TimeUnit
26import kotlin.coroutines.experimental.CoroutineContext
27
28/**
29 * Converts an instance of [Scheduler] to an implementation of [CoroutineDispatcher]
30 * and provides native [delay][Delay.delay] support.
31 */
32public fun Scheduler.asCoroutineDispatcher() = SchedulerCoroutineDispatcher(this)
33
34/**
35 * Implements [CoroutineDispatcher] on top of an arbitrary [Scheduler].
36 * @param scheduler a scheduler.
37 */
38public class SchedulerCoroutineDispatcher(private val scheduler: Scheduler) : CoroutineDispatcher(), Delay {
39 override fun dispatch(context: CoroutineContext, block: Runnable) {
40 scheduler.createWorker().schedule { block.run() }
41 }
42
43 override fun scheduleResumeAfterDelay(time: Long, unit: TimeUnit, continuation: CancellableContinuation<Unit>) =
44 scheduler.createWorker()
45 .schedule({
46 with(continuation) { resumeUndispatched(Unit) }
47 }, time, unit)
48 .let { subscription ->
Roman Elizarov3e9f2442018-04-28 17:38:22 +030049 continuation.unsubscribeOnCancellation(subscription)
Konrad Kamiński5d273a92017-04-26 17:18:41 +020050 }
51
52 override fun invokeOnTimeout(time: Long, unit: TimeUnit, block: Runnable): DisposableHandle =
53 scheduler.createWorker().schedule({ block.run() }, time, unit).asDisposableHandle()
54
55 private fun Subscription.asDisposableHandle(): DisposableHandle = object : DisposableHandle {
56 override fun dispose() = unsubscribe()
57 }
58
59 override fun toString(): String = scheduler.toString()
60 override fun equals(other: Any?): Boolean = other is SchedulerCoroutineDispatcher && other.scheduler === scheduler
61 override fun hashCode(): Int = System.identityHashCode(scheduler)
62}