feat: implement conveyor and arm bot event managers for monitoring state changes

This commit is contained in:
Jerald-Golden-B 2025-05-20 13:01:43 +05:30
parent 068af3f936
commit 6da65eba7b
5 changed files with 212 additions and 51 deletions

View File

@ -0,0 +1,65 @@
import { useEffect, useRef } from 'react';
import { useFrame } from '@react-three/fiber';
import { useConveyorStore } from '../../../../store/simulation/useConveyorStore';
type ConveyorCallback = {
conveyorId: string;
callback: () => void;
};
export function useConveyorEventManager() {
const { getConveyorById } = useConveyorStore();
const callbacksRef = useRef<ConveyorCallback[]>([]);
const isMonitoringRef = useRef(false);
// Add a new conveyor to monitor
const addConveyorToMonitor = (conveyorId: string, callback: () => void) => {
// Avoid duplicates
if (!callbacksRef.current.some((entry) => entry.conveyorId === conveyorId)) {
callbacksRef.current.push({ conveyorId, callback });
}
// Start monitoring if not already running
if (!isMonitoringRef.current) {
isMonitoringRef.current = true;
}
};
// Remove a conveyor from monitoring
const removeConveyorFromMonitor = (conveyorId: string) => {
callbacksRef.current = callbacksRef.current.filter(
(entry) => entry.conveyorId !== conveyorId
);
// Stop monitoring if no more conveyors to track
if (callbacksRef.current.length === 0) {
isMonitoringRef.current = false;
}
};
// Check conveyor states every frame
useFrame(() => {
if (!isMonitoringRef.current || callbacksRef.current.length === 0) return;
callbacksRef.current.forEach(({ conveyorId, callback }) => {
const conveyor = getConveyorById(conveyorId);
if (conveyor?.isPaused === false) {
callback();
removeConveyorFromMonitor(conveyorId); // Remove after triggering
}
});
});
// Cleanup on unmount
useEffect(() => {
return () => {
callbacksRef.current = [];
isMonitoringRef.current = false;
};
}, []);
return {
addConveyorToMonitor,
removeConveyorFromMonitor,
};
}

View File

@ -2,43 +2,37 @@ import React, { useEffect } from 'react'
import { useMaterialStore } from '../../../../../store/simulation/useMaterialStore';
import { useConveyorStore } from '../../../../../store/simulation/useConveyorStore';
import { useResetButtonStore } from '../../../../../store/usePlayButtonStore';
import { findConveyorInSequences } from '../../../simulator/functions/findConveyorInSequences';
import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore';
import { useProductStore } from '../../../../../store/simulation/useProductStore';
function ConveyorInstance({ conveyor }: { conveyor: ConveyorStatus }) {
const { getProductById } = useProductStore();
const { selectedProduct } = useSelectedProduct();
const { materials, getMaterialsByCurrentModelUuid } = useMaterialStore();
const { isReset } = useResetButtonStore();
const { setConveyorPaused } = useConveyorStore();
useEffect(() => {
const product = getProductById(selectedProduct.productId);
if (!product) return;
const sequenceInfo = findConveyorInSequences(product, conveyor.modelUuid);
if (!sequenceInfo) return;
const { currentSubSequence } = sequenceInfo;
const conveyorMaterials = getMaterialsByCurrentModelUuid(conveyor.modelUuid);
if (conveyorMaterials && conveyorMaterials?.length > 0) {
if (conveyorMaterials && conveyorMaterials.length > 0) {
const shouldPauseSubsequence = currentSubSequence.some(subConveyor => {
if (subConveyor.type !== 'transfer') return false;
const subMaterials = getMaterialsByCurrentModelUuid(subConveyor.modelUuid);
return subMaterials?.some(m => m.isPaused) ?? false;
});
const hasPausedMaterials = conveyorMaterials.some(material => material.isPaused);
currentSubSequence.forEach(subConveyor => {
if (subConveyor.type === 'transfer') {
setConveyorPaused(subConveyor.modelUuid, shouldPauseSubsequence);
}
});
if (hasPausedMaterials) {
setConveyorPaused(conveyor.modelUuid, true);
} else {
setConveyorPaused(conveyor.modelUuid, false);
}
}else{
setConveyorPaused(conveyor.modelUuid, false);
}
}, [materials, conveyor.modelUuid, getMaterialsByCurrentModelUuid, setConveyorPaused, isReset, selectedProduct.productId, getProductById]);
return null;
}
}, [materials, conveyor.modelUuid, getMaterialsByCurrentModelUuid, setConveyorPaused, isReset]);
export default React.memo(ConveyorInstance);
useEffect(() => {
// console.log('conveyor: ', conveyor);
}, [conveyor])
return (
<>
</>
)
};
export default ConveyorInstance

