From 5381261f0fee3908808f145bbe116e81ab29e55c Mon Sep 17 00:00:00 2001 From: Fischer Moseley <42497969+fischermoseley@users.noreply.github.com> Date: Sun, 14 Apr 2024 20:57:16 -0700 Subject: [PATCH] web: add non-blocking I/O via Web Worker --- doc/javascripts/serial.js | 17 +++++++--- doc/javascripts/webTerminal.js | 62 ++++++++++++++-------------------- 2 files changed, 38 insertions(+), 41 deletions(-) diff --git a/doc/javascripts/serial.js b/doc/javascripts/serial.js index 9640771..c82e657 100644 --- a/doc/javascripts/serial.js +++ b/doc/javascripts/serial.js @@ -17,7 +17,6 @@ async function write(data) { const writer = port.writable.getWriter(); await writer.write(new TextEncoder().encode(data)); await writer.releaseLock(); - console.log('Sent:', data); } async function read() { @@ -27,8 +26,18 @@ async function read() { reader.releaseLock(); if (!done) { - const data = new TextDecoder().decode(value); - console.log('Received:', data); - return data; + return new TextDecoder().decode(value); } } + +self.addEventListener('message', async function(event) { + await write(event.data); +}); + +async function readWrapper() { + if (port) { + self.postMessage(await read()); // this is a hack but i'm curious + } +} + +setInterval(readWrapper, 500); \ No newline at end of file diff --git a/doc/javascripts/webTerminal.js b/doc/javascripts/webTerminal.js index b59edcd..17cb7db 100644 --- a/doc/javascripts/webTerminal.js +++ b/doc/javascripts/webTerminal.js @@ -4,6 +4,21 @@ async function selectPort(){ await navigator.serial.requestPort(); } +// Start Web Worker for Serial API +globalThis.receiveBuffer = []; + +const serialWorker = new Worker("../javascripts/serial.js"); +function sendToSerialWorker(data){ + console.log("Main -> Worker: ", data); + serialWorker.postMessage(data); +} + +serialWorker.onmessage = (e) => { + console.log("Worker -> Main: ", e.data); + receiveBuffer.push(e.data); +}; + +// Main function for the Web Terminal async function WebTerminal(data){ let pyodide = await loadPyodide(); @@ -18,47 +33,20 @@ async function WebTerminal(data){ pyodide.runPythonAsync(` import asyncio - import time - - from js import read, write - from manta.utils import value_to_words - + from js import sendToSerialWorker + from js import receiveBuffer from manta import Manta - m = Manta("/manta.yaml") - print(m.my_io_core) - async def set_probe(name, value): - # Write value to core - probe = m.my_io_core._memory_map.get(name) - addrs = probe["addrs"] - datas = value_to_words(value, len(addrs)) - for a, d in zip(addrs, datas): - await write(a, d) + #m = Manta("/manta.yaml") - # Pulse strobe register - await write(m.my_io_core._base_addr, 0) - await write(m.my_io_core._base_addr, 1) - await write(m.my_io_core._base_addr, 0) + print("Sending read request") + sendToSerialWorker("R0000\\r\\n") - async def foobar(): - for i in range(10): - await set_probe(f"LED{i%4}", 1) - await set_probe(f"LED{i%4}", 0) - print(i) + for _ in range(10): + print(len(receiveBuffer)) + print(receiveBuffer) + await asyncio.sleep(0.1) - #loop = asyncio.get_event_loop() - #loop.run_until_complete(foobar()) - - async def barfoo(): - print("entering barfoo") - await write("R0000\\r\\n") - print(await read()) - - - loop = asyncio.get_event_loop() - loop.run_until_complete(barfoo()) - #asyncio.run(foobar()) # doesn't work! asyncio.run() cannot be called from a running event loop - #await foobar() # doesn't work either! await outside function - #await barfoo() # doesn't work either! await outside function + print("Python Complete") `); }