diff --git a/index.html b/index.html index 328d42a..a6c0214 100644 --- a/index.html +++ b/index.html @@ -69,7 +69,10 @@ document.getElementById("compile-button").addEventListener("click", () => { const code = document.getElementById("python-code").value; consoleElement.innerHTML = ""; // Clear console before running new code - pyodideWorker.postMessage({ code }); + pyodideWorker.postMessage({ + type: "execute", + code: code + }); }); // ✅ Update "distance" and "speed" every 2 seconds with random values diff --git a/pyodide-worker.js b/pyodide-worker.js index ba3c4db..350b562 100644 --- a/pyodide-worker.js +++ b/pyodide-worker.js @@ -1,30 +1,31 @@ importScripts("https://cdn.jsdelivr.net/pyodide/v0.23.4/full/pyodide.js"); -let sensorData = {}; // ✅ Declare sensorData globally +let sensorData = {}; // ✅ Store sensor values async function initializePyodide() { self.pyodide = await loadPyodide({ indexURL: "https://cdn.jsdelivr.net/pyodide/v0.23.4/full/" }); - // ✅ Explicitly define send_to_main before running Python self.pyodide.globals.set("send_to_main", (event, data) => { self.postMessage({ type: event, data: data }); }); - // ✅ Now set get_sensor_data AFTER Pyodide is initialized + // ✅ Expose sensor data to Python self.pyodide.globals.set("get_sensor_data", (name) => { - return sensorData[name] ?? null; // Return sensor value or null if not set + return sensorData[name] ?? null; }); - // ✅ Define the robot module in Python - self.pyodide.runPython(` + // ✅ Run Python initialization + await self.pyodide.runPythonAsync(` import sys import pyodide +import asyncio +import time class RobotModule: def get_sensor(self, name): - return get_sensor_data(name) # ✅ This should now work! + return get_sensor_data(name) robot = RobotModule() @@ -36,21 +37,27 @@ def turn(deg): class ConsoleOutput: def write(self, text): - if text.strip(): # Avoid empty writes - send_to_main("console", text) # ✅ send_to_main is now properly defined - return None + if text.strip(): + send_to_main("console", text) def flush(self): pass sys.stdout = ConsoleOutput() sys.stderr = ConsoleOutput() - -# ✅ Register robot module in sys.modules sys.modules["robot"] = robot + +# ✅ Override time.sleep() with an async version +_original_sleep = time.sleep # Backup original sleep + +async def async_sleep(seconds): + await asyncio.sleep(seconds) # ✅ Allows JavaScript to process events while sleeping + + +time.sleep = async_sleep # ✅ Monkey-patch time.sleep() `); - self.postMessage({ type: "ready" }); // Notify main thread that Pyodide is ready + self.postMessage({ type: "ready" }); // ✅ Notify main thread that Pyodide is ready } initializePyodide(); @@ -62,12 +69,11 @@ self.onmessage = async (event) => { } if (event.data.type === "sensor_update") { - // ✅ Update sensorData when receiving a sensor update + // ✅ Update sensor data Object.assign(sensorData, event.data.data); - } else { + } else if (event.data.type === "execute") { try { let result = await self.pyodide.runPythonAsync(event.data.code); - if (result !== undefined && result !== null && result !== "") { self.postMessage({ type: "console", data: result }); }