merge: trabajo pi-family paralelo + fix de swipe tactil (ramas concurrentes del submodulo)

This commit is contained in:
David Montero Crespo 2026-07-28 16:09:57 +02:00
commit ebe2ab9d5a
1 changed files with 36 additions and 23 deletions

View File

@ -238,32 +238,45 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => {
// overlay owns the wiring via ProBoardDef.attachBuiltins; we hand it the DOM // overlay owns the wiring via ProBoardDef.attachBuiltins; we hand it the DOM
// element + the board's simulator/bridge handles shortly after run start // element + the board's simulator/bridge handles shortly after run start
// (the element and bridge need a beat to exist) and dispose on stop/unmount. // (the element and bridge need a beat to exist) and dispose on stop/unmount.
//
// Keyed on a STABLE run signature, not the boards array identity: `boards`
// is replaced on every serial batch (~60 Hz while output flows), and
// re-running this effect then detaches/re-attaches the peripherals in a
// loop — any event arriving inside the 500 ms re-attach window is lost
// (one-shot streams like a display list never recover, unlike the
// continuously-repainting SPI LCD decoders that masked this).
const attachKey = boards
.map((b) => `${b.id}:${b.boardKind}:${b.running ? 1 : 0}`)
.join('|');
useEffect(() => { useEffect(() => {
const cleanups: (() => void)[] = []; const cleanups: (() => void)[] = [];
boards.forEach((board) => { useSimulatorStore
const proDef = getProBoard(board.boardKind); .getState()
if (!proDef?.attachBuiltins || !board.running) return; .boards.forEach((board) => {
const timeout = setTimeout(() => { const proDef = getProBoard(board.boardKind);
const el = document.getElementById(board.id); if (!proDef?.attachBuiltins || !board.running) return;
if (!el) return; const timeout = setTimeout(() => {
try { const el = document.getElementById(board.id);
cleanups.push( if (!el) return;
proDef.attachBuiltins!({ try {
el, cleanups.push(
sim: getBoardSimulator(board.id), proDef.attachBuiltins!({
// ESP32-family boards get their QEMU/JS bridge; QEMU-Linux el,
// (piFamily) boards get the Raspberry Pi bridge instead. sim: getBoardSimulator(board.id),
bridge: getEsp32Bridge(board.id) ?? getBoardBridge(board.id), // ESP32-family boards get their QEMU/JS bridge; QEMU-Linux
}), // (piFamily) boards get the Raspberry Pi bridge instead.
); bridge: getEsp32Bridge(board.id) ?? getBoardBridge(board.id),
} catch (e) { }),
console.warn(`[${board.boardKind}] built-in peripheral attach failed:`, e); );
} } catch (e) {
}, 500); console.warn(`[${board.boardKind}] built-in peripheral attach failed:`, e);
cleanups.push(() => clearTimeout(timeout)); }
}); }, 500);
cleanups.push(() => clearTimeout(timeout));
});
return () => cleanups.forEach((fn) => fn()); return () => cleanups.forEach((fn) => fn());
}, [boards]); // eslint-disable-next-line react-hooks/exhaustive-deps
}, [attachKey]);
// Component selection // Component selection
const [selectedComponentId, setSelectedComponentId] = useState<string | null>(null); const [selectedComponentId, setSelectedComponentId] = useState<string | null>(null);