Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | 26x 26x 26x 26x 14x 14x 26x 14x 2x 2x 2x 14x 14x 14x 26x 2x 2x 1x 1x 1x 26x 14x 3x 11x 9x 9x 8x 3x 26x | import { useState, useEffect, useCallback } from "react";
export interface UsePinStateParams {
resetPinStates: () => void;
}
export function usePinState({ resetPinStates }: UsePinStateParams) {
// Analog pins detected in the code that need sliders (internal pin numbers 14..19)
const [analogPinsUsed, setAnalogPinsUsed] = useState<number[]>([]);
// Detected explicit pinMode(...) declarations found during parsing.
// We store modes for pins so that we can apply them when the simulation starts.
const [detectedPinModes, setDetectedPinModes] = useState<
Record<number, "INPUT" | "OUTPUT" | "INPUT_PULLUP">
>({});
// Pins that have a detected pinMode(...) declaration which conflicts with analogRead usage
const [pendingPinConflicts, setPendingPinConflicts] = useState<number[]>([]);
// Pin Monitor visibility state (persisted to localStorage)
const [pinMonitorVisible, setPinMonitorVisible] = useState<boolean>(() => {
try {
return window.localStorage.getItem("unoPinMonitorVisible") === "1";
} catch {
return false; // Hidden by default
}
});
// Listen for pin monitor visibility change events from settings dialog
useEffect(() => {
const handler = (ev: any) => {
try {
const newValue = Boolean(ev?.detail?.value);
setPinMonitorVisible(newValue);
} catch {
// ignore
}
};
document.addEventListener("pinMonitorVisibleChange", handler as EventListener);
return () =>
document.removeEventListener("pinMonitorVisibleChange", handler as EventListener);
}, []);
// Centralized helper to reset UI pin-related state. Pass { keepDetected: true }
// to preserve detected pinMode declarations and pending conflicts when desired.
const resetPinUI = useCallback(
(opts?: { keepDetected?: boolean }) => {
resetPinStates();
// Only clear detected/derived data when keepDetected is not requested.
if (!opts?.keepDetected) {
setAnalogPinsUsed([]);
setDetectedPinModes({});
setPendingPinConflicts([]);
}
},
[resetPinStates],
);
// Helper function to convert pin strings to numbers (A0-A5 → 14-19, digital → as-is)
const pinToNumber = (pinStr: string): number | null => {
if (/^\d+$/.test(pinStr)) {
return parseInt(pinStr, 10);
}
if (/^A\d+$/i.test(pinStr)) {
const analogIndex = parseInt(pinStr.slice(1), 10);
if (analogIndex >= 0 && analogIndex <= 5) {
return 14 + analogIndex; // A0->14, A1->15, ..., A5->19
}
}
return null;
};
return {
analogPinsUsed,
setAnalogPinsUsed,
detectedPinModes,
setDetectedPinModes,
pendingPinConflicts,
setPendingPinConflicts,
pinMonitorVisible,
setPinMonitorVisible,
resetPinUI,
pinToNumber,
};
}
|