import { useEffect, useRef } from 'react'; import { useFrame } from '@react-three/fiber'; import { usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../store/usePlayButtonStore'; import { useSceneContext } from '../../../scene/sceneContext'; type HumanCallback = { humanId: string; actionId: string; callback: () => void; }; export function useHumanEventManager() { const { humanStore } = useSceneContext(); const { getHumanById } = humanStore(); const callbacksRef = useRef([]); const isMonitoringRef = useRef(false); const { isPlaying } = usePlayButtonStore(); const { isPaused } = usePauseButtonStore(); const { isReset } = useResetButtonStore(); useEffect(() => { if (isReset) { callbacksRef.current = []; } }, [isReset]) // Add a new human to monitor const addHumanToMonitor = (humanId: string, actionId: string, callback: () => void) => { // Avoid duplicates if (!callbacksRef.current.some((entry) => entry.humanId === humanId)) { callbacksRef.current.push({ humanId, actionId, callback }); } // Start monitoring if not already running if (!isMonitoringRef.current) { isMonitoringRef.current = true; } }; // Remove a human from monitoring const removeHumanFromMonitor = (humanId: string) => { callbacksRef.current = callbacksRef.current.filter( (entry) => entry.humanId !== humanId ); // Stop monitoring if no more humans to track if (callbacksRef.current.length === 0) { isMonitoringRef.current = false; } }; // Check human states every frame useFrame(() => { if (!isMonitoringRef.current || callbacksRef.current.length === 0 || !isPlaying || isPaused) return; callbacksRef.current.forEach(({ humanId, actionId, callback }) => { const human = getHumanById(humanId); if (!human) return; const action = human.point.actions.find((action) => action.actionUuid === actionId); if (action && human.isActive === false && human.state === 'idle' && human.isPicking && human.currentLoad < action.loadCapacity) { callback(); removeHumanFromMonitor(humanId); // Remove after triggering } }); }); // Cleanup on unmount useEffect(() => { return () => { callbacksRef.current = []; isMonitoringRef.current = false; }; }, []); return { addHumanToMonitor, removeHumanFromMonitor, }; }