Last active
August 5, 2019 21:35
-
-
Save Groostav/49cce5f623d96679abbccfeca295da4a to your computer and use it in GitHub Desktop.
Strategy to synchronously enter asynchronous code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.empowerops.common | |
import com.sun.javafx.tk.Toolkit | |
import kotlinx.coroutines.* | |
import kotlinx.coroutines.javafx.JavaFx | |
import java.util.* | |
private class ExceptionWrapper(val ex: Throwable) | |
private val toolkit = Toolkit.getToolkit() | |
fun <R> enterNestedJavaFxEventLoop(block: suspend CoroutineScope.() -> R): R { | |
require(BootstrappingUtilities.isFXApplicationThread()) | |
//this is required to avoid a race in the enter/exit strategy. | |
val key = UUID.randomUUID() | |
// regarding races: as long as launch does not run eagerly, | |
// then we know for certainty that this job is in the queue blocked by this current running method | |
// thus we cannot exit the nested event loop before we enter it | |
GlobalScope.launch(Dispatchers.JavaFx, CoroutineStart.DEFAULT){ | |
try { | |
val result = block() | |
toolkit.exitNestedEventLoop(key, result) | |
} | |
catch(ex: Throwable){ | |
toolkit.exitNestedEventLoop(key, ExceptionWrapper(ex)) | |
} | |
} | |
val result = toolkit.enterNestedEventLoop(key) | |
when { | |
//note: we dont need to wrap result.ex because of the nested event loop strategy. | |
// remember this is all call-stack games, we dont actually have any suspension here, | |
// so we dont need to mangle exceptions to make them readable. | |
// alternatively put: any exception generated here will have all of its stacktrace in result.ex's stacktrace. | |
result is ExceptionWrapper -> throw result.ex | |
else -> @Suppress("UNCHECKED_CAST") return result as R | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment