72 lines
2.7 KiB
TypeScript
72 lines
2.7 KiB
TypeScript
import { AVRSimulator } from '../AVRSimulator';
|
|
import { RP2040Simulator } from '../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
|
|
*/
|
|
export interface PartSimulationLogic {
|
|
/**
|
|
* Called when a digital pin connected to this part changes state.
|
|
* Useful for output components (LEDs, buzzers, etc).
|
|
*
|
|
* @param pinName The name of the pin on the component that changed
|
|
* @param state The new digital state (true = HIGH, false = LOW)
|
|
* @param element The DOM element of the wokwi component
|
|
*/
|
|
onPinStateChange?: (pinName: string, state: boolean, element: HTMLElement) => void;
|
|
|
|
/**
|
|
* Called when the simulation starts to attach events or setup periodic tasks.
|
|
* Useful for input components (buttons, potentiometers) or complex components (servos).
|
|
*
|
|
* @param element The DOM element of the wokwi component
|
|
* @param avrSimulator The running simulator instance
|
|
* @param getArduinoPinHelper Function to find what Arduino pin is connected to a specific component pin
|
|
* @param componentId The unique ID of this component instance (used by SensorUpdateRegistry)
|
|
* @returns A cleanup function to remove event listeners when simulation stops
|
|
*/
|
|
attachEvents?: (
|
|
element: HTMLElement,
|
|
simulator: AnySimulator,
|
|
getArduinoPinHelper: (componentPinName: string) => number | null,
|
|
componentId: string,
|
|
) => () => void;
|
|
}
|
|
|
|
class PartRegistry {
|
|
private parts: Map<string, PartSimulationLogic> = new Map();
|
|
|
|
register(metadataId: string, logic: PartSimulationLogic) {
|
|
this.parts.set(metadataId, logic);
|
|
}
|
|
|
|
get(metadataId: string): PartSimulationLogic | undefined {
|
|
return this.parts.get(metadataId);
|
|
}
|
|
}
|
|
|
|
export const PartSimulationRegistry = new PartRegistry();
|
|
|
|
// Import store explicitly inside a function to avoid circular dependencies if any,
|
|
// but since we just need it at runtime, we can import it at the top or dynamically.
|
|
import { useSimulatorStore } from '../../store/useSimulatorStore';
|
|
|
|
PartSimulationRegistry.register('raspberry-pi-3', {
|
|
onPinStateChange: (pinName: string, state: boolean, _element: HTMLElement) => {
|
|
// When Arduino changes a pin connected to Raspberry Pi, forward to backend
|
|
useSimulatorStore.getState().sendRemotePinEvent(pinName, state ? 1 : 0);
|
|
},
|
|
});
|