View File

@ -0,0 +1,65 @@
import { useEffect, useRef } from 'react';
import { useFrame } from '@react-three/fiber';
import { useArmBotStore } from '../../../../store/simulation/useArmBotStore';
type ArmBotCallback = {
armBotId: string;
callback: () => void;
};
export function useArmBotEventManager() {
const { getArmBotById } = useArmBotStore();
const callbacksRef = useRef<ArmBotCallback[]>([]);
const isMonitoringRef = useRef(false);
// Add a new armbot to monitor
const addArmBotToMonitor = (armBotId: string, callback: () => void) => {
// Avoid duplicates
if (!callbacksRef.current.some((entry) => entry.armBotId === armBotId)) {
callbacksRef.current.push({ armBotId, callback });
}
// Start monitoring if not already running
if (!isMonitoringRef.current) {
isMonitoringRef.current = true;
}
};
// Remove an armbot from monitoring (e.g., when unmounted)
const removeArmBotFromMonitor = (armBotId: string) => {
callbacksRef.current = callbacksRef.current.filter(
(entry) => entry.armBotId !== armBotId
);
// Stop monitoring if no more armbots to track
if (callbacksRef.current.length === 0) {
isMonitoringRef.current = false;
}
};
// Check armbot states every frame
useFrame(() => {
if (!isMonitoringRef.current || callbacksRef.current.length === 0) return;
callbacksRef.current.forEach(({ armBotId, callback }) => {
const armBot = getArmBotById(armBotId);
if (armBot?.isActive === false && armBot?.state === 'idle') {
callback();
removeArmBotFromMonitor(armBotId); // Remove after triggering
}
});
});
// Cleanup on unmount (optional, since useFrame auto-cleans)
useEffect(() => {
return () => {
callbacksRef.current = [];
isMonitoringRef.current = false;
};
}, []);
return {
addArmBotToMonitor,
removeArmBotFromMonitor,
};
}

View File

@ -27,15 +27,14 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
const pauseTimeRef = useRef<number | null>(null);
const isPausedRef = useRef<boolean>(false);
const isSpeedRef = useRef<any>(null);
const isIdleRef = useRef<boolean>(false);
let startTime: number;
const { armBots, setArmBotActive, setArmBotState, removeCurrentAction, incrementActiveTime, incrementIdleTime } = useArmBotStore();
const { setArmBotActive, setArmBotState, removeCurrentAction, incrementActiveTime, incrementIdleTime } = useArmBotStore();
const { decrementVehicleLoad, removeLastMaterial } = useVehicleStore();
const { removeLastMaterial: removeLastStorageMaterial, updateCurrentLoad } = useStorageUnitStore();
const { setIsVisible, setIsPaused, getMaterialById } = useMaterialStore();
const { selectedProduct } = useSelectedProduct();
const { getActionByUuid, getEventByActionUuid, getEventByModelUuid, getProductById } = useProductStore();
const { getActionByUuid, getEventByActionUuid, getEventByModelUuid } = useProductStore();
const { triggerPointActions } = useTriggerHandler();
const { isPlaying } = usePlayButtonStore();
const { isReset } = useResetButtonStore();
@ -47,7 +46,6 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
const animationFrameIdRef = useRef<number | null>(null);
const previousTimeRef = useRef<number | null>(null);
const checkActiveRoboticArms = useCheckActiveRoboticArmsInSubsequence();
const lastRemoved = useRef<{ type: string, materialId: string } | null>(null);
@ -95,15 +93,6 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
if (!model) return;
if (model.type === 'transfer') {
setIsVisible(armBot.currentAction.materialId || '', true);
const product = getProductById(selectedProduct.productId);
if (product) {
const result = checkActiveRoboticArms(product, armBot.modelUuid);
// console.log('result: ', result);
// if (result?.hasActiveRoboticArm) {
// lastRemoved.current = null;
// }
}
} else if (model.type === 'machine') {
//
} else if (model.type === 'vehicle') {
@ -116,6 +105,14 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
triggerPointActions(action, armBot.currentAction.materialId)
removeCurrentAction(armBot.modelUuid)
}
if (lastRemoved.current) {
if (lastRemoved.current.type === 'transfer') {
setIsPaused(lastRemoved.current.materialId, true)
} else {
setIsPaused(lastRemoved.current.materialId, false)
}
}
}
}
@ -386,13 +383,6 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
setCurrentPhase("rest");
setPath([])
if (lastRemoved.current) {
if (lastRemoved.current.type === 'transfer') {
setIsPaused(lastRemoved.current.materialId, true)
} else {
setIsPaused(lastRemoved.current.materialId, false)
}
}
}
}

