import { useMemo, useRef } from 'react'; import { isPerfLivePollWaitingForCpu, usePerfLiveSnapshot } from '../../../utils/perf/perfLiveStore'; import { usePerfLiveIncludeThreadGroups } from '../../../utils/perf/perfLivePollSettings'; import { togglePerfLiveOverlayPin, togglePipelineOverlayPin, usePerfLiveOverlayPins, usePipelineOverlayPinned, type PerfLiveOverlayPinId, } from '../../../utils/perf/perfOverlayPins'; import PerfProbeMetricCard, { PerfProbeMetricSection } from './PerfProbeMetricCard'; import PerfOverlayAppearanceControls from './PerfOverlayAppearanceControls'; import PerfOverlayModeControls from './PerfOverlayModeControls'; import PerfLivePollControls from './PerfLivePollControls'; function memoryBarPct(rssKb: number, maxKb: number): number { if (maxKb <= 0) return 0; return (rssKb / maxKb) * 100; } export default function SidebarPerfProbeMonitorTab() { const live = usePerfLiveSnapshot(); const livePins = usePerfLiveOverlayPins(); const fpsPinned = usePipelineOverlayPinned('pipeline:fps'); const analysisPinned = usePipelineOverlayPinned('pipeline:analysis'); const coverPinned = usePipelineOverlayPinned('pipeline:cover'); const cpu = live.cpu; const cpuSupported = cpu?.supported === true; const collecting = isPerfLivePollWaitingForCpu(); const includeThreadGroups = usePerfLiveIncludeThreadGroups(); const peakMemoryKbRef = useRef(1); const peakThreadCpuRef = useRef(1); const maxMemoryKb = useMemo(() => { const current = Math.max(1, ...(cpu?.memory.map(m => m.rss_kb) ?? [1])); // React Compiler refs rule: ref read imperatively outside reactive rendering; not used to compute the render output. // eslint-disable-next-line react-hooks/refs if (current > peakMemoryKbRef.current) peakMemoryKbRef.current = current; return peakMemoryKbRef.current; }, [cpu?.memory]); // React Compiler refs rule: ref read imperatively outside reactive rendering; not used to compute the render output. // eslint-disable-next-line react-hooks/refs const maxThreadCpu = useMemo(() => { const current = Math.max(1, ...(cpu?.threadCpu.map(t => t.pct) ?? [1])); if (current > peakThreadCpuRef.current) peakThreadCpuRef.current = current; return peakThreadCpuRef.current; }, [cpu?.threadCpu]); if (collecting) { return (