import { useSceneContext } from "../../../scene/sceneContext"; import { extractTriggersFromPoint } from "./extractTriggersFromPoint"; export function getRoboticArmSequencesInProduct( product: { productName: string; productUuid: string; eventDatas: EventsSchema[]; } ): EventsSchema[][][] { // Get all machine sequences for this product const machineSequences = determineExecutionMachineSequences([product]); const allRoboticArmSequences: EventsSchema[][][] = []; // Process each machine sequence separately for (const machineSequence of machineSequences) { const roboticArmSequencesForThisMachineSequence: EventsSchema[][] = []; let currentRoboticArmSequence: EventsSchema[] = []; for (const event of machineSequence) { if (event.type === 'roboticArm') { // Add robotic arm to current sequence currentRoboticArmSequence.push(event); } else if (event.type === 'vehicle') { // Vehicle encountered - split the sequence if (currentRoboticArmSequence.length > 0) { roboticArmSequencesForThisMachineSequence.push([...currentRoboticArmSequence]); currentRoboticArmSequence = []; } } // Other machine types continue the current sequence } // Add any remaining robotic arms in the current sequence if (currentRoboticArmSequence.length > 0) { roboticArmSequencesForThisMachineSequence.push([...currentRoboticArmSequence]); } if (roboticArmSequencesForThisMachineSequence.length > 0) { allRoboticArmSequences.push(roboticArmSequencesForThisMachineSequence); } } return allRoboticArmSequences; } export function findRoboticArmSubsequence( product: { productName: string; productUuid: string; eventDatas: EventsSchema[]; }, roboticArmModelUuid: string ): { allSequences: EventsSchema[][][]; parentSequence: EventsSchema[][]; currentSubSequence: EventsSchema[]; } | null { const allSequences = getRoboticArmSequencesInProduct(product); for (const parentSequence of allSequences) { for (const currentSubSequence of parentSequence) { const hasTargetRoboticArm = currentSubSequence.some( event => event.type === 'roboticArm' && event.modelUuid === roboticArmModelUuid ); if (hasTargetRoboticArm) { return { allSequences, parentSequence, currentSubSequence }; } } } return null; } // React component/hook that uses the pure functions export function useCheckActiveRoboticArmsInSubsequence() { const {armBotStore} = useSceneContext(); const { getArmBotById } = armBotStore(); return function (product: { productName: string; productUuid: string; eventDatas: EventsSchema[]; }, roboticArmModelUuid: string) { const result = findRoboticArmSubsequence(product, roboticArmModelUuid); if (!result) return null; const hasActiveRoboticArm = result.currentSubSequence.some(event => { if (event.type === 'roboticArm' && event.modelUuid !== roboticArmModelUuid) { const armBot = getArmBotById(event.modelUuid); return armBot?.isActive; } return false; }); return { ...result, hasActiveRoboticArm }; }; } // Helper function to get machine sequences (simplified from your example) function determineExecutionMachineSequences(products: productsSchema): EventsSchema[][] { 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' || event.type === 'human' ) { pointToEventMap.set(event.point.uuid, event); allPoints.push(event.point); } }); }); // Build dependency graph const dependencyGraph = 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); } }); dependencyGraph.set(point.uuid, dependencies); }); // Find root points (points that aren't triggered by others) const rootPoints = allPoints.filter(point => !triggeredPoints.has(point.uuid) && dependencyGraph.get(point.uuid)?.length ); 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)); }); return executionSequences; }