From 8ba2bae810cd6111ebad4167603d1f11b5813cea Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Mon, 5 May 2025 11:24:00 +0530 Subject: [PATCH] Refactor simulation action handlers: consolidate action handling, enhance spawn logic, and improve type definitions for actions. --- .../collaboration/functions/setCameraView.ts | 2 - ...awnActionHandler.ts => useSpawnHandler.ts} | 33 ++--- .../actions/conveyor/useConveyorActions.ts | 94 +++++++++------ .../actions/machine/useMachineActions.ts | 48 +++++--- .../roboticArm/useRoboticArmActions.ts | 48 ++++---- .../storageUnit/useStorageUnitActions.ts | 45 ++++--- .../simulation/actions/useActionHandler.ts | 89 +++++++++++--- .../actions/vehicle/useVehicleActions.ts | 53 ++++---- .../simulation/simulator/simulator.tsx | 113 ++---------------- .../triggerHandler/useTriggerHandler.ts | 13 ++ app/src/store/simulation/useProductStore.ts | 25 ++++ app/src/types/simulationTypes.d.ts | 54 ++++++++- 12 files changed, 366 insertions(+), 251 deletions(-) rename app/src/modules/simulation/actions/conveyor/actionHandler/{spawnActionHandler.ts => useSpawnHandler.ts} (82%) create mode 100644 app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts diff --git a/app/src/modules/collaboration/functions/setCameraView.ts b/app/src/modules/collaboration/functions/setCameraView.ts index 8bae59b..456f622 100644 --- a/app/src/modules/collaboration/functions/setCameraView.ts +++ b/app/src/modules/collaboration/functions/setCameraView.ts @@ -28,6 +28,4 @@ export default async function setCameraView({ controls?.setLookAt(...newPosition.toArray(), newPosition.x, 0, newPosition.z, true); } - // Optionally you can log - console.log(`Camera view updated by ${username ?? 'unknown user'}`); } diff --git a/app/src/modules/simulation/actions/conveyor/actionHandler/spawnActionHandler.ts b/app/src/modules/simulation/actions/conveyor/actionHandler/useSpawnHandler.ts similarity index 82% rename from app/src/modules/simulation/actions/conveyor/actionHandler/spawnActionHandler.ts rename to app/src/modules/simulation/actions/conveyor/actionHandler/useSpawnHandler.ts index c28f1d0..776b539 100644 --- a/app/src/modules/simulation/actions/conveyor/actionHandler/spawnActionHandler.ts +++ b/app/src/modules/simulation/actions/conveyor/actionHandler/useSpawnHandler.ts @@ -7,7 +7,7 @@ import { useSelectedProduct } from "../../../../../store/simulation/useSimulatio export function useSpawnHandler() { const { addMaterial } = useMaterialStore(); - const { getModelUuidByActionUuid } = useProductStore(); + const { getModelUuidByActionUuid, getPointUuidByActionUuid } = useProductStore(); const { selectedProduct } = useSelectedProduct(); const lastSpawnTime = useRef(null); const startTime = useRef(null); @@ -16,7 +16,7 @@ export function useSpawnHandler() { material: string; intervalMs: number; totalCount: number; - point: ConveyorPointSchema; + action: ConveyorAction; } | null>(null); const clearCurrentSpawn = useCallback(() => { @@ -27,12 +27,13 @@ export function useSpawnHandler() { }, []); const spawnLogStatus = (materialUuid: string, status: string) => { - // console.log(`${materialUuid}, ${status}`); + console.log(`${materialUuid}, ${status}`); } - const createNewMaterial = useCallback((materialType: string, point: ConveyorPointSchema) => { - const modelUuid = getModelUuidByActionUuid(selectedProduct.productId, point.action.actionUuid); - if (!modelUuid || !point.uuid) return; + const createNewMaterial = useCallback((materialType: string, action: ConveyorAction) => { + const modelUuid = getModelUuidByActionUuid(selectedProduct.productId, action.actionUuid); + const pointUuid = getPointUuidByActionUuid(selectedProduct.productId, action.actionUuid); + if (!modelUuid || !pointUuid) return; const newMaterial: MaterialSchema = { materialId: THREE.MathUtils.generateUUID(), @@ -43,8 +44,8 @@ export function useSpawnHandler() { isRendered: true, current: { modelUuid: modelUuid, - pointUuid: point.uuid, - actionUuid: point.action?.actionUuid || '' + pointUuid: pointUuid, + actionUuid: action?.actionUuid || '' }, weight: 1, cost: 1 @@ -58,14 +59,14 @@ export function useSpawnHandler() { if (!spawnParams.current || !startTime.current) return; const currentTime = performance.now(); - const { material, intervalMs, totalCount, point } = spawnParams.current; + const { material, intervalMs, totalCount, action } = spawnParams.current; const isFirstSpawn = lastSpawnTime.current === null; const elapsed = currentTime - startTime.current; // First spawn if (isFirstSpawn) { if (elapsed >= intervalMs) { - const createdMaterial = createNewMaterial(material, point); + const createdMaterial = createNewMaterial(material, action); if (createdMaterial) { spawnLogStatus(createdMaterial.materialId, `[${elapsed.toFixed(2)}ms] Spawned ${material} (1/${totalCount})`); } @@ -84,9 +85,9 @@ export function useSpawnHandler() { const timeSinceLast = currentTime - lastSpawnTime.current; if (timeSinceLast >= intervalMs) { const count = spawnCountRef.current + 1; - const createdMaterial = createNewMaterial(material, point); + const createdMaterial = createNewMaterial(material, action); if (createdMaterial) { - spawnLogStatus(createdMaterial.materialId, `[${elapsed.toFixed(2)}ms] Spawned ${material} (1/${totalCount})`); + spawnLogStatus(createdMaterial.materialId, `[${elapsed.toFixed(2)}ms] Spawned ${material} (${count}/${totalCount})`); } lastSpawnTime.current = currentTime; spawnCountRef.current = count; @@ -98,10 +99,10 @@ export function useSpawnHandler() { } }); - const handleSpawn = useCallback((point: ConveyorPointSchema) => { - if (!point.action || point.action.actionType !== 'spawn') return; + const handleSpawn = useCallback((action: ConveyorAction) => { + if (!action || action.actionType !== 'spawn') return; - const { material, spawnInterval = 0, spawnCount = 1 } = point.action; + const { material, spawnInterval = 0, spawnCount = 1 } = action; const intervalMs = spawnInterval * 1000; clearCurrentSpawn(); @@ -110,7 +111,7 @@ export function useSpawnHandler() { material, intervalMs, totalCount: spawnCount, - point: point + action: action }; startTime.current = performance.now(); diff --git a/app/src/modules/simulation/actions/conveyor/useConveyorActions.ts b/app/src/modules/simulation/actions/conveyor/useConveyorActions.ts index e10e115..a61e3c4 100644 --- a/app/src/modules/simulation/actions/conveyor/useConveyorActions.ts +++ b/app/src/modules/simulation/actions/conveyor/useConveyorActions.ts @@ -1,40 +1,66 @@ -import { useEffect } from "react"; -import { useSpawnHandler } from "./actionHandler/spawnActionHandler"; +import { useEffect, useCallback, useRef } from "react"; +import { useSpawnHandler } from "./actionHandler/useSpawnHandler"; -// Conveyor Actions -export function useConveyorActions(point: ConveyorPointSchema) { - const { handleSpawn } = useSpawnHandler(); +export function useConveyorActions() { + const { handleSpawn, clearCurrentSpawn } = useSpawnHandler(); + + const handleDefaultAction = useCallback((action: ConveyorAction) => { + console.log(`Default conveyor action ${action.actionUuid}`); + }, []); + + const handleSpawnAction = useCallback((action: ConveyorAction) => { + handleSpawn(action); + }, [handleSpawn]); + + const handleSwapAction = useCallback((action: ConveyorAction) => { + console.log(`Swapping to material ${action.material}`); + }, []); + + const handleDelayAction = useCallback((action: ConveyorAction) => { + const delayMs = (action.delay || 0) * 1000; + console.log(`Delaying for ${delayMs}ms`); + }, []); + + const handleDespawnAction = useCallback((action: ConveyorAction) => { + console.log(`Despawning material`); + }, []); + + const handleConveyorAction = useCallback((action: ConveyorAction) => { + if (!action) return; + + switch (action.actionType) { + case 'default': + handleDefaultAction(action); + break; + case 'spawn': + handleSpawnAction(action); + break; + case 'swap': + handleSwapAction(action); + break; + case 'delay': + handleDelayAction(action); + break; + case 'despawn': + handleDespawnAction(action); + break; + default: + console.warn(`Unknown conveyor action type: ${action.actionType}`); + } + }, [handleDefaultAction, handleSpawnAction, handleSwapAction, handleDelayAction, handleDespawnAction]); + + const cleanup = useCallback(() => { + clearCurrentSpawn(); + }, [clearCurrentSpawn]); useEffect(() => { - if (!point.action) return; - - const { actionType, material, delay, spawnInterval, spawnCount } = point.action; - - const handleAction = () => { - switch (actionType) { - case 'default': - console.log(`Default conveyor action at point ${point.uuid}`); - break; - case 'spawn': - console.log(`Spawning material ${material} at point ${point.uuid}`); - handleSpawn(point); - break; - case 'swap': - console.log(`Swapping to material ${material} at point ${point.uuid}`); - break; - case 'delay': - console.log(`Delaying for ${delay}ms at point ${point.uuid}`); - break; - case 'despawn': - console.log(`Despawning material at point ${point.uuid}`); - break; - } - }; - - handleAction(); - return () => { - // Cleanup if needed + cleanup(); }; - }, [point]); + }, [cleanup]); + + return { + handleConveyorAction, + cleanup + }; } \ No newline at end of file diff --git a/app/src/modules/simulation/actions/machine/useMachineActions.ts b/app/src/modules/simulation/actions/machine/useMachineActions.ts index 0ac9865..38e8ce3 100644 --- a/app/src/modules/simulation/actions/machine/useMachineActions.ts +++ b/app/src/modules/simulation/actions/machine/useMachineActions.ts @@ -1,23 +1,35 @@ -import { useEffect } from 'react'; +import { useEffect, useCallback, useRef, useState } from 'react'; + +export function useMachineActions() { + + const handleProcessAction = useCallback((action: MachineAction) => { + if (!action || action.actionType !== 'process') return; + console.log(`Machine processing for ${action.processTime}ms`); + }, []); + + const handleMachineAction = useCallback((action: MachineAction) => { + if (!action) return; + + switch (action.actionType) { + case 'process': + handleProcessAction(action); + break; + default: + console.warn(`Unknown machine action type: ${action.actionType}`); + } + }, [handleProcessAction]); + + const cleanup = useCallback(() => { + }, []); -// Machine Actions -export function useMachineActions(point: MachinePointSchema) { useEffect(() => { - if (!point.action) return; - - const { actionType, processTime, swapMaterial } = point.action; - - const handleAction = () => { - if (actionType === 'process') { - console.log(`Machine processing for ${processTime}ms at point ${point.uuid}`); - if (swapMaterial) { - console.log(`Swapping material to ${swapMaterial}`); - } - } - }; - return () => { - // Cleanup if needed + cleanup(); }; - }, [point]); + }, [cleanup]); + + return { + handleMachineAction, + cleanup, + }; } \ No newline at end of file diff --git a/app/src/modules/simulation/actions/roboticArm/useRoboticArmActions.ts b/app/src/modules/simulation/actions/roboticArm/useRoboticArmActions.ts index 50a6196..37990db 100644 --- a/app/src/modules/simulation/actions/roboticArm/useRoboticArmActions.ts +++ b/app/src/modules/simulation/actions/roboticArm/useRoboticArmActions.ts @@ -1,26 +1,32 @@ -import { useEffect } from 'react'; +import { useEffect, useCallback } from 'react'; + +export function useRoboticArmActions() { + + const handlePickAndPlace = useCallback((action: RoboticArmAction) => { + console.log(`Robotic arm pick and place`); + }, []); + + const handleRoboticArmAction = useCallback((action: RoboticArmAction) => { + switch (action.actionType) { + case 'pickAndPlace': + handlePickAndPlace(action); + break; + default: + console.warn(`Unknown robotic arm action type: ${action.actionType}`); + } + }, [handlePickAndPlace]); + + const cleanup = useCallback(() => { + }, []); -// Robotic Arm Actions -export function useRoboticArmActions(point: RoboticArmPointSchema) { useEffect(() => { - point.actions.forEach(action => { - const { actionType, process } = action; - - const handleAction = () => { - if (actionType === 'pickAndPlace') { - console.log(`Robotic arm pick and place at point ${point.uuid}`); - if (process.startPoint) { - console.log(`Start point: ${process.startPoint}`); - } - if (process.endPoint) { - console.log(`End point: ${process.endPoint}`); - } - } - }; - }); - return () => { - // Cleanup if needed + cleanup(); }; - }, [point]); + }, [cleanup]); + + return { + handleRoboticArmAction, + cleanup + }; } \ No newline at end of file diff --git a/app/src/modules/simulation/actions/storageUnit/useStorageUnitActions.ts b/app/src/modules/simulation/actions/storageUnit/useStorageUnitActions.ts index 6ffa8ad..bc1ab94 100644 --- a/app/src/modules/simulation/actions/storageUnit/useStorageUnitActions.ts +++ b/app/src/modules/simulation/actions/storageUnit/useStorageUnitActions.ts @@ -1,22 +1,33 @@ -import { useEffect } from 'react'; +import { useEffect, useCallback, useRef, useState } from 'react'; + +export function useStorageActions() { + const handleStoreAction = useCallback((action: StorageAction) => { + if (!action || action.actionType !== 'store') return; + }, []); + + const handleStorageAction = useCallback((action: StorageAction) => { + if (!action) return; + + switch (action.actionType) { + case 'store': + handleStoreAction(action); + break; + default: + console.warn(`Unknown storage action type: ${action.actionType}`); + } + }, [handleStoreAction]); + + const cleanup = useCallback(() => { + }, []); -// Storage Actions -export function useStorageActions(point: StoragePointSchema) { useEffect(() => { - if (!point.action) return; - - const { actionType, materials, storageCapacity } = point.action; - - const handleAction = () => { - if (actionType === 'store') { - console.log(`Storage action at point ${point.uuid}`); - console.log(`Materials: ${materials.map(m => m.materialName).join(', ')}`); - console.log(`Capacity: ${storageCapacity}`); - } - }; - return () => { - // Cleanup if needed + cleanup(); }; - }, [point]); + }, [cleanup]); + + return { + handleStorageAction, + cleanup + }; } \ No newline at end of file diff --git a/app/src/modules/simulation/actions/useActionHandler.ts b/app/src/modules/simulation/actions/useActionHandler.ts index 0975e83..dbffd69 100644 --- a/app/src/modules/simulation/actions/useActionHandler.ts +++ b/app/src/modules/simulation/actions/useActionHandler.ts @@ -3,23 +3,76 @@ import { useMachineActions } from "./machine/useMachineActions"; import { useRoboticArmActions } from "./roboticArm/useRoboticArmActions"; import { useStorageActions } from "./storageUnit/useStorageUnitActions"; import { useVehicleActions } from "./vehicle/useVehicleActions"; +import { useCallback, useEffect } from "react"; -// Master hook that selects the appropriate action handler -export function useActionHandler(point: PointsScheme) { - if ('actions' in point) { - // Robotic Arm - useRoboticArmActions(point); - } else if (point.action.actionType === 'travel') { - // Vehicle - useVehicleActions(point as VehiclePointSchema); - } else if (point.action.actionType === 'process') { - // Machine - useMachineActions(point as MachinePointSchema); - } else if (point.action.actionType === 'store') { - // Storage - useStorageActions(point as StoragePointSchema); - } else { - // Conveyor - useConveyorActions(point as ConveyorPointSchema); - } +export function useActionHandler() { + // Initialize all action handlers + const { handleConveyorAction, cleanup: cleanupConveyor } = useConveyorActions(); + const { handleVehicleAction, cleanup: cleanupVehicle } = useVehicleActions(); + const { handleRoboticArmAction, cleanup: cleanupRoboticArm } = useRoboticArmActions(); + const { handleMachineAction, cleanup: cleanupMachine } = useMachineActions(); + const { handleStorageAction, cleanup: cleanupStorage } = useStorageActions(); + + // Main handler function + const handleAction = useCallback((action: Action) => { + if (!action) return; + + try { + switch (action.actionType) { + case 'default': case 'spawn': case 'swap': case 'delay': case 'despawn': + handleConveyorAction(action as ConveyorAction); + break; + case 'travel': + handleVehicleAction(action as VehicleAction); + break; + case 'pickAndPlace': + handleRoboticArmAction(action as RoboticArmAction); + break; + case 'process': + handleMachineAction(action as MachineAction); + break; + case 'store': + handleStorageAction(action as StorageAction); + break; + default: + console.warn(`Unknown action type: ${(action as Action).actionType}`); + } + } catch (error) { + console.error('Error handling action:', error); + // Consider adding error recovery or notification here + } + }, [ + handleConveyorAction, + handleVehicleAction, + handleRoboticArmAction, + handleMachineAction, + handleStorageAction + ]); + + // Cleanup all actions + const cleanup = useCallback(() => { + cleanupConveyor(); + cleanupVehicle(); + cleanupRoboticArm(); + cleanupMachine(); + cleanupStorage(); + }, [ + cleanupConveyor, + cleanupVehicle, + cleanupRoboticArm, + cleanupMachine, + cleanupStorage + ]); + + // Auto cleanup on unmount + useEffect(() => { + return () => { + cleanup(); + }; + }, [cleanup]); + + return { + handleAction, + cleanup + }; } \ No newline at end of file diff --git a/app/src/modules/simulation/actions/vehicle/useVehicleActions.ts b/app/src/modules/simulation/actions/vehicle/useVehicleActions.ts index 7a6ce4d..313fb5d 100644 --- a/app/src/modules/simulation/actions/vehicle/useVehicleActions.ts +++ b/app/src/modules/simulation/actions/vehicle/useVehicleActions.ts @@ -1,26 +1,37 @@ -import { useEffect } from 'react'; +import { useEffect, useCallback } from 'react'; + +export function useVehicleActions() { + + const handleTravelAction = useCallback((action: VehicleAction) => { + if (!action || action.actionType !== 'travel') return; + + console.log(`Vehicle travel action ${action.actionUuid}`); + + }, []); + + const handleVehicleAction = useCallback((action: VehicleAction) => { + if (!action) return; + + switch (action.actionType) { + case 'travel': + handleTravelAction(action); + break; + default: + console.warn(`Unknown vehicle action type: ${action.actionType}`); + } + }, [handleTravelAction]); + + const cleanup = useCallback(() => { + }, []); -// Vehicle Actions -export function useVehicleActions(point: VehiclePointSchema) { useEffect(() => { - if (!point.action) return; - - const { actionType, unLoadDuration, loadCapacity, steeringAngle } = point.action; - - const handleAction = () => { - if (actionType === 'travel') { - console.log(`Vehicle travel action at point ${point.uuid}`); - if (point.action.pickUpPoint) { - console.log(`Pick up at: ${JSON.stringify(point.action.pickUpPoint)}`); - } - if (point.action.unLoadPoint) { - console.log(`Unload at: ${JSON.stringify(point.action.unLoadPoint)}`); - } - } - }; - return () => { - // Cleanup if needed + cleanup(); }; - }, [point]); + }, [cleanup]); + + return { + handleVehicleAction, + cleanup + }; } \ No newline at end of file diff --git a/app/src/modules/simulation/simulator/simulator.tsx b/app/src/modules/simulation/simulator/simulator.tsx index 66a1dc3..05b6569 100644 --- a/app/src/modules/simulation/simulator/simulator.tsx +++ b/app/src/modules/simulation/simulator/simulator.tsx @@ -1,114 +1,21 @@ +import { useEffect } from 'react'; import { useProductStore } from '../../../store/simulation/useProductStore'; import { useActionHandler } from '../actions/useActionHandler'; function Simulator() { const { products } = useProductStore(); + const { handleAction } = useActionHandler(); - const executionOrder = determineExecutionOrder(products); - - executionOrder.forEach(point => { - useActionHandler(point); - }); - - function determineExecutionSequences(products: productsSchema): PointsScheme[][] { - // Create maps for all points - const pointMap = new Map(); - const allPoints: PointsScheme[] = []; - - // First pass: collect all points - products.forEach(product => { - product.eventDatas.forEach(event => { - if (event.type === 'transfer') { - event.points.forEach(point => { - pointMap.set(point.uuid, point); - allPoints.push(point); - }); - } else if (event.type === 'vehicle' || - event.type === 'machine' || - event.type === 'storageUnit' || - event.type === 'roboticArm') { - pointMap.set(event.point.uuid, event.point); - allPoints.push(event.point); - } - }); - }); - - // Build complete dependency graph - const dependencyGraph = new Map(); - const reverseDependencyGraph = new Map(); - const triggeredPoints = new Set(); - - allPoints.forEach(point => { - const triggers = extractTriggersFromPoint(point); - const dependencies: string[] = []; - - triggers.forEach(trigger => { - const targetUuid = trigger.triggeredAsset?.triggeredPoint?.pointUuid; - if (targetUuid && pointMap.has(targetUuid)) { - dependencies.push(targetUuid); - triggeredPoints.add(targetUuid); - - if (!reverseDependencyGraph.has(targetUuid)) { - reverseDependencyGraph.set(targetUuid, []); - } - reverseDependencyGraph.get(targetUuid)!.push(point.uuid); - } - }); - - dependencyGraph.set(point.uuid, dependencies); - }); - - // Identify independent root points (points that trigger others but aren't triggered themselves) - const rootPoints = allPoints.filter(point => { - const hasOutgoingTriggers = extractTriggersFromPoint(point).some( - t => t.triggeredAsset?.triggeredPoint?.pointUuid - ); - return hasOutgoingTriggers && !triggeredPoints.has(point.uuid); - }); - - // For each root point, build its complete trigger chain - const executionSequences: PointsScheme[][] = []; - - function buildSequence(startUuid: string): PointsScheme[] { - const sequence: PointsScheme[] = []; - const visited = new Set(); - - function traverse(uuid: string) { - if (visited.has(uuid)) return; - visited.add(uuid); - - const point = pointMap.get(uuid); - if (point) { - sequence.push(point); - } - - // Follow forward dependencies - const nextPoints = dependencyGraph.get(uuid) || []; - nextPoints.forEach(nextUuid => traverse(nextUuid)); - } - - traverse(startUuid); - return sequence; - } - - // Build sequences for all root points - rootPoints.forEach(root => { - executionSequences.push(buildSequence(root.uuid)); - }); - - // Handle any triggered points not reachable from roots (isolated chains) - const processedPoints = new Set( - executionSequences.flat().map(p => p.uuid) - ); - - allPoints.forEach(point => { - if (triggeredPoints.has(point.uuid) && !processedPoints.has(point.uuid)) { - executionSequences.push(buildSequence(point.uuid)); + useEffect(() => { + const executionOrder = determineExecutionOrder(products); + executionOrder.forEach(point => { + if ('actions' in point) { + handleAction(point.actions[0]); + }else{ + handleAction(point.action); } }); - - return executionSequences; - } + }, [products, handleAction]); function determineExecutionOrder(products: productsSchema): PointsScheme[] { // Create maps for all events and points diff --git a/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts b/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts new file mode 100644 index 0000000..6e1f095 --- /dev/null +++ b/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts @@ -0,0 +1,13 @@ +import { useCallback } from 'react'; +import { useActionHandler } from '../../actions/useActionHandler'; + +export function useTriggerHandler() { + + const triggerPointActions = useCallback((point: PointsScheme) => { + if (!point) return; + }, []); + + return { + triggerPointActions + }; +} \ No newline at end of file diff --git a/app/src/store/simulation/useProductStore.ts b/app/src/store/simulation/useProductStore.ts index c24ec63..3ed534e 100644 --- a/app/src/store/simulation/useProductStore.ts +++ b/app/src/store/simulation/useProductStore.ts @@ -64,6 +64,7 @@ type ProductsStore = { getPointByUuid: (productId: string, modelUuid: string, pointUuid: string) => ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema | undefined; getActionByUuid: (productId: string, actionUuid: string) => (ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']) | undefined; getModelUuidByActionUuid: (productId: string, actionUuid: string) => (string) | undefined; + getPointUuidByActionUuid: (productId: string, actionUuid: string) => (string) | undefined; getTriggerByUuid: (productId: string, triggerUuid: string) => TriggerSchema | undefined; getIsEventInProduct: (productId: string, modelUuid: string) => boolean; }; @@ -598,6 +599,30 @@ export const useProductStore = create()( return undefined; }, + getPointUuidByActionUuid: (productId, actionUuid) => { + const product = get().products.find(p => p.productId === productId); + if (!product) return undefined; + + for (const event of product.eventDatas) { + if ('points' in event) { + for (const point of (event as ConveyorEventSchema).points) { + if (point.action?.actionUuid === actionUuid) { + return point.uuid; + } + } + } else if ('point' in event) { + const point = (event as any).point; + if ('action' in point && point.action?.actionUuid === actionUuid) { + return point.uuid; + } else if ('actions' in point) { + const action = point.actions.find((a: any) => a.actionUuid === actionUuid); + if (action) return point.uuid; + } + } + } + return undefined; + }, + getTriggerByUuid: (productId, triggerUuid) => { const product = get().products.find(p => p.productId === productId); if (!product) return undefined; diff --git a/app/src/types/simulationTypes.d.ts b/app/src/types/simulationTypes.d.ts index a33056e..3cd7267 100644 --- a/app/src/types/simulationTypes.d.ts +++ b/app/src/types/simulationTypes.d.ts @@ -203,4 +203,56 @@ interface MaterialSchema { }; } -type MaterialsSchema = MaterialSchema[]; \ No newline at end of file +type MaterialsSchema = MaterialSchema[]; + + +interface ConveyorAction { + actionUuid: string; + actionName: string; + actionType: "default" | "spawn" | "swap" | "delay" | "despawn"; + material: string; + delay: number; + spawnInterval: number; + spawnCount: number; + triggers: TriggerSchema[]; +} + +interface VehicleAction { + actionUuid: string; + actionName: string; + actionType: "travel"; + unLoadDuration: number; + loadCapacity: number; + steeringAngle: number; + pickUpPoint: { position: { x: number; y: number, z: number }, rotation: { x: number; y: number, z: number } } | null; + unLoadPoint: { position: { x: number; y: number, z: number }, rotation: { x: number; y: number, z: number } } | null; + triggers: TriggerSchema[]; +} + +interface RoboticArmAction { + actionUuid: string; + actionName: string; + actionType: "pickAndPlace"; + process: { startPoint: [number, number, number] | null; endPoint: [number, number, number] | null; }; + triggers: TriggerSchema[]; +} + +interface MachineAction { + actionUuid: string; + actionName: string; + actionType: "process"; + processTime: number; + swapMaterial: string; + triggers: TriggerSchema[]; +} + +interface StorageAction { + actionUuid: string; + actionName: string; + actionType: "store"; + materials: { materialName: string; materialId: string; }[]; + storageCapacity: number; + triggers: TriggerSchema[]; +} + +type Action = ConveyorAction | VehicleAction | RoboticArmAction | MachineAction | StorageAction;