import { useEffect, useRef, useState } from 'react' import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore'; import MachineAnimator from '../animator/machineAnimator'; import { useProductStore } from '../../../../../store/simulation/useProductStore'; import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler'; import { useSceneContext } from '../../../../scene/sceneContext'; import { useProductContext } from '../../../products/productContext'; function MachineInstance({ machineDetail }: { readonly machineDetail: MachineStatus }) { const [currentPhase, setCurrentPhase] = useState('idle'); let isIncrememtable = useRef(true); const idleTimeRef = useRef(0); const activeTimeRef = useRef(0); const previousTimeRef = useRef(null); const animationFrameIdRef = useRef(null); const isSpeedRef = useRef(0); const isPausedRef = useRef(false); const { isPlaying } = usePlayButtonStore(); const { machineStore } = useSceneContext(); const { selectedProductStore } = useProductContext(); const { machines, setMachineState, setMachineActive, incrementIdleTime, incrementActiveTime, resetTime } = machineStore(); const { selectedProduct } = selectedProductStore(); const { getActionByUuid } = useProductStore(); const { triggerPointActions } = useTriggerHandler(); const { speed } = useAnimationPlaySpeed(); const { isPaused } = usePauseButtonStore(); useEffect(() => { isPausedRef.current = isPaused; }, [isPaused]); useEffect(() => { isSpeedRef.current = speed; }, [speed]); const reset = () => { setCurrentPhase("idle"); setMachineState(machineDetail.modelUuid, 'idle'); setMachineActive(machineDetail.modelUuid, false); isIncrememtable.current = true; isPausedRef.current = false; resetTime(machineDetail.modelUuid) activeTimeRef.current = 0 idleTimeRef.current = 0 previousTimeRef.current = null if (animationFrameIdRef.current !== null) { cancelAnimationFrame(animationFrameIdRef.current) animationFrameIdRef.current = null } } function machineStatus(modelId: string, status: string) { // console.log(`${modelId} , ${status}`); } function animate(currentTime: number) { if (previousTimeRef.current === null) { previousTimeRef.current = currentTime; } const deltaTime = (currentTime - previousTimeRef.current) / 1000; previousTimeRef.current = currentTime; if (machineDetail.isActive) { if (!isPausedRef.current) { activeTimeRef.current += deltaTime * isSpeedRef.current; // console.log(' activeTimeRef.current: ', activeTimeRef.current); } } else { if (!isPausedRef.current) { idleTimeRef.current += deltaTime * isSpeedRef.current; // console.log('idleTimeRef.curre: ', idleTimeRef.current); } } animationFrameIdRef.current = requestAnimationFrame(animate); } useEffect(() => { if (!isPlaying) return if (!machineDetail.isActive) { const roundedActiveTime = Math.round(activeTimeRef.current); // console.log('Final Active Time:', roundedActiveTime, 'seconds'); incrementActiveTime(machineDetail.modelUuid, roundedActiveTime); activeTimeRef.current = 0; } else { const roundedIdleTime = Math.round(idleTimeRef.current); // console.log('Final Idle Time:', roundedIdleTime, 'seconds'); incrementIdleTime(machineDetail.modelUuid, roundedIdleTime); idleTimeRef.current = 0; } if (animationFrameIdRef.current === null) { animationFrameIdRef.current = requestAnimationFrame(animate); } return () => { if (animationFrameIdRef.current !== null) { cancelAnimationFrame(animationFrameIdRef.current); animationFrameIdRef.current = null; } }; }, [machineDetail, isPlaying]); useEffect(() => { if (isPlaying) { if (!machineDetail.isActive && machineDetail.state === "idle" && currentPhase == "idle" && !machineDetail.currentAction) { machineStatus(machineDetail.modelUuid, 'Machine is idle and waiting for next instruction.') } else if (!machineDetail.isActive && machineDetail.state === "idle" && currentPhase == "idle" && machineDetail.currentAction) { setCurrentPhase("processing"); setMachineState(machineDetail.modelUuid, 'running'); setMachineActive(machineDetail.modelUuid, true); machineStatus(machineDetail.modelUuid, "Machine started processing") } } }, [currentPhase, isPlaying, machines]) function handleCallBack() { if (currentPhase == "processing") { setMachineState(machineDetail.modelUuid, 'idle'); setMachineActive(machineDetail.modelUuid, false); setCurrentPhase("idle") isIncrememtable.current = true; machineStatus(machineDetail.modelUuid, "Machine has completed the processing") if (machineDetail.currentAction) { const action = getActionByUuid(selectedProduct.productId, machineDetail.currentAction.actionUuid); if (action && machineDetail.currentAction.materialId) { triggerPointActions(action, machineDetail.currentAction.materialId) } } } } return ( <> ) } export default MachineInstance