fix(DynamicComponent): pass componentId through to PinTracer
`PinTracer` signature is `(componentId, componentPinName) => number | null` but the local `getArduinoPin` lambda only accepted one arg and used the closure-captured `id`. When `createDefaultPinResolver` passed both args (per the typed signature), JS bound the FIRST arg (the componentId) into the lambda's single `componentPinName` parameter. `traceDetailed` then looked up a pin literally named "rgb-led-1" on component "rgb-led-1", returned null, and the resolver locked itself into 'FLOATING' state — its onChange path never subscribed and the wokwi-rgb-led element's ledRed/ledGreen/ledBlue stayed at 0 forever even as the SPICE side correctly cycled through R, G, B, Y, C, M, W via analogWrite(). Same bug latent for any multi-pin component that goes through the PinResolver path (multi-pin LEDs, RGB strips, 7-seg drivers, anything that calls `getPinResolver(<pinName>)` for several pin names). Fix: lambda now accepts both shapes — `getArduinoPin(pinName)` (legacy single-arg used by every PartSimulationRegistry handler) AND `getArduinoPin(componentId, pinName)` (PinTracer 2-arg form used by createDefaultPinResolver / createSpiceResolvedPinResolver). Picks the right componentId in either case. Verified via the rgb-led example: ledRed/ledGreen/ledBlue now cycle 0→255→0 in sync with the SPICE node voltages on pins 9/10/11. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
81837eedb9
commit
55b3dd29e5
|
|
@ -369,11 +369,29 @@ export const DynamicComponent: React.FC<DynamicComponentProps> = ({
|
|||
// Helper to find Arduino pin connected to a component pin.
|
||||
// Traces through electrically-transparent passive components so that a
|
||||
// circuit like LED-cathode → resistor → GND returns -1 (GND) instead
|
||||
// of null. Delegates to the module-level `traceDetailed` (shared with
|
||||
// getPinResolver).
|
||||
const getArduinoPin = (componentPinName: string): number | null => {
|
||||
// of null. Delegates to the module-level `traceDetailed`.
|
||||
//
|
||||
// Two call shapes are supported because this same function is passed
|
||||
// BOTH to PartSimulationRegistry handlers (which call it as
|
||||
// `getArduinoPin(componentPinName)`) AND to `createDefaultPinResolver`
|
||||
// as a `PinTracer` (which calls it as `tracePin(componentId,
|
||||
// componentPinName)`). When the second arg is present we treat the
|
||||
// first as a componentId override; otherwise we use the closure-
|
||||
// captured component id. The previous single-arg signature silently
|
||||
// matched the PinTracer 2-arg call as `(componentId, undefined)` —
|
||||
// traceDetailed then looked up a pin literally named "rgb-led-1" on
|
||||
// component "rgb-led-1", got null, and the PinResolver reported
|
||||
// FLOATING forever (the canonical "wokwi-rgb-led never lights up
|
||||
// even though SPICE is driving R/G/B" symptom).
|
||||
const getArduinoPin = (
|
||||
componentIdOrPin: string,
|
||||
maybePinName?: string,
|
||||
): number | null => {
|
||||
const state = useSimulatorStore.getState();
|
||||
return traceDetailed(state, id, componentPinName, 0).arduinoPin;
|
||||
const componentId = maybePinName !== undefined ? componentIdOrPin : id;
|
||||
const componentPinName =
|
||||
maybePinName !== undefined ? maybePinName : componentIdOrPin;
|
||||
return traceDetailed(state, componentId, componentPinName, 0).arduinoPin;
|
||||
};
|
||||
|
||||
// PinResolver factory — Phase 0 of the mixed-mode simulator project
|
||||
|
|
|
|||
Loading…
Reference in New Issue