blob: d6fdf5df66c72292f7af3b3892a54d4bc50cdd8d [file] [log] [blame]
Roman Elizarova7db8ec2017-12-21 22:45:12 +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 Elizarove1c0b652017-12-01 14:02:57 +030017package kotlinx.coroutines.experimental
18
Roman Elizarov1867f6d2018-01-13 11:20:32 +030019import kotlin.browser.*
Roman Elizarovf29203c2018-01-11 12:39:36 +030020import kotlin.coroutines.experimental.*
Roman Elizarove1c0b652017-12-01 14:02:57 +030021
Roman Elizarovecc68f12018-03-05 12:01:07 +030022private external val navigator: dynamic
23private const val UNDEFINED = "undefined"
24
Roman Elizarove1c0b652017-12-01 14:02:57 +030025/**
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 Pierce54d57e02018-02-10 14:35:58 -050029@Suppress("PropertyName", "UnsafeCastFromDynamic")
Roman Elizarov1867f6d2018-01-13 11:20:32 +030030public actual val DefaultDispatcher: CoroutineDispatcher = when {
Roman Elizarovecc68f12018-03-05 12:01:07 +030031 // 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 Elizarov1867f6d2018-01-13 11:20:32 +030037 // Check if we are in the browser and must use window.postMessage to avoid setTimeout throttling
Roman Elizarovecc68f12018-03-05 12:01:07 +030038 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 Elizarov1867f6d2018-01-13 11:20:32 +030041 else -> NodeDispatcher()
42}
Roman Elizarove1c0b652017-12-01 14:02:57 +030043
Roman Elizarovaa461cf2018-04-11 13:20:29 +030044internal actual val DefaultDelay: Delay = DefaultDispatcher as Delay
45
Roman Elizarove1c0b652017-12-01 14:02:57 +030046/**
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 Gorbunovf0cd1802018-04-17 19:59:31 +030050@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
Roman Elizarovaa461cf2018-04-11 13:20:29 +030051public actual fun newCoroutineContext(context: CoroutineContext, parent: Job? = null): CoroutineContext {
Roman Elizarove1c0b652017-12-01 14:02:57 +030052 val wp = if (parent == null) context else context + parent
53 return if (context !== DefaultDispatcher && context[ContinuationInterceptor] == null)
54 wp + DefaultDispatcher else wp
55}
Roman Elizarovb1708192017-12-22 12:14:05 +030056
Roman Elizarovf29203c2018-01-11 12:39:36 +030057// No debugging facilities on JS
58internal actual inline fun <T> withCoroutineContext(context: CoroutineContext, block: () -> T): T = block()
59internal actual fun Continuation<*>.toDebugString(): String = toString()
Roman Elizarovc12123e2018-01-24 22:07:12 +030060internal actual val CoroutineContext.coroutineName: String? get() = null // not supported on JS