web: add non-blocking I/O via Web Worker

This commit is contained in:
Fischer Moseley 2024-04-14 20:57:16 -07:00
parent e2752e30d5
commit 5381261f0f
2 changed files with 38 additions and 41 deletions

View File

@ -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);

View File

@ -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")
`);
}