fix(toolbar): Run follows the disabled-while-running convention on QEMU-Linux boards; Reset is the fast re-run

Keeping Play enabled while the guest ran broke the convention every
other board follows (owner report). Run now disables as usual; RESET on
a booted guest re-uploads the edited files and re-runs the script
without the ~45 s reboot, matching Reset's restart-the-program meaning.
This commit is contained in:
David Montero Crespo 2026-07-28 22:05:36 +02:00
parent 330b9ed1b2
commit 7da01c6a91
1 changed files with 36 additions and 26 deletions

View File

@ -818,26 +818,21 @@ export const EditorToolbar = ({
// boot straight from the rootfs — there is no firmware to compile, // boot straight from the rootfs — there is no firmware to compile,
// and handleCompile's Pi early-return never sets compiledProgram, so // and handleCompile's Pi early-return never sets compiledProgram, so
// the gate below would surface a bogus "Compilation produced no // the gate below would surface a bogus "Compilation produced no
// firmware" error. Power the board on directly; if the guest is // firmware" error. Power the board on directly (Run follows the
// ALREADY booted, skip the ~45 s reboot: interrupt the running // standard disabled-while-running convention; RESET is the fast
// script, re-upload the edited files and run again. This branch must // re-run-without-reboot on a booted guest). Must stay ABOVE the
// stay ABOVE the generic stop-then-boot restart below, which would // generic stop-then-boot restart below.
// otherwise power-cycle the live guest.
if (isPiBoardKind(board?.boardKind ?? '')) { if (isPiBoardKind(board?.boardKind ?? '')) {
trackRunSimulation(board?.boardKind); trackRunSimulation(board?.boardKind);
reportRun(board?.boardKind); reportRun(board?.boardKind);
if (board?.running && board?.piBooted) { if (board?.running) {
console.log('[handleRun] → piRerunScript (booted, no reboot)', activeBoardId); // Zombie/edge case (Run is normally disabled while running):
await piRerunScript(activeBoardId, board.boardKind); // power-cycle for a clean boot.
} else { stopBoard(activeBoardId);
if (board?.running) { await new Promise((resolve) => setTimeout(resolve, 300));
// Running but never reached the shell (stuck/zombie): power-cycle.
stopBoard(activeBoardId);
await new Promise((resolve) => setTimeout(resolve, 300));
}
console.log('[handleRun] → startBoard (QEMU-Linux, no firmware)', activeBoardId);
startBoard(activeBoardId);
} }
console.log('[handleRun] → startBoard (QEMU-Linux, no firmware)', activeBoardId);
startBoard(activeBoardId);
setMessage(null); setMessage(null);
return; return;
} }
@ -974,6 +969,15 @@ export const EditorToolbar = ({
const handleReset = () => { const handleReset = () => {
trackResetSimulation(); trackResetSimulation();
// QEMU-Linux boards: Reset = re-upload the edited files and re-run the
// script on the live guest (no ~45 s reboot). Mirrors what Reset means
// elsewhere — restart the program — while Run keeps the standard
// disabled-while-running behaviour.
if (activeBoard && isPiBoardKind(activeBoard.boardKind) && activeBoard.piBooted) {
void piRerunScript(activeBoard.id, activeBoard.boardKind);
setMessage(null);
return;
}
if (activeBoardId) resetBoard(activeBoardId); if (activeBoardId) resetBoard(activeBoardId);
else resetSimulation(); else resetSimulation();
setMessage(null); setMessage(null);
@ -1478,13 +1482,7 @@ export const EditorToolbar = ({
? digitalRunning || verifying ? digitalRunning || verifying
: isMultiBoard : isMultiBoard
? compileAllRunning || anyBoardRunning || verifying ? compileAllRunning || anyBoardRunning || verifying
: // QEMU-Linux boards keep Run enabled while running: : running || compiling || verifying || !activeBoard
// on a booted guest it re-uploads the edited files
// and re-runs the script without the ~45 s reboot.
(running && !isPiBoardKind(activeBoard?.boardKind ?? '')) ||
compiling ||
verifying ||
!activeBoard
} }
className="tb-btn tb-btn-run" className="tb-btn tb-btn-run"
title={ title={
@ -1588,12 +1586,24 @@ export const EditorToolbar = ({
</svg> </svg>
</button> </button>
{/* Reset */} {/* Reset for a booted QEMU-Linux guest this re-uploads the
edited files and re-runs the script without rebooting. */}
<button <button
onClick={handleReset} onClick={handleReset}
disabled={!compiledHex && !activeBoard?.compiledProgram} disabled={
isPiBoardKind(activeBoard?.boardKind ?? '')
? !activeBoard?.piBooted
: !compiledHex && !activeBoard?.compiledProgram
}
className="tb-btn tb-btn-reset" className="tb-btn tb-btn-reset"
title={t('editor.toolbar.reset')} title={
isPiBoardKind(activeBoard?.boardKind ?? '')
? t(
'editor.toolbar.rerunScript',
'Re-run script with your latest edits (no reboot)',
)
: t('editor.toolbar.reset')
}
> >
<svg <svg
width="18" width="18"