Skip to content

Commit

Permalink
Workers. Common factory for WorkerFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
turansky committed Nov 18, 2024
1 parent 18d5373 commit 0630899
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -1,30 +1,12 @@
package web.workers

import js.coroutines.internal.IsolatedCoroutineScope
import js.globals.globalThis
import js.reflect.unsafeCast
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.launch

fun SharedWorkerFactory(
block: suspend CoroutineScope.(self: SharedWorkerGlobalScope) -> Unit,
): WorkerFactory<SharedWorker> {
val self = if (globalThis["SharedWorkerGlobalScope"] != null) {
globalThis as? SharedWorkerGlobalScope
} else null

requireNotNull(self) {
"Invalid shared worker context! `SharedWorkerGlobalScope` as `self` is required!"
}

IsolatedCoroutineScope()
.launch(
start = CoroutineStart.UNDISPATCHED,
block = { block(self) },
)

return unsafeCast {
error("Missed plugin integration! SharedWorker factory shouldn't be called directly!")
}
}
): WorkerFactory<SharedWorker> =
createWorkerFactory(
workerName = "SharedWorker",
scopeClassName = "SharedWorkerGlobalScope",
block = block,
)
30 changes: 6 additions & 24 deletions kotlin-browser/src/jsMain/kotlin/web/workers/WorkerFactory.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package web.workers

import js.coroutines.internal.IsolatedCoroutineScope
import js.globals.globalThis
import js.reflect.unsafeCast
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.launch
import seskar.js.JsNative

sealed external interface WorkerFactory<T : AbstractWorker> {
Expand All @@ -15,22 +10,9 @@ sealed external interface WorkerFactory<T : AbstractWorker> {

fun WorkerFactory(
block: suspend CoroutineScope.(self: DedicatedWorkerGlobalScope) -> Unit,
): WorkerFactory<Worker> {
val self = if (globalThis["DedicatedWorkerGlobalScope"] != null) {
globalThis as? DedicatedWorkerGlobalScope
} else null

requireNotNull(self) {
"Invalid worker context! `DedicatedWorkerGlobalScope` as `self` is required!"
}

IsolatedCoroutineScope()
.launch(
start = CoroutineStart.UNDISPATCHED,
block = { block(self) },
)

return unsafeCast {
error("Missed plugin integration! Worker factory shouldn't be called directly!")
}
}
): WorkerFactory<Worker> =
createWorkerFactory(
workerName = "Worker",
scopeClassName = "DedicatedWorkerGlobalScope",
block = block,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package web.workers

import js.coroutines.internal.IsolatedCoroutineScope
import js.globals.globalThis
import js.reflect.unsafeCast
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.launch
import kotlin.reflect.cast

internal fun <T : AbstractWorker, S : WorkerGlobalScope> createWorkerFactory(
workerName: String,
scopeClassName: String,
block: suspend CoroutineScope.(self: S) -> Unit,
): WorkerFactory<T> {
val self: S = getGlobalScope(scopeClassName)

IsolatedCoroutineScope()
.launch(
start = CoroutineStart.UNDISPATCHED,
block = { block(self) },
)

return unsafeCast {
error("Missed plugin integration! $workerName factory shouldn't be called directly!")
}
}

private fun <S : WorkerGlobalScope> getGlobalScope(
scopeClassName: String,
): S {
val jsClass = globalThis[scopeClassName]
?: error("Class `$scopeClassName` not found!")

val kotlinClass = unsafeCast<JsClass<S>>(jsClass).kotlin
return kotlinClass.cast(globalThis)
}

0 comments on commit 0630899

Please sign in to comment.