Files
Dwinzo_Demo/app/src/modules/simulation/human/eventManager/useHumanEventManager.ts

105 lines
3.3 KiB
TypeScript
Raw Normal View History

import { useEffect, useRef } from 'react';
import { useFrame } from '@react-three/fiber';
import { usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../store/usePlayButtonStore';
import { useSceneContext } from '../../../scene/sceneContext';
export function useHumanEventManager() {
const { humanStore } = useSceneContext();
const { getHumanById } = humanStore();
const callbacksRef = useRef<Map<string, (() => void)[]>>(new Map());
const isMonitoringRef = useRef(false);
const isCooldownRef = useRef<Map<string, boolean>>(new Map());
const { isPlaying } = usePlayButtonStore();
const { isPaused } = usePauseButtonStore();
const { isReset } = useResetButtonStore();
useEffect(() => {
if (isReset) {
callbacksRef.current.clear();
isCooldownRef.current.clear();
}
}, [isReset]);
2025-07-03 18:01:11 +05:30
const addHumanToMonitor = (humanId: string, callback: () => void) => {
if (!callbacksRef.current.has(humanId)) {
callbacksRef.current.set(humanId, []);
}
callbacksRef.current.get(humanId)!.push(callback);
if (!isMonitoringRef.current) {
isMonitoringRef.current = true;
}
};
const removeHumanFromMonitor = (humanId: string) => {
callbacksRef.current.delete(humanId);
isCooldownRef.current.delete(humanId);
if (callbacksRef.current.size === 0) {
isMonitoringRef.current = false;
}
};
useFrame(() => {
if (!isMonitoringRef.current || !isPlaying || isPaused) return;
callbacksRef.current.forEach((queue, humanId) => {
if (queue.length === 0 || isCooldownRef.current.get(humanId)) return;
const human = getHumanById(humanId);
const actionType = human?.point.action.actionType;
let conditionMet = false;
if (actionType === 'worker') {
conditionMet = Boolean(
human &&
human.isActive === false &&
human.state === 'idle' &&
human.isScheduled === false &&
human.currentLoad < human.point.action.loadCapacity
);
} else if (actionType === 'assembly') {
conditionMet = Boolean(
human &&
human.isActive === false &&
human.state === 'idle' &&
human.isScheduled === false
);
}
if (conditionMet) {
const callback = queue.shift();
if (callback) {
callback();
if (queue.length === 0) {
removeHumanFromMonitor(humanId);
} else {
isCooldownRef.current.set(humanId, true);
setTimeout(() => {
isCooldownRef.current.set(humanId, false);
}, 1000);
}
}
}
});
});
useEffect(() => {
return () => {
callbacksRef.current.clear();
isMonitoringRef.current = false;
isCooldownRef.current.clear();
};
}, []);
return {
addHumanToMonitor,
removeHumanFromMonitor,
};
}