feat: enhance simulator interfaces and add ESP32 bridge shim for improved component interaction
parent
ee7281383c
commit
84370e6f8d
|
|
@ -1,7 +1,14 @@
|
|||
import { AVRSimulator } from '../AVRSimulator';
|
||||
import { RP2040Simulator } from '../RP2040Simulator';
|
||||
|
||||
export type AnySimulator = AVRSimulator | RP2040Simulator;
|
||||
/** Any simulator that components can interact with (AVR, RP2040, or ESP32 bridge shim). */
|
||||
export type AnySimulator = {
|
||||
setPinState(pin: number, state: boolean): void;
|
||||
isRunning(): boolean;
|
||||
pinManager: import('../PinManager').PinManager;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[key: string]: any;
|
||||
} | AVRSimulator | RP2040Simulator;
|
||||
|
||||
/**
|
||||
* Interface for simulation logic mapped to a specific wokwi-element
|
||||
|
|
|
|||
|
|
@ -35,8 +35,41 @@ export const BOARD_LABELS: Record<BoardType, string> = {
|
|||
export const DEFAULT_BOARD_POSITION = { x: 50, y: 50 };
|
||||
export const ARDUINO_POSITION = DEFAULT_BOARD_POSITION;
|
||||
|
||||
// ── Lightweight shim wrapping Esp32Bridge so component simulations (DHT22, etc.)
|
||||
// can call setPinState / pinManager just like they would on a local simulator. ──
|
||||
class Esp32BridgeShim {
|
||||
pinManager: PinManager;
|
||||
onSerialData: ((ch: string) => void) | null = null;
|
||||
onPinChangeWithTime: ((pin: number, state: boolean, timeMs: number) => void) | null = null;
|
||||
onBaudRateChange: ((baud: number) => void) | null = null;
|
||||
private bridge: Esp32Bridge;
|
||||
|
||||
constructor(bridge: Esp32Bridge, pm: PinManager) {
|
||||
this.bridge = bridge;
|
||||
this.pinManager = pm;
|
||||
}
|
||||
|
||||
setPinState(pin: number, state: boolean): void { this.bridge.sendPinEvent(pin, state); }
|
||||
getCurrentCycles(): number { return -1; }
|
||||
getClockHz(): number { return 240_000_000; }
|
||||
isRunning(): boolean { return this.bridge.connected; }
|
||||
serialWrite(text: string): void {
|
||||
this.bridge.sendSerialBytes(Array.from(new TextEncoder().encode(text)));
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
getADC(): any { return null; }
|
||||
getMCU(): null { return null; }
|
||||
start(): void { /* managed by bridge */ }
|
||||
stop(): void { /* managed by bridge */ }
|
||||
reset(): void { /* managed by bridge */ }
|
||||
setSpeed(_s: number): void { /* no-op */ }
|
||||
getSpeed(): number { return 1; }
|
||||
loadHex(_hex: string): void { /* no-op */ }
|
||||
loadBinary(_b64: string): void { /* no-op */ }
|
||||
}
|
||||
|
||||
// ── Runtime Maps (outside Zustand — not serialisable) ─────────────────────
|
||||
const simulatorMap = new Map<string, AVRSimulator | RP2040Simulator | RiscVSimulator | Esp32C3Simulator>();
|
||||
const simulatorMap = new Map<string, AVRSimulator | RP2040Simulator | RiscVSimulator | Esp32C3Simulator | Esp32BridgeShim>();
|
||||
const pinManagerMap = new Map<string, PinManager>();
|
||||
const bridgeMap = new Map<string, RaspberryPi3Bridge>();
|
||||
const esp32BridgeMap = new Map<string, Esp32Bridge>();
|
||||
|
|
@ -97,7 +130,7 @@ interface SimulatorState {
|
|||
/** @deprecated use boards[x].x/y */
|
||||
boardPosition: { x: number; y: number };
|
||||
/** @deprecated use getBoardSimulator(activeBoardId) */
|
||||
simulator: AVRSimulator | RP2040Simulator | RiscVSimulator | Esp32C3Simulator | null;
|
||||
simulator: AVRSimulator | RP2040Simulator | RiscVSimulator | Esp32C3Simulator | Esp32BridgeShim | null;
|
||||
/** @deprecated use getBoardPinManager(activeBoardId) */
|
||||
pinManager: PinManager;
|
||||
running: boolean;
|
||||
|
|
@ -337,6 +370,11 @@ export const useSimulatorStore = create<SimulatorState>((set, get) => {
|
|||
}
|
||||
};
|
||||
esp32BridgeMap.set(id, bridge);
|
||||
// Provide a shim so PartSimulationRegistry components (DHT22, etc.)
|
||||
// can call setPinState / access pinManager on ESP32 boards.
|
||||
const shim = new Esp32BridgeShim(bridge, pm);
|
||||
shim.onSerialData = serialCallback;
|
||||
simulatorMap.set(id, shim);
|
||||
} else {
|
||||
const sim = createSimulator(
|
||||
boardKind,
|
||||
|
|
@ -645,10 +683,13 @@ export const useSimulatorStore = create<SimulatorState>((set, get) => {
|
|||
}
|
||||
};
|
||||
esp32BridgeMap.set(boardId, bridge);
|
||||
const shim = new Esp32BridgeShim(bridge, pm);
|
||||
shim.onSerialData = serialCallback;
|
||||
simulatorMap.set(boardId, shim);
|
||||
|
||||
set((s) => ({
|
||||
boardType: type,
|
||||
simulator: null,
|
||||
simulator: shim as any,
|
||||
compiledHex: null,
|
||||
serialOutput: '',
|
||||
serialBaudRate: 0,
|
||||
|
|
|
|||
|
|
@ -132,6 +132,13 @@ const ESP32_PIN_MAP: Record<string, number> = {
|
|||
'GPIO25': 25, 'GPIO26': 26, 'GPIO27': 27,
|
||||
'GPIO32': 32, 'GPIO33': 33, 'GPIO34': 34, 'GPIO35': 35,
|
||||
'GPIO36': 36, 'GPIO39': 39,
|
||||
// Wokwi element "D" prefix aliases (esp32-devkit-v1-element pin names)
|
||||
'D2': 2, 'D4': 4, 'D5': 5,
|
||||
'D12': 12, 'D13': 13, 'D14': 14, 'D15': 15,
|
||||
'D16': 16, 'D17': 17, 'D18': 18, 'D19': 19,
|
||||
'D21': 21, 'D22': 22, 'D23': 23,
|
||||
'D25': 25, 'D26': 26, 'D27': 27,
|
||||
'D32': 32, 'D33': 33, 'D34': 34, 'D35': 35,
|
||||
// ADC aliases
|
||||
'VP': 36, 'VN': 39,
|
||||
// Power / GND — not real GPIOs; mapped to -1 so WirePin skips silently
|
||||
|
|
|
|||
Loading…
Reference in New Issue