first commit
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
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<string, EventsSchema>();
|
||||
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<string, string[]>();
|
||||
const triggeredPoints = new Set<string>();
|
||||
|
||||
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<string>();
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
import { extractTriggersFromPoint } from "./extractTriggersFromPoint";
|
||||
|
||||
export async function determineExecutionMachineSequences(products: productsSchema): Promise<EventsSchema[][]> {
|
||||
const pointToEventMap = new Map<string, EventsSchema>();
|
||||
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<string, string[]>();
|
||||
const reverseDependencyGraph = new Map<string, string[]>();
|
||||
const triggeredPoints = new Set<string>();
|
||||
|
||||
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<string>();
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import { extractTriggersFromPoint } from "./extractTriggersFromPoint";
|
||||
|
||||
export function determineExecutionOrder(products: productsSchema): PointsScheme[] {
|
||||
// Create maps for all events and points
|
||||
const eventMap = new Map<string, EventsSchema>();
|
||||
const pointMap = new Map<string, PointsScheme>();
|
||||
const allPoints: PointsScheme[] = [];
|
||||
|
||||
// First pass: collect all points
|
||||
products.forEach(product => {
|
||||
product.eventDatas.forEach(event => {
|
||||
eventMap.set(event.modelUuid, 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 dependency graphs
|
||||
const graph = new Map<string, string[]>();
|
||||
const reverseGraph = new Map<string, string[]>();
|
||||
const allTriggeredPoints = new Set<string>();
|
||||
|
||||
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);
|
||||
allTriggeredPoints.add(targetUuid);
|
||||
|
||||
if (!reverseGraph.has(targetUuid)) {
|
||||
reverseGraph.set(targetUuid, []);
|
||||
}
|
||||
reverseGraph.get(targetUuid)!.push(point.uuid);
|
||||
}
|
||||
});
|
||||
|
||||
graph.set(point.uuid, dependencies);
|
||||
});
|
||||
|
||||
// Identify root points (points that trigger others but aren't triggered themselves)
|
||||
const rootPoints = allPoints
|
||||
.filter(point => !allTriggeredPoints.has(point.uuid))
|
||||
.filter(point => {
|
||||
// Only include roots that actually have triggers pointing FROM them
|
||||
const triggers = extractTriggersFromPoint(point);
|
||||
return triggers.some(t => t.triggeredAsset?.triggeredPoint?.pointUuid);
|
||||
});
|
||||
|
||||
// If no root points found but we have triggered points, find the earliest triggers
|
||||
if (rootPoints.length === 0 && allTriggeredPoints.size > 0) {
|
||||
// This handles cases where we have circular dependencies
|
||||
// but still want to include the triggered points
|
||||
const minTriggerCount = Math.min(
|
||||
...Array.from(allTriggeredPoints)
|
||||
.map(uuid => (graph.get(uuid) || []).length)
|
||||
);
|
||||
const potentialRoots = Array.from(allTriggeredPoints)
|
||||
.filter(uuid => (graph.get(uuid) || []).length === minTriggerCount);
|
||||
|
||||
rootPoints.push(...potentialRoots.map(uuid => pointMap.get(uuid)!));
|
||||
}
|
||||
|
||||
// Topological sort only for triggered points
|
||||
const visited = new Set<string>();
|
||||
const temp = new Set<string>();
|
||||
const order: string[] = [];
|
||||
let hasCycle = false;
|
||||
|
||||
function visit(node: string) {
|
||||
if (temp.has(node)) {
|
||||
hasCycle = true;
|
||||
return;
|
||||
}
|
||||
if (visited.has(node)) return;
|
||||
|
||||
temp.add(node);
|
||||
|
||||
const dependencies = reverseGraph.get(node) || [];
|
||||
for (const dep of dependencies) {
|
||||
visit(dep);
|
||||
}
|
||||
|
||||
temp.delete(node);
|
||||
visited.add(node);
|
||||
order.push(node);
|
||||
}
|
||||
|
||||
// Start processing from root points
|
||||
rootPoints.forEach(root => visit(root.uuid));
|
||||
|
||||
// Convert UUIDs back to points and filter out untriggered points
|
||||
const triggeredPoints = order
|
||||
.map(uuid => pointMap.get(uuid)!)
|
||||
.filter(point => allTriggeredPoints.has(point.uuid) ||
|
||||
rootPoints.some(root => root.uuid === point.uuid));
|
||||
|
||||
return triggeredPoints;
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
import { extractTriggersFromPoint } from "./extractTriggersFromPoint";
|
||||
|
||||
export async function determineExecutionSequences(products: productsSchema): Promise<PointsScheme[][]> {
|
||||
// Create maps for all points
|
||||
const pointMap = new Map<string, PointsScheme>();
|
||||
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<string, string[]>();
|
||||
const reverseDependencyGraph = new Map<string, string[]>();
|
||||
const triggeredPoints = new Set<string>();
|
||||
|
||||
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<string>();
|
||||
|
||||
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));
|
||||
}
|
||||
});
|
||||
|
||||
return executionSequences;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
export function extractTriggersFromPoint(point: PointsScheme): TriggerSchema[] {
|
||||
if ('actions' in point) {
|
||||
return point.actions.flatMap(action => action.triggers);
|
||||
} else if ('action' in point) {
|
||||
return point.action.triggers;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
import { extractTriggersFromPoint } from "./extractTriggersFromPoint";
|
||||
|
||||
// Gets all conveyor sequences split by non-transfer events
|
||||
export function getConveyorSequencesInProduct(
|
||||
product: {
|
||||
productName: string;
|
||||
productUuid: string;
|
||||
eventDatas: EventsSchema[];
|
||||
}
|
||||
): EventsSchema[][][] {
|
||||
const machineSequences = determineExecutionMachineSequences([product]);
|
||||
const allConveyorSequences: EventsSchema[][][] = [];
|
||||
|
||||
for (const machineSequence of machineSequences) {
|
||||
const conveyorSequencesForMachine: EventsSchema[][] = [];
|
||||
let currentSequence: EventsSchema[] = [];
|
||||
|
||||
for (const event of machineSequence) {
|
||||
if (event.type === 'transfer') {
|
||||
currentSequence.push(event);
|
||||
} else {
|
||||
// Split sequence when non-transfer event is encountered
|
||||
if (currentSequence.length > 0) {
|
||||
conveyorSequencesForMachine.push([...currentSequence]);
|
||||
currentSequence = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the last sequence if it exists
|
||||
if (currentSequence.length > 0) {
|
||||
conveyorSequencesForMachine.push([...currentSequence]);
|
||||
}
|
||||
|
||||
if (conveyorSequencesForMachine.length > 0) {
|
||||
allConveyorSequences.push(conveyorSequencesForMachine);
|
||||
}
|
||||
}
|
||||
|
||||
return allConveyorSequences;
|
||||
}
|
||||
|
||||
// Finds the subsequence containing a specific conveyor
|
||||
export function findConveyorSubsequence(
|
||||
product: {
|
||||
productName: string;
|
||||
productUuid: string;
|
||||
eventDatas: EventsSchema[];
|
||||
},
|
||||
conveyorModelUuid: string
|
||||
): {
|
||||
allSequences: EventsSchema[][][];
|
||||
parentSequence: EventsSchema[][];
|
||||
currentSubSequence: EventsSchema[];
|
||||
} | null {
|
||||
const allSequences = getConveyorSequencesInProduct(product);
|
||||
|
||||
for (const parentSequence of allSequences) {
|
||||
for (const currentSubSequence of parentSequence) {
|
||||
const hasTargetConveyor = currentSubSequence.some(
|
||||
event => event.type === 'transfer' && event.modelUuid === conveyorModelUuid
|
||||
);
|
||||
|
||||
if (hasTargetConveyor) {
|
||||
return {
|
||||
allSequences,
|
||||
parentSequence,
|
||||
currentSubSequence
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Helper function to get machine sequences (simplified from your example)
|
||||
function determineExecutionMachineSequences(products: productsSchema): EventsSchema[][] {
|
||||
const pointToEventMap = new Map<string, EventsSchema>();
|
||||
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<string, string[]>();
|
||||
const triggeredPoints = new Set<string>();
|
||||
|
||||
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<string>();
|
||||
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user