martmists
02/13/2022, 3:01 PMgildor
02/13/2022, 3:40 PMmartmists
02/13/2022, 3:52 PM@JvmStatic
fun main(args: Array<String>) = runBlocking {
run()
}
override suspend fun run() {
coroutineScope {
ClientConnection(factory.connect("localhost", 22222)).apply {
spawn()
}
launch {
mainLoop() // LWJGL initialization and stuff goes here, not sure how to force this on main thread though in case that's needed. This function also blocks and the connection established above halts.
}
}
}
louiscad
02/13/2022, 3:54 PMrunBlocking
, if you need to suspend over blocking code, you can use withContext(<http://Dispatchers.IO|Dispatchers.IO>)
suspendCancellableCoroutine
, or callbackFlow
for repeat callbacks.martmists
02/13/2022, 3:57 PMlouiscad
02/13/2022, 3:59 PMmartmists
02/13/2022, 4:02 PMgildor
02/13/2022, 4:03 PMmartmists
02/13/2022, 4:05 PMlaunch
in the same coroutineScope
block.loop.run_in_executor
that runs in the main thread, as that doesn't block the background taskslouiscad
02/13/2022, 4:06 PMwithContext
martmists
02/13/2022, 4:07 PMwithContext(Dispatchers.Main) { myBlockingCode() }
?gildor
02/13/2022, 4:07 PMlouiscad
02/13/2022, 4:07 PMwithContext
using the asCoroutineDispatcher()
extension functionmartmists
02/13/2022, 4:08 PMlouiscad
02/13/2022, 4:08 PMmartmists
02/13/2022, 4:08 PMlouiscad
02/13/2022, 4:08 PMmartmists
02/13/2022, 4:09 PMgildor
02/13/2022, 4:10 PMlouiscad
02/13/2022, 4:10 PMmartmists
02/13/2022, 4:10 PMgildor
02/13/2022, 4:10 PMmartmists
02/13/2022, 4:11 PMspawn
simply calls launch {} on the current coroutineScopelouiscad
02/13/2022, 4:13 PMwithContext(Dispatchers.Main)
or with asCoroutineDispatcher()
and see if it's doing what I want. It seems that you're doing it the other way around, running UI stuff coming from a background thread.gildor
02/13/2022, 4:13 PMlouiscad
02/13/2022, 4:14 PMgildor
02/13/2022, 4:15 PMmartmists
02/13/2022, 4:15 PMgildor
02/13/2022, 4:15 PMmartmists
02/13/2022, 4:15 PMgildor
02/13/2022, 4:16 PMmartmists
02/13/2022, 4:17 PMgildor
02/13/2022, 4:17 PMmartmists
02/13/2022, 4:18 PMlaunch
,I get this warning from sonarlint: SonarLint: Remove this dispatcher. It is pointless when used with only suspending functions.
Is this a bug in sonarlint or is the dispatcher parameter not necessary here?gildor
02/13/2022, 4:20 PMmartmists
02/13/2022, 4:21 PMgildor
02/13/2022, 4:24 PMNick Allen
02/13/2022, 9:58 PMmainLoop
) from blocking code(main
).
You can see https://github.com/Kotlin/kotlinx.coroutines/tree/master/ui/kotlinx-coroutines-swing for how to make Dispatchers.Main
run code within a particular event loop. Replace SwingUtilities.invokeLater
and the like with equivalent LWJGL code. Make sure you register the service in META-INF.
If you don't care about hooking up Dispatchers.Main
, then you can just create a simple Executor
that posts to the main event loop, and use myMainPostingExecutor.asCoroutineDispatcher()
instead of Dispatchers.Main
.
Create a coroutine scope: val mainScope = MainScope() + Dispatchers.Main.immediate
(or val mainScope = CoroutineScope(SupervisorJob()) + myMainPostingExecutor.asCoroutineDispatcher()
)
Then in your event callbacks you can do something like:
glfwSetKeyCallback(window) {window, key, scancode, action, mods ->
mainScope.launch {
val result = doSuspendingMethod()
updateUI(result) // This is running on main thread
});
gildor
02/14/2022, 6:39 AM// This is running on main threadIt doesn’t run on main thread, it runs on myMainPostingExecutor Own dispatcher is definitely one of ways to work, but it’s not a real main thread, you cannot send events back to UI with it
then you can just create a simpleIf you can send events to main loop from another thread, then I think it’s better and easier to implement Disaptchers.Mainthat posts to the main event loopExecutor
Nick Allen
02/14/2022, 7:26 AMOwn dispatcher is definitely one of ways to work, but it’s not a real main thread, you cannot send events back to UI with itThis is false, or at least misleading/confusing. It’s a real main thread, reguardless of how you post events to it. Hooking up
Dispatchers.Main
is the standard and clearest way to do it. I missed explicitly recommending it.gildor
02/14/2022, 4:00 PM