blob: 304993c287fba84d62aeb096b2544115b8e0a2c1 [file] [log] [blame]
Roman Elizarovf16fd272017-02-07 11:26:00 +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 Elizarovf16fd272017-02-07 11:26:00 +03003 */
4
Roman Elizarov3754f952017-01-18 20:47:54 +03005package kotlinx.coroutines.experimental.swing
6
7import kotlinx.coroutines.experimental.CancellableContinuation
8import kotlinx.coroutines.experimental.CoroutineDispatcher
9import kotlinx.coroutines.experimental.Delay
Roman Elizarovdaa1d9d2017-03-02 19:00:50 +030010import kotlinx.coroutines.experimental.DisposableHandle
Roman Elizarov3754f952017-01-18 20:47:54 +030011import kotlinx.coroutines.experimental.swing.Swing.delay
12import java.awt.event.ActionListener
13import java.util.concurrent.TimeUnit
14import javax.swing.SwingUtilities
15import javax.swing.Timer
Roman Elizarovea4a51b2017-01-31 12:01:25 +030016import kotlin.coroutines.experimental.CoroutineContext
Roman Elizarov3754f952017-01-18 20:47:54 +030017
18/**
19 * Dispatches execution onto Swing event dispatching thread and provides native [delay] support.
20 */
Roman Elizarov7cf452e2017-01-29 21:58:33 +030021object Swing : CoroutineDispatcher(), Delay {
Roman Elizarov67891d82017-01-23 16:47:20 +030022 override fun dispatch(context: CoroutineContext, block: Runnable) = SwingUtilities.invokeLater(block)
Roman Elizarov3754f952017-01-18 20:47:54 +030023
Roman Elizarovd528e3e2017-01-23 15:40:05 +030024 override fun scheduleResumeAfterDelay(time: Long, unit: TimeUnit, continuation: CancellableContinuation<Unit>) {
Roman Elizarovdaa1d9d2017-03-02 19:00:50 +030025 val timer = schedule(time, unit, ActionListener {
Roman Elizarova198bad2017-02-10 13:30:38 +030026 with(continuation) { resumeUndispatched(Unit) }
Roman Elizarovdaa1d9d2017-03-02 19:00:50 +030027 })
Vsevolod Tolstopyatov80a29472018-04-17 16:02:02 +030028 continuation.invokeOnCancellation { timer.stop() }
Roman Elizarovdaa1d9d2017-03-02 19:00:50 +030029 }
30
31 override fun invokeOnTimeout(time: Long, unit: TimeUnit, block: Runnable): DisposableHandle {
32 val timer = schedule(time, unit, ActionListener {
33 block.run()
34 })
35 return object : DisposableHandle {
36 override fun dispose() {
37 timer.stop()
38 }
Roman Elizarova198bad2017-02-10 13:30:38 +030039 }
Roman Elizarovdaa1d9d2017-03-02 19:00:50 +030040 }
41
42 private fun schedule(time: Long, unit: TimeUnit, action: ActionListener): Timer =
43 Timer(unit.toMillis(time).coerceAtMost(Int.MAX_VALUE.toLong()).toInt(), action).apply {
Roman Elizarov3754f952017-01-18 20:47:54 +030044 isRepeats = false
45 start()
46 }
Roman Elizarova198bad2017-02-10 13:30:38 +030047
48 override fun toString() = "Swing"
Roman Elizarov3754f952017-01-18 20:47:54 +030049}