diff --git a/app/src/modules/simulation/actions/conveyor/useConveyorActions.ts b/app/src/modules/simulation/actions/conveyor/useConveyorActions.ts index 600fae5..f2dc047 100644 --- a/app/src/modules/simulation/actions/conveyor/useConveyorActions.ts +++ b/app/src/modules/simulation/actions/conveyor/useConveyorActions.ts @@ -37,7 +37,7 @@ export function useConveyorActions() { switch (action.actionType) { case 'default': - handleDefaultAction(action); + handleDefaultAction(action, materialId); break; case 'spawn': handleSpawnAction(action); diff --git a/app/src/modules/simulation/actions/human/actionHandler/useWorkerHandler.ts b/app/src/modules/simulation/actions/human/actionHandler/useWorkerHandler.ts index efefc39..67132e7 100644 --- a/app/src/modules/simulation/actions/human/actionHandler/useWorkerHandler.ts +++ b/app/src/modules/simulation/actions/human/actionHandler/useWorkerHandler.ts @@ -8,7 +8,7 @@ export function useWorkerHandler() { const { getModelUuidByActionUuid } = productStore(); const { selectedProductStore } = useProductContext(); const { selectedProduct } = selectedProductStore(); - const { incrementHumanLoad, incrementLoadCount, addCurrentMaterial, addCurrentAction } = humanStore(); + const { incrementHumanLoad, addCurrentMaterial, addCurrentAction } = humanStore(); const workerLogStatus = (materialUuid: string, status: string) => { echo.info(`${materialUuid}, ${status}`); @@ -24,7 +24,6 @@ export function useWorkerHandler() { if (!modelUuid) return; incrementHumanLoad(modelUuid, 1); - incrementLoadCount(modelUuid, 1); addCurrentAction(modelUuid, action.actionUuid); addCurrentMaterial(modelUuid, material.materialType, material.materialId); diff --git a/app/src/modules/simulation/actions/storageUnit/actionHandler/useRetrieveHandler.ts b/app/src/modules/simulation/actions/storageUnit/actionHandler/useRetrieveHandler.ts index 79d6401..03c7138 100644 --- a/app/src/modules/simulation/actions/storageUnit/actionHandler/useRetrieveHandler.ts +++ b/app/src/modules/simulation/actions/storageUnit/actionHandler/useRetrieveHandler.ts @@ -11,7 +11,7 @@ export function useRetrieveHandler() { const { getModelUuidByActionUuid, getPointUuidByActionUuid, getEventByModelUuid, getActionByUuid } = productStore(); const { getStorageUnitById, getLastMaterial, updateCurrentLoad, removeLastMaterial } = storageUnitStore(); const { getVehicleById, incrementVehicleLoad, addCurrentMaterial } = vehicleStore(); - const { getHumanById, incrementHumanLoad, incrementLoadCount, addCurrentMaterial: addCurrentMaterialToHuman } = humanStore(); + const { getHumanById, incrementHumanLoad, addCurrentMaterial: addCurrentMaterialToHuman } = humanStore(); const { getAssetById, setCurrentAnimation } = assetStore(); const { selectedProduct } = selectedProductStore(); const { getArmBotById, addCurrentAction } = armBotStore(); @@ -316,7 +316,6 @@ export function useRetrieveHandler() { removeLastMaterial(storageUnit.modelUuid); updateCurrentLoad(storageUnit.modelUuid, -1); incrementHumanLoad(human.modelUuid, 1); - incrementLoadCount(human.modelUuid, 1); addCurrentMaterialToHuman(human.modelUuid, material.materialType, material.materialId); retrieveLogStatus(material.materialName, `is picked by ${human.modelName}`); } diff --git a/app/src/modules/simulation/human/eventManager/useHumanEventManager.ts b/app/src/modules/simulation/human/eventManager/useHumanEventManager.ts index 2d2fc11..ac5a478 100644 --- a/app/src/modules/simulation/human/eventManager/useHumanEventManager.ts +++ b/app/src/modules/simulation/human/eventManager/useHumanEventManager.ts @@ -6,16 +6,21 @@ import { useProductContext } from '../../products/productContext'; export function useHumanEventManager() { const { humanStore, productStore, assetStore } = useSceneContext(); - const { getHumanById, clearLoadCount, setCurrentPhase } = humanStore(); + const { getHumanById, setCurrentPhase } = humanStore(); const { getAssetById } = assetStore(); const { getActionByUuid } = productStore(); const { selectedProductStore } = useProductContext(); const { selectedProduct } = selectedProductStore(); - const callbacksRef = useRef void)[]>>(new Map()); - const actionQueueRef = useRef>(new Map()); - const isCooldownRef = useRef>(new Map()); - const isMonitoringRef = useRef(false); + const stateRef = useRef({ + humanStates: new Map void)[], + actionQueue: { actionType: "worker" | "assembly", actionUuid: string, actionName: string }[], + isCooldown: boolean + }>(), + callbackCounts: new Map>(), + isMonitoring: false + }); const { isPlaying } = usePlayButtonStore(); const { isPaused } = usePauseButtonStore(); @@ -23,10 +28,9 @@ export function useHumanEventManager() { useEffect(() => { if (isReset) { - callbacksRef.current.clear(); - actionQueueRef.current.clear(); - isCooldownRef.current.clear(); - isMonitoringRef.current = false; + stateRef.current.humanStates.clear(); + stateRef.current.callbackCounts.clear(); + stateRef.current.isMonitoring = false; } }, [isReset]); @@ -38,34 +42,64 @@ export function useHumanEventManager() { const actionType = action.actionType; if (actionType !== "worker" && actionType !== "assembly") return; - if (!callbacksRef.current.has(humanId)) { - callbacksRef.current.set(humanId, []); - actionQueueRef.current.set(humanId, []); + if (!stateRef.current.callbackCounts.has(humanId)) { + stateRef.current.callbackCounts.set(humanId, new Map()); } - callbacksRef.current.get(humanId)!.push(callback); - actionQueueRef.current.get(humanId)!.push({ actionType, actionUuid }); + const actionCounts = stateRef.current.callbackCounts.get(humanId)!; + if (!actionCounts.has(actionUuid)) { + actionCounts.set(actionUuid, 0); + } - isMonitoringRef.current = true; + const currentCount = actionCounts.get(actionUuid)!; + if (actionType === 'worker' && currentCount >= action.loadCount) { + return; + } + + if (!stateRef.current.humanStates.has(humanId)) { + stateRef.current.humanStates.set(humanId, { + callbacks: [], + actionQueue: [], + isCooldown: false + }); + } + + const humanState = stateRef.current.humanStates.get(humanId)!; + humanState.callbacks.push(callback); + humanState.actionQueue.push({ actionType, actionUuid, actionName: action.actionName }); + + stateRef.current.isMonitoring = true; }; const removeHumanFromMonitor = (humanId: string) => { - callbacksRef.current.delete(humanId); - actionQueueRef.current.delete(humanId); - isCooldownRef.current.delete(humanId); + // stateRef.current.humanStates.delete(humanId); - if (callbacksRef.current.size === 0) { - isMonitoringRef.current = false; + if (stateRef.current.humanStates.size === 0) { + stateRef.current.isMonitoring = false; } }; + const getCallbackCount = (humanId: string, actionUuid: string) => { + if (!stateRef.current.callbackCounts.has(humanId)) return 0; + return stateRef.current.callbackCounts.get(humanId)!.get(actionUuid) || 0; + }; + + const incrementCallbackCount = (humanId: string, actionUuid: string) => { + if (!stateRef.current.callbackCounts.has(humanId)) { + stateRef.current.callbackCounts.set(humanId, new Map()); + } + const actionCounts = stateRef.current.callbackCounts.get(humanId)!; + const currentCount = actionCounts.get(actionUuid) || 0; + actionCounts.set(actionUuid, currentCount + 1); + }; + useFrame(() => { - if (!isMonitoringRef.current || !isPlaying || isPaused) return; + if (!stateRef.current.isMonitoring || !isPlaying || isPaused) return; - callbacksRef.current.forEach((queue, humanId) => { - if (queue.length === 0 || isCooldownRef.current.get(humanId)) return; + stateRef.current.humanStates.forEach((humanState, humanId) => { + if (humanState.callbacks.length === 0 || humanState.isCooldown) return; - const actionQueue = actionQueueRef.current.get(humanId); + const actionQueue = humanState.actionQueue; if (!actionQueue || actionQueue.length === 0) return; const { actionType: expectedActionType, actionUuid } = actionQueue[0]; @@ -75,11 +109,22 @@ export function useHumanEventManager() { if (!humanAsset || !human || !action || action.actionType !== expectedActionType) return; - let conditionMet = false; + const currentCount = getCallbackCount(humanId, actionUuid); const currentAction = getActionByUuid(selectedProduct.productUuid, human.currentAction?.actionUuid || '') as HumanAction | undefined; + let conditionMet = false; + if (expectedActionType === "worker") { + if (currentAction && currentAction.actionType === 'worker' && currentCount >= currentAction.loadCount) { + humanState.callbacks.shift(); + actionQueue.shift(); + if (humanState.callbacks.length === 0) { + removeHumanFromMonitor(humanId); + } + return; + } + if (currentAction && currentAction.actionType === 'worker') { conditionMet = ( !human.isActive && @@ -88,15 +133,6 @@ export function useHumanEventManager() { human.currentLoad < currentAction.loadCapacity ); - if (human.totalLoadCount >= currentAction.loadCount && actionUuid === human.currentAction?.actionUuid) { - queue.shift(); - actionQueue.shift(); - if (queue.length === 0) { - removeHumanFromMonitor(humanId); - } - return; - } - if (conditionMet && actionUuid !== human.currentAction?.actionUuid) { setCurrentPhase(human.modelUuid, 'init'); } @@ -104,8 +140,7 @@ export function useHumanEventManager() { conditionMet = ( !human.isActive && human.state === "idle" && - humanAsset.animationState?.current === 'idle' && - human.currentLoad < action.loadCapacity + humanAsset.animationState?.current === 'idle' ); if (conditionMet && actionUuid !== human.currentAction?.actionUuid) { setCurrentPhase(human.modelUuid, 'init'); @@ -127,44 +162,34 @@ export function useHumanEventManager() { conditionMet = ( !human.isActive && human.state === "idle" && - humanAsset.animationState?.current === 'idle' && - human.currentLoad < action.loadCapacity + humanAsset.animationState?.current === 'idle' ) } - if (conditionMet) { - clearLoadCount(human.modelUuid); - } } if (conditionMet) { - const callback = queue.shift(); + const callback = humanState.callbacks.shift(); actionQueue.shift(); - if (callback) callback(); + if (callback) { + callback(); + incrementCallbackCount(humanId, actionUuid); + } - if (queue.length === 0) { + if (humanState.callbacks.length === 0) { removeHumanFromMonitor(humanId); } else { - isCooldownRef.current.set(humanId, true); + humanState.isCooldown = true; setTimeout(() => { - isCooldownRef.current.set(humanId, false); + humanState.isCooldown = false; }, 1000); } } }); - }, 0); - - useEffect(() => { - return () => { - callbacksRef.current.clear(); - actionQueueRef.current.clear(); - isCooldownRef.current.clear(); - isMonitoringRef.current = false; - }; - }, []); + }); return { addHumanToMonitor, removeHumanFromMonitor, }; -} +} \ No newline at end of file diff --git a/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts b/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts index 6a0ef6b..62582af 100644 --- a/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts +++ b/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts @@ -478,8 +478,10 @@ export function useTriggerHandler() { if (toEvent?.type === 'transfer') { // Vehicle to Transfer if (materialId && trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) { + const conveyor = getConveyorById(toEvent.modelUuid); const material = getMaterialById(materialId); - if (material) { + + if (material && conveyor) { const action = getActionByUuid(selectedProduct.productUuid, trigger.triggeredAsset.triggeredAction.actionUuid); setPreviousLocation(material.materialId, { @@ -494,23 +496,29 @@ export function useTriggerHandler() { actionUuid: trigger.triggeredAsset?.triggeredAction?.actionUuid, }); + setIsPaused(materialId, false); + setIsVisible(materialId, true); if (action && action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid && action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid ) { + setNextLocation(material.materialId, { - modelUuid: action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid, - pointUuid: action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid, + modelUuid: action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid || '', + pointUuid: action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid || '', }); - handleAction(action, materialId); - } + addConveyorToMonitor(conveyor.modelUuid, () => { + setIsPaused(materialId, false); + + handleAction(action, materialId); + }) + } } } - } else if (toEvent?.type === 'vehicle') { // Vehicle to Vehicle @@ -539,7 +547,6 @@ export function useTriggerHandler() { setNextLocation(material.materialId, null); - if (action && armBot) { if (armBot.isActive === false && armBot.state === 'idle') { @@ -1439,13 +1446,11 @@ export function useTriggerHandler() { const material = getMaterialById(materialId); if (material) { - setIsPaused(material.materialId, false); + setIsPaused(material.materialId, true); const action = getActionByUuid(selectedProduct.productUuid, trigger.triggeredAsset.triggeredAction.actionUuid); const vehicle = getVehicleById(trigger.triggeredAsset?.triggeredModel.modelUuid); - setNextLocation(material.materialId, null); - if (action) { if (vehicle) { @@ -1466,16 +1471,15 @@ export function useTriggerHandler() { actionUuid: trigger.triggeredAsset?.triggeredAction?.actionUuid, }); + setNextLocation(material.materialId, null); + // Handle current action from vehicle handleAction(action, materialId); } else { - setIsPaused(materialId, true); - addVehicleToMonitor(vehicle.modelUuid, () => { - setIsPaused(materialId, false); setIsVisible(materialId, false); setPreviousLocation(material.materialId, { @@ -1493,6 +1497,7 @@ export function useTriggerHandler() { setNextLocation(material.materialId, null); // Handle current action from vehicle + console.log('action: ', action); handleAction(action, materialId); } ) diff --git a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx index 59cd9da..5ea19f9 100644 --- a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx +++ b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx @@ -325,7 +325,6 @@ function DraggableLineSegment({ }; const onPointerMove = (e: ThreeEvent) => { - console.log('isAnyDragging: ', isAnyDragging); if (isAnyDragging !== "line" || activeTool !== 'pen') return; const intersect = new THREE.Vector3(); diff --git a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx index 3d6d274..5de64cd 100644 --- a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx +++ b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx @@ -19,7 +19,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) const { materialStore, armBotStore, conveyorStore, vehicleStore, storageUnitStore, humanStore, productStore, assetStore } = useSceneContext(); const { removeMaterial, setEndTime, setIsVisible } = materialStore(); const { getStorageUnitById } = storageUnitStore(); - const { getHumanById, addCurrentAction, addCurrentMaterial, incrementHumanLoad , incrementLoadCount } = humanStore(); + const { getHumanById, addCurrentAction, addCurrentMaterial, incrementHumanLoad } = humanStore(); const { getArmBotById } = armBotStore(); const { getConveyorById } = conveyorStore(); const { triggerPointActions } = useTriggerHandler(); @@ -302,7 +302,6 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) setIsVisible(material.materialId, false); addCurrentMaterial(humanId, material.materialType, material.materialId); incrementHumanLoad(humanId, 1); - incrementLoadCount(humanId, 1); } return; } diff --git a/app/src/store/simulation/useHumanStore.ts b/app/src/store/simulation/useHumanStore.ts index bcaf303..685970f 100644 --- a/app/src/store/simulation/useHumanStore.ts +++ b/app/src/store/simulation/useHumanStore.ts @@ -27,11 +27,6 @@ interface HumansStore { incrementHumanLoad: (modelUuid: string, incrementBy: number) => void; decrementHumanLoad: (modelUuid: string, decrementBy: number) => void; - incrementLoadCount: (modelUuid: string, incrementBy: number) => void; - decrementLoadCount: (modelUuid: string, decrementBy: number) => void; - - clearLoadCount: (modelUuid: string) => void; - addCurrentMaterial: (modelUuid: string, materialType: string, materialId: string) => void; setCurrentMaterials: (modelUuid: string, materials: { materialType: string; materialId: string }[]) => void; removeLastMaterial: (modelUuid: string) => { materialType: string; materialId: string } | undefined; @@ -65,7 +60,6 @@ export const createHumanStore = () => { isScheduled: false, idleTime: 0, activeTime: 0, - totalLoadCount: 0, currentLoad: 0, currentMaterials: [], distanceTraveled: 0 @@ -182,33 +176,6 @@ export const createHumanStore = () => { }); }, - incrementLoadCount: (modelUuid, incrementBy) => { - set((state) => { - const human = state.humans.find(h => h.modelUuid === modelUuid); - if (human) { - human.totalLoadCount += incrementBy; - } - }); - }, - - decrementLoadCount: (modelUuid, decrementBy) => { - set((state) => { - const human = state.humans.find(h => h.modelUuid === modelUuid); - if (human) { - human.totalLoadCount -= decrementBy; - } - }); - }, - - clearLoadCount: (modelUuid) => { - set((state) => { - const human = state.humans.find(h => h.modelUuid === modelUuid); - if (human) { - human.totalLoadCount = 0; - } - }); - }, - addCurrentMaterial: (modelUuid, materialType, materialId) => { set((state) => { const human = state.humans.find(h => h.modelUuid === modelUuid); diff --git a/app/src/types/simulationTypes.d.ts b/app/src/types/simulationTypes.d.ts index 5d6b21f..dcb9f49 100644 --- a/app/src/types/simulationTypes.d.ts +++ b/app/src/types/simulationTypes.d.ts @@ -252,7 +252,6 @@ interface HumanStatus extends HumanEventSchema { isScheduled: boolean; idleTime: number; activeTime: number; - totalLoadCount: number; currentLoad: number; currentMaterials: { materialType: string; materialId: string; }[]; distanceTraveled: number;