View File

@ -7,12 +7,18 @@ import { useArmBotStore } from '../../../../store/simulation/useArmBotStore';
import { useVehicleStore } from '../../../../store/simulation/useVehicleStore';
import { useMachineStore } from '../../../../store/simulation/useMachineStore';
import { useStorageUnitStore } from '../../../../store/simulation/useStorageUnitStore';
import { useArmBotEventManager } from '../../roboticArm/eventManager/useArmBotEventManager';
import { useConveyorStore } from '../../../../store/simulation/useConveyorStore';
import { useConveyorEventManager } from '../../conveyor/eventManager/useConveyorEventManager';
export function useTriggerHandler() {
const { handleAction } = useActionHandler();
const { selectedProduct } = useSelectedProduct();
const { getEventByTriggerUuid, getEventByModelUuid, getActionByUuid, getModelUuidByActionUuid } = useProductStore();
const { getArmBotById } = useArmBotStore();
const { getConveyorById } = useConveyorStore();
const { addArmBotToMonitor } = useArmBotEventManager();
const { addConveyorToMonitor } = useConveyorEventManager();
const { getVehicleById } = useVehicleStore();
const { getMachineById } = useMachineStore();
const { getStorageUnitById } = useStorageUnitStore();
@ -144,6 +150,10 @@ export function useTriggerHandler() {
} else {
// Event Manager Needed
setIsPaused(materialId, true);
addArmBotToMonitor(armBot.modelUuid,
() => handleAction(action, materialId)
);
}
}
@ -320,12 +330,42 @@ export function useTriggerHandler() {
if (armBot.isActive === false && armBot.state === 'idle') {
// Handle current action from arm bot
handleAction(action, materialId);
const model = getEventByModelUuid(selectedProduct.productId, action.triggers[0].triggeredAsset?.triggeredModel.modelUuid || '');
if (model?.type === 'transfer') {
const conveyor = getConveyorById(action.triggers[0].triggeredAsset?.triggeredModel.modelUuid || '');
if (conveyor) {
addConveyorToMonitor(conveyor.modelUuid,
() => {
handleAction(action, materialId)
}
)
// handleAction(action, materialId)
}
} else {
handleAction(action, materialId)
}
} else {
// Event Manager Needed
addArmBotToMonitor(armBot.modelUuid,
() => {
const model = getEventByModelUuid(selectedProduct.productId, action.triggers[0].triggeredAsset?.triggeredModel.modelUuid || '');
if (model?.type === 'transfer') {
const conveyor = getConveyorById(action.triggers[0].triggeredAsset?.triggeredModel.modelUuid || '');
if (conveyor) {
addConveyorToMonitor(conveyor.modelUuid,
() => {
handleAction(action, materialId)
}
)
// handleAction(action, materialId)
}
} else {
handleAction(action, materialId)
}
}
);
}
}
}
@ -342,8 +382,6 @@ export function useTriggerHandler() {
const material = getMaterialById(materialId);
if (material) {
// setIsPaused(material.materialId, false);
setPreviousLocation(material.materialId, {
modelUuid: material.current.modelUuid,
pointUuid: material.current.pointUuid,
@ -410,6 +448,15 @@ export function useTriggerHandler() {
}
}
} else if (model?.type === 'transfer') {
const conveyor = getConveyorById(action.triggers[0].triggeredAsset?.triggeredModel.modelUuid);
if (conveyor) {
setNextLocation(material.materialId, {
modelUuid: action.triggers[0].triggeredAsset?.triggeredModel.modelUuid,
pointUuid: action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid,
})
handleAction(action, material.materialId);
}
} else {
setNextLocation(material.materialId, {
modelUuid: action.triggers[0].triggeredAsset?.triggeredModel.modelUuid,