diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cf8ede211d..3605d0cb6d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ## 0.16.3 +* `Coroutines`: + * Create `launchInCurrentThread` * `Startup`: * `Launcher`: * All starting API have been moved into `StartLauncherPlugin` and do not require serialize/deserialize cycle for now diff --git a/coroutines/build.gradle b/coroutines/build.gradle index 968d31e1521..3dc3c1d4121 100644 --- a/coroutines/build.gradle +++ b/coroutines/build.gradle @@ -22,6 +22,7 @@ kotlin { dependencies { api libs.kt.coroutines.android } + dependsOn(jvmMain) } } } diff --git a/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchInCurrentThread.kt b/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchInCurrentThread.kt new file mode 100644 index 00000000000..d60e191281e --- /dev/null +++ b/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchInCurrentThread.kt @@ -0,0 +1,9 @@ +package dev.inmo.micro_utils.coroutines + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers + +fun launchInCurrentThread(block: suspend CoroutineScope.() -> T): T { + val scope = CoroutineScope(Dispatchers.Unconfined) + return scope.launchSynchronously(block) +} diff --git a/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchSynchronously.kt b/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchSynchronously.kt index e4fb735da36..7e9bfe5a205 100644 --- a/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchSynchronously.kt +++ b/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchSynchronously.kt @@ -6,7 +6,7 @@ fun CoroutineScope.launchSynchronously(block: suspend CoroutineScope.() -> T var result: Result? = null val objectToSynchronize = Object() synchronized(objectToSynchronize) { - launch { + launch(start = CoroutineStart.UNDISPATCHED) { result = safelyWithResult(block) }.invokeOnCompletion { synchronized(objectToSynchronize) { diff --git a/coroutines/src/jvmTest/kotlin/dev/inmo/micro_utils/coroutines/LaunchInCurrentThreadTests.kt b/coroutines/src/jvmTest/kotlin/dev/inmo/micro_utils/coroutines/LaunchInCurrentThreadTests.kt new file mode 100644 index 00000000000..e46f445e527 --- /dev/null +++ b/coroutines/src/jvmTest/kotlin/dev/inmo/micro_utils/coroutines/LaunchInCurrentThreadTests.kt @@ -0,0 +1,47 @@ +package dev.inmo.micro_utils.coroutines + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.withContext +import kotlin.test.Test +import kotlin.test.assertEquals + +class LaunchInCurrentThreadTests { + @Test + fun simpleTestThatLaunchInCurrentThreadWorks() { + val expectedResult = 10 + val result = launchInCurrentThread { + expectedResult + } + assertEquals(expectedResult, result) + } + @Test + fun simpleTestThatSeveralLaunchInCurrentThreadWorks() { + val testData = 0 until 100 + + testData.forEach { + val result = launchInCurrentThread { + it + } + assertEquals(it, result) + } + } + @Test + fun simpleTestThatLaunchInCurrentThreadWillCorrectlyHandleSuspensionsWorks() { + val testData = 0 until 100 + + suspend fun test(data: Any): Any { + return withContext(Dispatchers.Default) { + delay(1) + data + } + } + + testData.forEach { + val result = launchInCurrentThread { + test(it) + } + assertEquals(it, result) + } + } +}