From c42aa98b17354db21990dce7475915860938f04c Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Fri, 9 May 2025 18:48:24 +0530 Subject: [PATCH] Refactor simulation components: update event handling, enhance execution sequence determination, and improve state management. --- .../sidebarRight/simulation/Simulations.tsx | 54 +++++++--- .../determineExecutionMachineSequences.ts | 101 ++++++++++++++++++ .../functions/determineExecutionOrder.ts | 6 +- .../functions/determineExecutionSequences.ts | 2 +- .../simulation/simulator/simulator.tsx | 2 +- 5 files changed, 144 insertions(+), 21 deletions(-) create mode 100644 app/src/modules/simulation/simulator/functions/determineExecutionMachineSequences.ts diff --git a/app/src/components/layout/sidebarRight/simulation/Simulations.tsx b/app/src/components/layout/sidebarRight/simulation/Simulations.tsx index a261e08..b665c3d 100644 --- a/app/src/components/layout/sidebarRight/simulation/Simulations.tsx +++ b/app/src/components/layout/sidebarRight/simulation/Simulations.tsx @@ -1,4 +1,4 @@ -import React, { useRef, useState } from "react"; +import React, { useEffect, useRef, useState } from "react"; import { AddIcon, ArrowIcon, @@ -20,9 +20,12 @@ import { useEventsStore } from "../../../../store/simulation/useEventsStore"; import { deleteEventDataApi } from "../../../../services/simulation/deleteEventDataApi"; import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertProductOrEventApi"; import { deleteProductApi } from "../../../../services/simulation/deleteProductApi"; +import { renameProductApi } from "../../../../services/simulation/renameProductApi"; +import { determineExecutionMachineSequences } from "../../../../modules/simulation/simulator/functions/determineExecutionMachineSequences"; interface Event { - pathName: string; + modelName: string; + modelId: string; } interface ListProps { @@ -32,7 +35,7 @@ interface ListProps { const List: React.FC = ({ val }) => { return (
-
{val.pathName}
+
{val.modelName}
); }; @@ -46,6 +49,7 @@ const Simulations: React.FC = () => { renameProduct, addEvent, removeEvent, + getProductById } = useProductStore(); const { selectedProduct, setSelectedProduct } = useSelectedProduct(); const { getEventByModelUuid } = useEventsStore(); @@ -53,6 +57,7 @@ const Simulations: React.FC = () => { const email = localStorage.getItem("email"); const organization = email!.split("@")[1].split(".")[0]; const [openObjects, setOpenObjects] = useState(true); + const [processes, setProcesses] = useState(); const handleAddProduct = () => { const id = generateUUID(); @@ -92,6 +97,7 @@ const Simulations: React.FC = () => { const handleRenameProduct = (productId: string, newName: string) => { renameProduct(productId, newName); + renameProductApi({ productName: newName, productId, organization }); if (selectedProduct.productId === productId) { setSelectedProduct(productId, newName); } @@ -111,14 +117,27 @@ const Simulations: React.FC = () => { } }; - const selectedProductData = products.find( - (product) => product.productId === selectedProduct.productId - ); + useEffect(() => { + const processes: Event[][] = []; + const selectedProductData = getProductById(selectedProduct.productId); - const events: Event[] = - selectedProductData?.eventDatas.map((event) => ({ - pathName: event.modelName, - })) || []; + if (selectedProductData) { + determineExecutionMachineSequences([selectedProductData]) + .then((sequences) => { + sequences.forEach((sequence) => { + const events: Event[] = + sequence.map((event) => ({ + modelName: event.modelName, + modelId: event.modelUuid + })) || []; + processes.push(events); + }) + console.log('processes: ', processes); + setProcesses(processes) + }) + + } + }, [selectedProduct.productId]) return (
@@ -141,8 +160,8 @@ const Simulations: React.FC = () => {
{/* eslint-disable-next-line */} @@ -197,9 +216,14 @@ const Simulations: React.FC = () => {
{openObjects && - events.map((event, index) => ( - - ))} + processes?.map((process, index) => +
+ {process.map((event, index) => ( + + ))} +
+ ) + }
diff --git a/app/src/modules/simulation/simulator/functions/determineExecutionMachineSequences.ts b/app/src/modules/simulation/simulator/functions/determineExecutionMachineSequences.ts new file mode 100644 index 0000000..211b28f --- /dev/null +++ b/app/src/modules/simulation/simulator/functions/determineExecutionMachineSequences.ts @@ -0,0 +1,101 @@ +import { extractTriggersFromPoint } from "./extractTriggersFromPoint"; + +export async function determineExecutionMachineSequences(products: productsSchema): Promise { + const pointToEventMap = new Map(); + const allPoints: PointsScheme[] = []; + + // First pass: map points to their corresponding events + products.forEach(product => { + product.eventDatas.forEach(event => { + if (event.type === 'transfer') { + event.points.forEach(point => { + pointToEventMap.set(point.uuid, event); + allPoints.push(point); + }); + } else if ( + event.type === 'vehicle' || + event.type === 'machine' || + event.type === 'storageUnit' || + event.type === 'roboticArm' + ) { + pointToEventMap.set(event.point.uuid, event); + allPoints.push(event.point); + } + }); + }); + + // Build 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 && pointToEventMap.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); + }); + + // Find root points (points that trigger others but are not triggered themselves) + const rootPoints = allPoints.filter(point => { + const hasOutgoingTriggers = extractTriggersFromPoint(point).some( + t => t.triggeredAsset?.triggeredPoint?.pointUuid + ); + return hasOutgoingTriggers && !triggeredPoints.has(point.uuid); + }); + + const executionSequences: EventsSchema[][] = []; + + function buildSequence(startUuid: string): EventsSchema[] { + const sequence: EventsSchema[] = []; + const visited = new Set(); + + function traverse(uuid: string) { + if (visited.has(uuid)) return; + visited.add(uuid); + + const event = pointToEventMap.get(uuid); + if (event && !sequence.includes(event)) { + sequence.push(event); + } + + const nextPoints = dependencyGraph.get(uuid) || []; + nextPoints.forEach(nextUuid => traverse(nextUuid)); + } + + traverse(startUuid); + return sequence; + } + + // Build sequences from root points + rootPoints.forEach(root => { + executionSequences.push(buildSequence(root.uuid)); + }); + + // Handle any isolated triggered points + const processedEvents = new Set( + executionSequences.flat().map(event => event) + ); + + allPoints.forEach(point => { + const event = pointToEventMap.get(point.uuid); + if (triggeredPoints.has(point.uuid) && event && !processedEvents.has(event)) { + executionSequences.push(buildSequence(point.uuid)); + } + }); + + return executionSequences; +} \ No newline at end of file diff --git a/app/src/modules/simulation/simulator/functions/determineExecutionOrder.ts b/app/src/modules/simulation/simulator/functions/determineExecutionOrder.ts index fd42547..1f29ab3 100644 --- a/app/src/modules/simulation/simulator/functions/determineExecutionOrder.ts +++ b/app/src/modules/simulation/simulator/functions/determineExecutionOrder.ts @@ -18,10 +18,8 @@ export function determineExecutionOrder(products: productsSchema): PointsScheme[ }); } else if (event.type === 'vehicle' || event.type === 'machine' || - event.type === 'storageUnit') { - pointMap.set(event.point.uuid, event.point); - allPoints.push(event.point); - } else if (event.type === 'roboticArm') { + event.type === 'storageUnit' || + event.type === 'roboticArm') { pointMap.set(event.point.uuid, event.point); allPoints.push(event.point); } diff --git a/app/src/modules/simulation/simulator/functions/determineExecutionSequences.ts b/app/src/modules/simulation/simulator/functions/determineExecutionSequences.ts index afd5324..bb88fb5 100644 --- a/app/src/modules/simulation/simulator/functions/determineExecutionSequences.ts +++ b/app/src/modules/simulation/simulator/functions/determineExecutionSequences.ts @@ -1,6 +1,6 @@ import { extractTriggersFromPoint } from "./extractTriggersFromPoint"; -export function determineExecutionSequences(products: productsSchema): PointsScheme[][] { +export async function determineExecutionSequences(products: productsSchema): Promise { // Create maps for all points const pointMap = new Map(); const allPoints: PointsScheme[] = []; diff --git a/app/src/modules/simulation/simulator/simulator.tsx b/app/src/modules/simulation/simulator/simulator.tsx index 8c9d8f0..d6ff2fa 100644 --- a/app/src/modules/simulation/simulator/simulator.tsx +++ b/app/src/modules/simulation/simulator/simulator.tsx @@ -14,7 +14,7 @@ function Simulator() { if (!isPlaying || isReset) return; const executionOrder = determineExecutionOrder(products); - executionOrder.map(point => { + executionOrder.forEach(point => { const action = 'actions' in point ? point.actions[0] : point.action; handleAction(action); });