blob: a901c586fd91219ff6087ff1d76fc29cdf521bf3 [file] [log] [blame]
Roman Elizarovf16fd272017-02-07 11:26:00 +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
Roman Elizarov3754f952017-01-18 20:47:54 +030017package kotlinx.coroutines.experimental.swing
18
19import kotlinx.coroutines.experimental.CancellableContinuation
20import kotlinx.coroutines.experimental.CoroutineDispatcher
21import kotlinx.coroutines.experimental.Delay
Roman Elizarovdaa1d9d2017-03-02 19:00:50 +030022import kotlinx.coroutines.experimental.DisposableHandle
Roman Elizarov3754f952017-01-18 20:47:54 +030023import kotlinx.coroutines.experimental.swing.Swing.delay
24import java.awt.event.ActionListener
25import java.util.concurrent.TimeUnit
26import javax.swing.SwingUtilities
27import javax.swing.Timer
Roman Elizarovea4a51b2017-01-31 12:01:25 +030028import kotlin.coroutines.experimental.CoroutineContext
Roman Elizarov3754f952017-01-18 20:47:54 +030029
30/**
31 * Dispatches execution onto Swing event dispatching thread and provides native [delay] support.
32 */
Roman Elizarov7cf452e2017-01-29 21:58:33 +030033object Swing : CoroutineDispatcher(), Delay {
Roman Elizarov67891d82017-01-23 16:47:20 +030034 override fun dispatch(context: CoroutineContext, block: Runnable) = SwingUtilities.invokeLater(block)
Roman Elizarov3754f952017-01-18 20:47:54 +030035
Roman Elizarovd528e3e2017-01-23 15:40:05 +030036 override fun scheduleResumeAfterDelay(time: Long, unit: TimeUnit, continuation: CancellableContinuation<Unit>) {
Roman Elizarovdaa1d9d2017-03-02 19:00:50 +030037 val timer = schedule(time, unit, ActionListener {
Roman Elizarova198bad2017-02-10 13:30:38 +030038 with(continuation) { resumeUndispatched(Unit) }
Roman Elizarovdaa1d9d2017-03-02 19:00:50 +030039 })
Vsevolod Tolstopyatov80a29472018-04-17 16:02:02 +030040 continuation.invokeOnCancellation { timer.stop() }
Roman Elizarovdaa1d9d2017-03-02 19:00:50 +030041 }
42
43 override fun invokeOnTimeout(time: Long, unit: TimeUnit, block: Runnable): DisposableHandle {
44 val timer = schedule(time, unit, ActionListener {
45 block.run()
46 })
47 return object : DisposableHandle {
48 override fun dispose() {
49 timer.stop()
50 }
Roman Elizarova198bad2017-02-10 13:30:38 +030051 }
Roman Elizarovdaa1d9d2017-03-02 19:00:50 +030052 }
53
54 private fun schedule(time: Long, unit: TimeUnit, action: ActionListener): Timer =
55 Timer(unit.toMillis(time).coerceAtMost(Int.MAX_VALUE.toLong()).toInt(), action).apply {
Roman Elizarov3754f952017-01-18 20:47:54 +030056 isRepeats = false
57 start()
58 }
Roman Elizarova198bad2017-02-10 13:30:38 +030059
60 override fun toString() = "Swing"
Roman Elizarov3754f952017-01-18 20:47:54 +030061}