fix(reset): clear display state + don't clobber Interconnect on Reset
Two paired bugs that surfaced on the Reset button.
(1) 7-segment / NeoPixel / LCD freeze on last pattern after Reset.
resetPinStates() was wiping the pinStates cache + outputPins set
silently — no listener notifications fired, so visual components
that update on pinChange kept rendering whatever segments were
lit at the instant the user pressed Reset. Now we snapshot every
pin that was HIGH before clearing and fan out a synthetic
(pin, false) to each registered listener. Stateful displays
redraw cleanly to all-off; passive listeners (analog sensors,
debounce-only buttons) ignore the synthetic LOW and recover on
their next real write.
(2) Cross-board serial silently dies after pressing Reset. resetBoard
was unconditionally reassigning:
sim.onSerialData = (ch) => appendSerial(boardId, ch);
immediately after sim.reset(). The comment said "re-wire after
reset" but reset() does NOT clear that property — the new USART's
onByteTransmit chains through `this.onSerialData` which IS the
Interconnect wrapper. The reassignment destroyed that wrapper and
sibling-board UART forwarding (Uno TX → Nano RX) stopped working
until a full page reload. Same root pattern as the initSimulator
bug fixed in 5480052 — Interconnect's __icSerialHookInstalled
flag is on the live sim, so once the wrapper is blown away
nothing reinstalls it. Removed the reassignment and left a NOTE
so the next person doesn't reintroduce it.
Verified the AVRSimulator + dual-arduino-software-serial +
interconnect-routing test suites still pass (26 tests).
This commit is contained in:
parent
5480052379
commit
7aca3db51c
|
|
@ -139,15 +139,34 @@ export class PinManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Clear cached pin states + output-pin classifications. Called by
|
||||
* Clear cached pin states + output-pin classifications. Called by
|
||||
* stopBoard / resetBoard so the next Run starts without stale output
|
||||
* classifications from a previous session forcing premature V-source
|
||||
* emission. Also keeps the test fixtures' fresh-triggerPinChange path
|
||||
* (the original reason this helper exists) working.
|
||||
* emission.
|
||||
*
|
||||
* Also notifies every listener that its pin returned to LOW when the
|
||||
* previously-cached state was HIGH. Without this notification,
|
||||
* stateful display components (7-segment, dot-matrix, NeoPixel, LCD
|
||||
* backlight) keep the last lit pattern frozen on screen after the
|
||||
* user presses Reset / Stop — their visual state only updates when a
|
||||
* pinChange callback fires, and resetPinStates was clearing the
|
||||
* cache silently. Listeners that ignore the synthetic LOW (analog
|
||||
* sensors, buttons) are unaffected; their next external write
|
||||
* overrides the false anyway.
|
||||
*/
|
||||
resetPinStates(): void {
|
||||
const wereHigh: number[] = [];
|
||||
for (const [pin, state] of this.pinStates) {
|
||||
if (state) wereHigh.push(pin);
|
||||
}
|
||||
this.pinStates.clear();
|
||||
this.outputPins.clear();
|
||||
for (const pin of wereHigh) {
|
||||
const callbacks = this.listeners.get(pin);
|
||||
if (callbacks) {
|
||||
callbacks.forEach((cb) => cb(pin, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── PWM duty cycle API ───────────────────────────────────────────────────
|
||||
|
|
|
|||
|
|
@ -1630,10 +1630,20 @@ export const useSimulatorStore = create<SimulatorState>((set, get) => {
|
|||
if (sim) {
|
||||
sim.reset();
|
||||
// Drop MCU-output classification so the new program starts
|
||||
// clean — no stale V-sources from the previous run.
|
||||
// clean — no stale V-sources from the previous run. The
|
||||
// resetPinStates call also notifies listeners that pins which
|
||||
// were HIGH are now LOW, so visual components (7-segment,
|
||||
// NeoPixel, LCD backlight) clear their stale state instead of
|
||||
// freezing on whatever pattern they had at the moment of
|
||||
// Reset.
|
||||
getBoardPinManager(boardId)?.resetPinStates();
|
||||
// Re-wire serial callback after reset
|
||||
sim.onSerialData = (ch) => appendSerial(boardId, ch);
|
||||
// NOTE: do NOT reassign sim.onSerialData here. sim.reset()
|
||||
// recreates the USART but the new usart.onByteTransmit
|
||||
// already chains through `this.onSerialData`, which is the
|
||||
// wrapper Interconnect installed for cross-board UART. The
|
||||
// previous "re-wire" line was destroying that wrapper and
|
||||
// silently breaking sibling-board serial forwarding after
|
||||
// every Reset press.
|
||||
if (sim instanceof AVRSimulator) {
|
||||
sim.onBaudRateChange = (baud) => {
|
||||
set((s) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue