feat(sim): P4 slice 2 — burnt parts go open + LED joins the charred visual
- The live solver now excludes runtime-destroyed components from the netlist, so a burnt part actually goes OPEN: its current stops and anything it fed loses power (cascading failure), the way real hardware behaves once a part burns out. Filter is in CircuitSimulationService.runSolve (no-op when nothing is burnt). - The LED's burnout now also marks it in the shared burntComponents set, so a burnt LED gets the same charred + smoke-badge visual (and is opened in the solve) as a resistor / capacitor, on top of going dark.
This commit is contained in:
parent
cbcf6ba81e
commit
e4aae82ca5
|
|
@ -1,5 +1,6 @@
|
|||
import { PartSimulationRegistry } from './PartSimulationRegistry';
|
||||
import { useElectricalStore } from '../../store/useElectricalStore';
|
||||
import { useSimulatorStore } from '../../store/useSimulatorStore';
|
||||
import { emitPropertyChange } from './partUtils';
|
||||
|
||||
/**
|
||||
|
|
@ -171,6 +172,14 @@ const LED_BURNOUT_A = 0.1;
|
|||
/** Surface a circuit fault for an LED — console + a UI event the toolbar shows. */
|
||||
function reportLedFault(componentId: string, kind: string, message: string): void {
|
||||
console.warn(`[led] ${componentId}: ${message}`);
|
||||
// Mark it destroyed in the shared burnt set (P4): the canvas renders it
|
||||
// charred + a smoke badge, and the solver opens it — same treatment as a
|
||||
// burnt resistor/capacitor. (The LED also goes dark via its own update.)
|
||||
try {
|
||||
useSimulatorStore.getState().markComponentBurnt?.(componentId);
|
||||
} catch {
|
||||
/* store unavailable (test env) — ignore */
|
||||
}
|
||||
if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function') {
|
||||
try {
|
||||
window.dispatchEvent(
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ export interface SimulatorStorePort {
|
|||
end: { componentId: string; pinName: string };
|
||||
}>;
|
||||
boards: Array<{ id: string; boardKind: string; pinStates?: Record<string, unknown> }>;
|
||||
/** Components destroyed at runtime (P4) — excluded from the netlist so a
|
||||
* burnt part actually goes open. Optional for non-store ports. */
|
||||
burntComponents?: Set<string>;
|
||||
};
|
||||
subscribe(listener: (state: unknown, prev: unknown) => void): () => void;
|
||||
}
|
||||
|
|
@ -279,8 +282,14 @@ export class CircuitSimulationService {
|
|||
|
||||
private async runSolve(): Promise<void> {
|
||||
const state = this.simStore.getState();
|
||||
// P4: a runtime-destroyed part is excluded from the netlist so it actually
|
||||
// goes open — its current stops and anything it fed loses power (cascading
|
||||
// failure), the way real hardware behaves once a component burns out.
|
||||
const burnt = state.burntComponents;
|
||||
const liveComponents =
|
||||
burnt && burnt.size > 0 ? state.components.filter((c) => !burnt.has(c.id)) : state.components;
|
||||
const snap = {
|
||||
components: state.components,
|
||||
components: liveComponents,
|
||||
wires: state.wires,
|
||||
boards: state.boards.map((b) => ({
|
||||
id: b.id,
|
||||
|
|
|
|||
Loading…
Reference in New Issue