summaryrefslogtreecommitdiff
path: root/src/main/kotlin/asyncio.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/asyncio.kt')
-rw-r--r--src/main/kotlin/asyncio.kt61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/main/kotlin/asyncio.kt b/src/main/kotlin/asyncio.kt
new file mode 100644
index 0000000..e14fea9
--- /dev/null
+++ b/src/main/kotlin/asyncio.kt
@@ -0,0 +1,61 @@
+import kotlin.coroutines.*
+
+class IORunner : Continuation<Unit> {
+ var nextStep: Continuation<Unit>? = null
+ val eventQueue = ArrayDeque<String>()
+ fun _CALLED_BY_JS_onInput(str: String) {
+ eventQueue.addLast(str)
+ awake()
+ }
+
+ fun _CALLED_BY_JS_onWhatever() {
+ awake()
+ }
+
+ private fun awake() {
+ val step = nextStep
+ if (step != null) {
+ nextStep = null
+ step.resume(Unit)
+ }
+ }
+
+ suspend fun wait() {
+ return suspendCoroutine { c ->
+ console.log("SUSPENDING COROUTINE")
+ nextStep = c
+ }
+ }
+
+ override val context: CoroutineContext
+ get() = EmptyCoroutineContext
+
+ override fun resumeWith(result: Result<Unit>) {
+ if (result.isFailure) {
+ result.exceptionOrNull()?.printStackTrace()
+ } else {
+ println("IORunner exited successfully")
+ }
+ }
+
+ companion object {
+ fun runOnIO(block: suspend IORunner.() -> Unit): IORunner {
+ val r = IORunner()
+ block.startCoroutine(r, r)
+ return r
+ }
+ }
+}
+
+
+suspend fun IORunner.getOneKey(): String {
+ while (true) {
+ val x = eventQueue.removeFirstOrNull()
+ if (x == null)
+ wait()
+ else {
+ return x
+ }
+ }
+}
+