diff --git a/src/PyodideWorker.js b/src/PyodideWorker.js index 811467bb3..e755b621f 100644 --- a/src/PyodideWorker.js +++ b/src/PyodideWorker.js @@ -42,6 +42,26 @@ const PyodideWorker = () => { case "writeFile": pyodide.FS.writeFile(data.filename, encoder.encode(data.content)); break; + case "setCanvas": + if (data.canvas) { + pyodide._api._skip_unwind_fatal_error = true; + // telll pyodide that this is the canvas to use for SDL2 + // globalThis.canvas = data.canvas; // Store the OffscreenCanvas globally in the worker + // Now, register it with Pyodide + // pyodide.globals.set("js_canvas", data.canvas); + // console.log(data.canvas); + // globalThis.screen = { width: 100, height: 100 }; + pyodide.runPython(` + #import js + #import sdl2.ext + #sdl2.ext.init() + #sdl2.ext.window = js.js_canvas + globals()['screen'] = {'width': 100, 'height': 100} + `); + pyodide.canvas.setCanvas2D(data.canvas); + } + break; + case "runPython": runPython(data.python); break; @@ -367,6 +387,22 @@ const PyodideWorker = () => { `); }, }, + pygame: { + before: async () => { + await pyodide.loadPackage("pygame-ce"); + pyodide.runPython(` + from pygame import display + print("pygame is running!") + + def _custom_flip(): + print("pygame.flip() called") + + display.flip = _custom_flip + display.update = _custom_flip + `); + }, + after: () => {}, + }, }; const fakeBasthonPackage = { diff --git a/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.jsx b/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.jsx index 0d39afe80..e73136283 100644 --- a/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.jsx +++ b/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.jsx @@ -259,6 +259,24 @@ const PyodideRunner = ({ active, outputPanels = ["text", "visual"] }) => { setVisuals([]); stdinClosed.current = false; + const canvas = document + .querySelector("editor-wc") + .shadowRoot.getElementById("sdl2Canvas"); + if (canvas) { + console.log("Setting up canvas for Pyodide"); + let offScreenCanvas = canvas; + if ( + canvas.transferControlToOffscreen && + !(canvas instanceof OffscreenCanvas) + ) { + offScreenCanvas = canvas.transferControlToOffscreen(); + } + pyodideWorker.postMessage( + { method: "setCanvas", canvas: offScreenCanvas }, + [offScreenCanvas], + ); + } + await Promise.allSettled( projectImages.map(({ filename, url }) => fetch(url) diff --git a/src/components/Editor/Runners/PythonRunner/PyodideRunner/VisualOutputPane.jsx b/src/components/Editor/Runners/PythonRunner/PyodideRunner/VisualOutputPane.jsx index dadb12c6f..799acbef8 100644 --- a/src/components/Editor/Runners/PythonRunner/PyodideRunner/VisualOutputPane.jsx +++ b/src/components/Editor/Runners/PythonRunner/PyodideRunner/VisualOutputPane.jsx @@ -74,6 +74,7 @@ const VisualOutputPane = ({ visuals, setVisuals }) => { return (
+ {senseHatEnabled || senseHatAlways ? : null}
);