Skip to content

Commit 8b01d12

Browse files
committed
fix(simulator): deinit LVGL and reset driver/event_loop state between script runs
1 parent 9fdedb7 commit 8b01d12

1 file changed

Lines changed: 50 additions & 5 deletions

File tree

simulator/simulator.js

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,24 +227,69 @@ if "pyscript" not in sys.modules:
227227
// Ensure canvas dimensions match preset
228228
setCanvasResolution(currentResolution.width, currentResolution.height, currentResolution.shape);
229229

230-
// Set environment variables for board_config.py before user script runs
230+
// Cleanly reset previous driver / event_loop state before user script runs
231231
await pyodide.runPythonAsync(`
232232
import sys
233233
from displaydev import env_set
234+
234235
env_set("PYDEVICES_WIDTH", ${currentResolution.width})
235236
env_set("PYDEVICES_HEIGHT", ${currentResolution.height})
236237
env_set("PYDEVICES_CANVAS_ID", "display_canvas")
237238
238-
# If board_config is already in sys.modules, reload or update its display_drv
239+
# Clean up active LVGL event loop / display driver if present
240+
if "display_driver" in sys.modules:
241+
try:
242+
dd = sys.modules["display_driver"]
243+
if hasattr(dd, "event_loop"):
244+
inst = dd.event_loop.current_instance()
245+
if inst is not None:
246+
inst.deinit()
247+
if hasattr(dd, "app"):
248+
dd.app.stop_timer()
249+
except Exception:
250+
pass
251+
sys.modules.pop("display_driver", None)
252+
253+
# Fully deinit LVGL to prevent orphaned displays and stale render pipelines
254+
try:
255+
import lvgl as lv
256+
if lv.is_initialized():
257+
lv.deinit()
258+
except Exception:
259+
pass
260+
239261
if "board_config" in sys.modules:
240-
import importlib
241-
import board_config
242-
importlib.reload(board_config)
262+
sys.modules.pop("board_config", None)
263+
264+
if "appdev" in sys.modules:
265+
try:
266+
appdev = sys.modules["appdev"]
267+
if hasattr(appdev.App, "_instance"):
268+
appdev.App._instance = None
269+
except Exception:
270+
pass
243271
`);
244272

245273
// Execute user script
246274
await pyodide.runPythonAsync(code);
247275

276+
// If this is an LVGL script, pump task_handler to ensure immediate paint
277+
if (code.includes("lvgl") || code.includes("lv.")) {
278+
await pyodide.runPythonAsync(`
279+
try:
280+
import lvgl as lv
281+
if lv.is_initialized():
282+
lv.task_handler()
283+
if "display_driver" in sys.modules:
284+
dd = sys.modules["display_driver"]
285+
for drv in getattr(dd, "_drivers", []):
286+
if hasattr(drv, "display_drv") and hasattr(drv.display_drv, "show"):
287+
drv.display_drv.show()
288+
except Exception:
289+
pass
290+
`);
291+
}
292+
248293
const elapsed = ((performance.now() - t0) / 1000).toFixed(2);
249294
logConsole(`--- Completed in ${elapsed}s ---\n`, "success");
250295
setStatus("Ready", "ready");

0 commit comments

Comments
 (0)