Roman Elizarov | a7db8ec | 2017-12-21 22:45:12 +0300 | [diff] [blame] | 1 | /* |
| 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 Elizarov | e1c0b65 | 2017-12-01 14:02:57 +0300 | [diff] [blame] | 17 | package kotlinx.coroutines.experimental |
| 18 | |
Roman Elizarov | 1867f6d | 2018-01-13 11:20:32 +0300 | [diff] [blame] | 19 | import kotlin.browser.* |
Roman Elizarov | f29203c | 2018-01-11 12:39:36 +0300 | [diff] [blame] | 20 | import kotlin.coroutines.experimental.* |
Roman Elizarov | e1c0b65 | 2017-12-01 14:02:57 +0300 | [diff] [blame] | 21 | |
Roman Elizarov | ecc68f1 | 2018-03-05 12:01:07 +0300 | [diff] [blame] | 22 | private external val navigator: dynamic |
| 23 | private const val UNDEFINED = "undefined" |
| 24 | |
Roman Elizarov | e1c0b65 | 2017-12-01 14:02:57 +0300 | [diff] [blame] | 25 | /** |
| 26 | * This is the default [CoroutineDispatcher] that is used by all standard builders like |
| 27 | * [launch], [async], etc if no dispatcher nor any other [ContinuationInterceptor] is specified in their context. |
| 28 | */ |
Scott Pierce | 54d57e0 | 2018-02-10 14:35:58 -0500 | [diff] [blame] | 29 | @Suppress("PropertyName", "UnsafeCastFromDynamic") |
Roman Elizarov | 1867f6d | 2018-01-13 11:20:32 +0300 | [diff] [blame] | 30 | public actual val DefaultDispatcher: CoroutineDispatcher = when { |
Roman Elizarov | ecc68f1 | 2018-03-05 12:01:07 +0300 | [diff] [blame] | 31 | // Check if we are running under ReactNative. We have to use NodeDispatcher under it. |
| 32 | // The problem is that ReactNative has a `window` object with `addEventListener`, but it does not really work. |
| 33 | // For details see https://github.com/Kotlin/kotlinx.coroutines/issues/236 |
| 34 | // The check for ReactNative is based on https://github.com/facebook/react-native/commit/3c65e62183ce05893be0822da217cb803b121c61 |
| 35 | jsTypeOf(navigator) != UNDEFINED && navigator != null && navigator.product == "ReactNative" -> |
| 36 | NodeDispatcher() |
Roman Elizarov | 1867f6d | 2018-01-13 11:20:32 +0300 | [diff] [blame] | 37 | // Check if we are in the browser and must use window.postMessage to avoid setTimeout throttling |
Roman Elizarov | ecc68f1 | 2018-03-05 12:01:07 +0300 | [diff] [blame] | 38 | jsTypeOf(window) != UNDEFINED && window.asDynamic() != null && jsTypeOf(window.asDynamic().addEventListener) != UNDEFINED -> |
| 39 | window.asCoroutineDispatcher() |
| 40 | // Fallback to NodeDispatcher when browser environment is not detected |
Roman Elizarov | 1867f6d | 2018-01-13 11:20:32 +0300 | [diff] [blame] | 41 | else -> NodeDispatcher() |
| 42 | } |
Roman Elizarov | e1c0b65 | 2017-12-01 14:02:57 +0300 | [diff] [blame] | 43 | |
Roman Elizarov | aa461cf | 2018-04-11 13:20:29 +0300 | [diff] [blame] | 44 | internal actual val DefaultDelay: Delay = DefaultDispatcher as Delay |
| 45 | |
Roman Elizarov | e1c0b65 | 2017-12-01 14:02:57 +0300 | [diff] [blame] | 46 | /** |
| 47 | * Creates context for the new coroutine. It installs [DefaultDispatcher] when no other dispatcher nor |
| 48 | * [ContinuationInterceptor] is specified, and adds optional support for debugging facilities (when turned on). |
| 49 | */ |
Ilya Gorbunov | f0cd180 | 2018-04-17 19:59:31 +0300 | [diff] [blame] | 50 | @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") |
Roman Elizarov | aa461cf | 2018-04-11 13:20:29 +0300 | [diff] [blame] | 51 | public actual fun newCoroutineContext(context: CoroutineContext, parent: Job? = null): CoroutineContext { |
Roman Elizarov | e1c0b65 | 2017-12-01 14:02:57 +0300 | [diff] [blame] | 52 | val wp = if (parent == null) context else context + parent |
| 53 | return if (context !== DefaultDispatcher && context[ContinuationInterceptor] == null) |
| 54 | wp + DefaultDispatcher else wp |
| 55 | } |
Roman Elizarov | b170819 | 2017-12-22 12:14:05 +0300 | [diff] [blame] | 56 | |
Roman Elizarov | f29203c | 2018-01-11 12:39:36 +0300 | [diff] [blame] | 57 | // No debugging facilities on JS |
| 58 | internal actual inline fun <T> withCoroutineContext(context: CoroutineContext, block: () -> T): T = block() |
| 59 | internal actual fun Continuation<*>.toDebugString(): String = toString() |
Roman Elizarov | c12123e | 2018-01-24 22:07:12 +0300 | [diff] [blame] | 60 | internal actual val CoroutineContext.coroutineName: String? get() = null // not supported on JS |