Merge remote-tracking branch 'origin/v2-ui'
This commit is contained in:
@@ -83,13 +83,13 @@ export function useSpawnHandler() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (action.triggers[0].triggeredAsset?.triggeredModel.modelUuid &&
|
if (action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid &&
|
||||||
action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid &&
|
action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid &&
|
||||||
action.triggers[0].triggeredAsset?.triggeredAction?.actionUuid
|
action.triggers[0]?.triggeredAsset?.triggeredAction?.actionUuid
|
||||||
) {
|
) {
|
||||||
newMaterial.next = {
|
newMaterial.next = {
|
||||||
modelUuid: action.triggers[0].triggeredAsset?.triggeredModel.modelUuid,
|
modelUuid: action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid,
|
||||||
pointUuid: action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid,
|
pointUuid: action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ export function useRetrieveHandler() {
|
|||||||
actionUuid: action.actionUuid
|
actionUuid: action.actionUuid
|
||||||
},
|
},
|
||||||
current: {
|
current: {
|
||||||
modelUuid: action.triggers[0].triggeredAsset.triggeredModel.modelUuid,
|
modelUuid: action.triggers[0]?.triggeredAsset.triggeredModel.modelUuid,
|
||||||
pointUuid: action.triggers[0].triggeredAsset.triggeredPoint.pointUuid,
|
pointUuid: action.triggers[0]?.triggeredAsset.triggeredPoint.pointUuid,
|
||||||
actionUuid: action.triggers[0].triggeredAsset.triggeredAction.actionUuid
|
actionUuid: action.triggers[0]?.triggeredAsset.triggeredAction.actionUuid
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -110,13 +110,13 @@ export function useRetrieveHandler() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retrieval.action.triggers.length === 0 || !retrieval.action.triggers[0].triggeredAsset) {
|
if (retrieval.action.triggers.length === 0 || !retrieval.action.triggers[0]?.triggeredAsset) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const triggeredModel = getEventByModelUuid(
|
const triggeredModel = getEventByModelUuid(
|
||||||
selectedProduct.productId,
|
selectedProduct.productId,
|
||||||
retrieval.action.triggers[0].triggeredAsset.triggeredModel.modelUuid
|
retrieval.action.triggers[0]?.triggeredAsset.triggeredModel.modelUuid
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!triggeredModel) return;
|
if (!triggeredModel) return;
|
||||||
@@ -160,10 +160,10 @@ export function useRetrieveHandler() {
|
|||||||
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
||||||
if (lastMaterial) {
|
if (lastMaterial) {
|
||||||
|
|
||||||
if (retrieval.action.triggers[0].triggeredAsset.triggeredAction?.actionUuid) {
|
if (retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid) {
|
||||||
const action = getActionByUuid(selectedProduct.productId, retrieval.action.triggers[0].triggeredAsset.triggeredAction.actionUuid);
|
const action = getActionByUuid(selectedProduct.productId, retrieval.action.triggers[0]?.triggeredAsset.triggeredAction.actionUuid);
|
||||||
if (action && action.triggers.length > 0 && action.triggers[0].triggeredAsset?.triggeredModel.modelUuid) {
|
if (action && action.triggers.length > 0 && action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid) {
|
||||||
const model = getEventByModelUuid(selectedProduct.productId, action.triggers[0].triggeredAsset.triggeredModel.modelUuid);
|
const model = getEventByModelUuid(selectedProduct.productId, action.triggers[0]?.triggeredAsset.triggeredModel.modelUuid);
|
||||||
if (model) {
|
if (model) {
|
||||||
if (model.type === 'vehicle') {
|
if (model.type === 'vehicle') {
|
||||||
const vehicle = getVehicleById(model.modelUuid);
|
const vehicle = getVehicleById(model.modelUuid);
|
||||||
@@ -178,7 +178,7 @@ export function useRetrieveHandler() {
|
|||||||
|
|
||||||
addCurrentAction(
|
addCurrentAction(
|
||||||
triggeredModel.modelUuid,
|
triggeredModel.modelUuid,
|
||||||
retrieval.action.triggers[0].triggeredAsset.triggeredAction?.actionUuid ?? '',
|
retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid ?? '',
|
||||||
material.materialType,
|
material.materialType,
|
||||||
material.materialId
|
material.materialId
|
||||||
);
|
);
|
||||||
@@ -195,7 +195,7 @@ export function useRetrieveHandler() {
|
|||||||
|
|
||||||
addCurrentAction(
|
addCurrentAction(
|
||||||
triggeredModel.modelUuid,
|
triggeredModel.modelUuid,
|
||||||
retrieval.action.triggers[0].triggeredAsset.triggeredAction?.actionUuid ?? '',
|
retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid ?? '',
|
||||||
material.materialType,
|
material.materialType,
|
||||||
material.materialId
|
material.materialId
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import React, { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { useMaterialStore } from '../../../../../store/simulation/useMaterialStore';
|
import { useMaterialStore } from '../../../../../store/simulation/useMaterialStore';
|
||||||
import { useConveyorStore } from '../../../../../store/simulation/useConveyorStore';
|
import { useConveyorStore } from '../../../../../store/simulation/useConveyorStore';
|
||||||
import { useResetButtonStore } from '../../../../../store/usePlayButtonStore';
|
import { useResetButtonStore } from '../../../../../store/usePlayButtonStore';
|
||||||
import { findConveyorInSequences } from '../../../simulator/functions/findConveyorInSequences';
|
|
||||||
import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore';
|
import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore';
|
||||||
import { useProductStore } from '../../../../../store/simulation/useProductStore';
|
import { useProductStore } from '../../../../../store/simulation/useProductStore';
|
||||||
|
// import { findConveyorSubsequence } from '../../../simulator/functions/getConveyorSequencesInProduct';
|
||||||
|
|
||||||
function ConveyorInstance({ conveyor }: { conveyor: ConveyorStatus }) {
|
function ConveyorInstance({ conveyor }: { conveyor: ConveyorStatus }) {
|
||||||
const { getProductById } = useProductStore();
|
const { getProductById } = useProductStore();
|
||||||
@@ -17,28 +17,51 @@ function ConveyorInstance({ conveyor }: { conveyor: ConveyorStatus }) {
|
|||||||
const product = getProductById(selectedProduct.productId);
|
const product = getProductById(selectedProduct.productId);
|
||||||
if (!product) return;
|
if (!product) return;
|
||||||
|
|
||||||
const sequenceInfo = findConveyorInSequences(product, conveyor.modelUuid);
|
|
||||||
if (!sequenceInfo) return;
|
|
||||||
|
|
||||||
const { currentSubSequence } = sequenceInfo;
|
|
||||||
const conveyorMaterials = getMaterialsByCurrentModelUuid(conveyor.modelUuid);
|
const conveyorMaterials = getMaterialsByCurrentModelUuid(conveyor.modelUuid);
|
||||||
|
if (conveyorMaterials && conveyorMaterials?.length > 0) {
|
||||||
|
|
||||||
if (conveyorMaterials && conveyorMaterials.length > 0) {
|
const hasPausedMaterials = conveyorMaterials.some(material => material.isPaused);
|
||||||
const shouldPauseSubsequence = currentSubSequence.some(subConveyor => {
|
|
||||||
if (subConveyor.type !== 'transfer') return false;
|
|
||||||
const subMaterials = getMaterialsByCurrentModelUuid(subConveyor.modelUuid);
|
|
||||||
return subMaterials?.some(m => m.isPaused) ?? false;
|
|
||||||
});
|
|
||||||
|
|
||||||
currentSubSequence.forEach(subConveyor => {
|
if (hasPausedMaterials) {
|
||||||
if (subConveyor.type === 'transfer') {
|
setConveyorPaused(conveyor.modelUuid, true);
|
||||||
setConveyorPaused(subConveyor.modelUuid, shouldPauseSubsequence);
|
} else {
|
||||||
}
|
setConveyorPaused(conveyor.modelUuid, false);
|
||||||
});
|
}
|
||||||
|
} else {
|
||||||
|
setConveyorPaused(conveyor.modelUuid, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// const conveyorSubsequence = findConveyorSubsequence(product, conveyor.modelUuid);
|
||||||
|
|
||||||
|
// if (!conveyorSubsequence || !conveyorSubsequence.currentSubSequence) {
|
||||||
|
// setConveyorPaused(conveyor.modelUuid, false);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const { currentSubSequence } = conveyorSubsequence;
|
||||||
|
|
||||||
|
// const allMaterials = currentSubSequence.flatMap(event =>
|
||||||
|
// getMaterialsByCurrentModelUuid(event.modelUuid)
|
||||||
|
// );
|
||||||
|
|
||||||
|
// const hasPausedMaterials = allMaterials.some(mat => mat?.isPaused);
|
||||||
|
|
||||||
|
// currentSubSequence.forEach(event => {
|
||||||
|
// if (event.type === 'transfer') {
|
||||||
|
// setConveyorPaused(event.modelUuid, hasPausedMaterials);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
}, [materials, conveyor.modelUuid, getMaterialsByCurrentModelUuid, setConveyorPaused, isReset, selectedProduct.productId, getProductById]);
|
}, [materials, conveyor.modelUuid, getMaterialsByCurrentModelUuid, setConveyorPaused, isReset, selectedProduct.productId, getProductById]);
|
||||||
|
|
||||||
return null;
|
useEffect(() => {
|
||||||
}
|
// console.log('conveyor: ', conveyor);
|
||||||
|
}, [conveyor])
|
||||||
|
|
||||||
export default React.memo(ConveyorInstance);
|
return (
|
||||||
|
<>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ConveyorInstance
|
||||||
207
app/src/modules/simulation/events/arrows/arrows.tsx
Normal file
207
app/src/modules/simulation/events/arrows/arrows.tsx
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
import * as THREE from "three";
|
||||||
|
import { useMemo, useRef } from "react";
|
||||||
|
import { useThree } from "@react-three/fiber";
|
||||||
|
|
||||||
|
interface ConnectionLine {
|
||||||
|
id: string;
|
||||||
|
startPointUuid: string;
|
||||||
|
endPointUuid: string;
|
||||||
|
trigger: TriggerSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Arrows({ connections }: { connections: ConnectionLine[] }) {
|
||||||
|
const groupRef = useRef<THREE.Group>(null);
|
||||||
|
const { scene } = useThree();
|
||||||
|
|
||||||
|
const getWorldPositionFromScene = (uuid: string): THREE.Vector3 | null => {
|
||||||
|
const obj = scene.getObjectByProperty("uuid", uuid);
|
||||||
|
if (!obj) return null;
|
||||||
|
const pos = new THREE.Vector3();
|
||||||
|
obj.getWorldPosition(pos);
|
||||||
|
return pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
const createArrow = (
|
||||||
|
key: string,
|
||||||
|
fullCurve: THREE.QuadraticBezierCurve3,
|
||||||
|
centerT: number,
|
||||||
|
segmentSize: number,
|
||||||
|
scale: number,
|
||||||
|
reverse = false
|
||||||
|
) => {
|
||||||
|
const t1 = Math.max(0, centerT - segmentSize / 2);
|
||||||
|
const t2 = Math.min(1, centerT + segmentSize / 2);
|
||||||
|
const subCurve = getSubCurve(fullCurve, t1, t2, reverse);
|
||||||
|
|
||||||
|
const shaftGeometry = new THREE.TubeGeometry(subCurve, 8, 0.01 * scale, 8, false);
|
||||||
|
|
||||||
|
const end = subCurve.getPoint(1);
|
||||||
|
const tangent = subCurve.getTangent(1).normalize();
|
||||||
|
|
||||||
|
const arrowHeadLength = 0.15 * scale;
|
||||||
|
const arrowRadius = 0.01 * scale;
|
||||||
|
const arrowHeadRadius = arrowRadius * 2.5;
|
||||||
|
|
||||||
|
const headGeometry = new THREE.ConeGeometry(arrowHeadRadius, arrowHeadLength, 8);
|
||||||
|
headGeometry.translate(0, arrowHeadLength / 2, 0);
|
||||||
|
|
||||||
|
const rotation = new THREE.Quaternion().setFromUnitVectors(
|
||||||
|
new THREE.Vector3(0, 1, 0),
|
||||||
|
tangent
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<group key={key}>
|
||||||
|
<mesh geometry={shaftGeometry}>
|
||||||
|
<meshStandardMaterial color="#42a5f5" />
|
||||||
|
</mesh>
|
||||||
|
<mesh position={end} quaternion={rotation} geometry={headGeometry}>
|
||||||
|
<meshStandardMaterial color="#42a5f5" />
|
||||||
|
</mesh>
|
||||||
|
</group>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getSubCurve = (
|
||||||
|
curve: THREE.Curve<THREE.Vector3>,
|
||||||
|
t1: number,
|
||||||
|
t2: number,
|
||||||
|
reverse = false
|
||||||
|
) => {
|
||||||
|
const divisions = 10;
|
||||||
|
const subPoints = Array.from({ length: divisions + 1 }, (_, i) => {
|
||||||
|
const t = THREE.MathUtils.lerp(t1, t2, i / divisions);
|
||||||
|
return curve.getPoint(t);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (reverse) subPoints.reverse();
|
||||||
|
|
||||||
|
return new THREE.CatmullRomCurve3(subPoints);
|
||||||
|
};
|
||||||
|
|
||||||
|
const arrowGroups = connections.flatMap((connection) => {
|
||||||
|
const start = getWorldPositionFromScene(connection.startPointUuid);
|
||||||
|
const end = getWorldPositionFromScene(connection.endPointUuid);
|
||||||
|
if (!start || !end) return [];
|
||||||
|
|
||||||
|
const isBidirectional = connections.some(
|
||||||
|
(other) =>
|
||||||
|
other.startPointUuid === connection.endPointUuid &&
|
||||||
|
other.endPointUuid === connection.startPointUuid
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isBidirectional && connection.startPointUuid < connection.endPointUuid) {
|
||||||
|
const distance = start.distanceTo(end);
|
||||||
|
const heightFactor = Math.max(0.5, distance * 0.2);
|
||||||
|
const control = new THREE.Vector3(
|
||||||
|
(start.x + end.x) / 2,
|
||||||
|
Math.max(start.y, end.y) + heightFactor,
|
||||||
|
(start.z + end.z) / 2
|
||||||
|
);
|
||||||
|
const curve = new THREE.QuadraticBezierCurve3(start, control, end);
|
||||||
|
const scale = THREE.MathUtils.clamp(distance * 0.75, 0.5, 3);
|
||||||
|
|
||||||
|
return [
|
||||||
|
createArrow(connection.id + "-fwd", curve, 0.33, 0.25, scale, true),
|
||||||
|
createArrow(connection.id + "-bwd", curve, 0.66, 0.25, scale, false),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isBidirectional) {
|
||||||
|
const distance = start.distanceTo(end);
|
||||||
|
const heightFactor = Math.max(0.5, distance * 0.2);
|
||||||
|
const control = new THREE.Vector3(
|
||||||
|
(start.x + end.x) / 2,
|
||||||
|
Math.max(start.y, end.y) + heightFactor,
|
||||||
|
(start.z + end.z) / 2
|
||||||
|
);
|
||||||
|
const curve = new THREE.QuadraticBezierCurve3(start, control, end);
|
||||||
|
const scale = THREE.MathUtils.clamp(distance * 0.75, 0.5, 5);
|
||||||
|
|
||||||
|
return [
|
||||||
|
createArrow(connection.id, curve, 0.5, 0.3, scale)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
|
return <group ref={groupRef} name="connectionArrows">{arrowGroups}</group>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ArrowOnQuadraticBezier({
|
||||||
|
start,
|
||||||
|
mid,
|
||||||
|
end,
|
||||||
|
color = "#42a5f5",
|
||||||
|
}: {
|
||||||
|
start: number[];
|
||||||
|
mid: number[];
|
||||||
|
end: number[];
|
||||||
|
color?: string;
|
||||||
|
}) {
|
||||||
|
const minScale = 0.5;
|
||||||
|
const maxScale = 5;
|
||||||
|
const segmentSize = 0.3;
|
||||||
|
|
||||||
|
const startVec = useMemo(() => new THREE.Vector3(...start), [start]);
|
||||||
|
const midVec = useMemo(() => new THREE.Vector3(...mid), [mid]);
|
||||||
|
const endVec = useMemo(() => new THREE.Vector3(...end), [end]);
|
||||||
|
|
||||||
|
const fullCurve = useMemo(
|
||||||
|
() => new THREE.QuadraticBezierCurve3(startVec, midVec, endVec),
|
||||||
|
[startVec, midVec, endVec]
|
||||||
|
);
|
||||||
|
|
||||||
|
const distance = useMemo(() => startVec.distanceTo(endVec), [startVec, endVec]);
|
||||||
|
const scale = useMemo(() => THREE.MathUtils.clamp(distance * 0.75, minScale, maxScale), [distance]);
|
||||||
|
|
||||||
|
const arrowHeadLength = 0.15 * scale;
|
||||||
|
const arrowRadius = 0.01 * scale;
|
||||||
|
const arrowHeadRadius = arrowRadius * 2.5;
|
||||||
|
|
||||||
|
const curveLength = useMemo(() => fullCurve.getLength(), [fullCurve]);
|
||||||
|
const arrowHeadTOffset = useMemo(() => Math.min(arrowHeadLength / curveLength, 0.5), [arrowHeadLength, curveLength]);
|
||||||
|
|
||||||
|
const endT = 1 - arrowHeadTOffset;
|
||||||
|
|
||||||
|
const subCurve = useMemo(() => {
|
||||||
|
const t1 = Math.max(0, endT - segmentSize / 2);
|
||||||
|
const t2 = Math.min(1, endT + segmentSize / 2);
|
||||||
|
const divisions = 10;
|
||||||
|
const subPoints = Array.from({ length: divisions + 1 }, (_, i) => {
|
||||||
|
const t = THREE.MathUtils.lerp(t1, t2, i / divisions);
|
||||||
|
return fullCurve.getPoint(t);
|
||||||
|
});
|
||||||
|
return new THREE.CatmullRomCurve3(subPoints);
|
||||||
|
}, [fullCurve, endT, segmentSize]);
|
||||||
|
|
||||||
|
const tubeGeometry = useMemo(
|
||||||
|
() => new THREE.TubeGeometry(subCurve, 20, arrowRadius, 8, false),
|
||||||
|
[subCurve, arrowRadius]
|
||||||
|
);
|
||||||
|
|
||||||
|
const arrowPosition = useMemo(() => fullCurve.getPoint(1), [fullCurve]);
|
||||||
|
const arrowTangent = useMemo(() => fullCurve.getTangent(1).normalize(), [fullCurve]);
|
||||||
|
|
||||||
|
const arrowRotation = useMemo(() => {
|
||||||
|
return new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0, 1, 0), arrowTangent);
|
||||||
|
}, [arrowTangent]);
|
||||||
|
|
||||||
|
const coneGeometry = useMemo(() => {
|
||||||
|
const geom = new THREE.ConeGeometry(arrowHeadRadius, arrowHeadLength, 8);
|
||||||
|
geom.translate(0, arrowHeadLength / 2, 0);
|
||||||
|
return geom;
|
||||||
|
}, [arrowHeadRadius, arrowHeadLength]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<group name="ArrowWithTube">
|
||||||
|
<mesh name="ArrowWithTube" geometry={tubeGeometry}>
|
||||||
|
<meshStandardMaterial color={color} />
|
||||||
|
</mesh>
|
||||||
|
<mesh name="ArrowWithTube" position={arrowPosition} quaternion={arrowRotation} geometry={coneGeometry}>
|
||||||
|
<meshStandardMaterial color={color} />
|
||||||
|
</mesh>
|
||||||
|
</group>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,17 +1,22 @@
|
|||||||
import React, { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { useEventsStore } from "../../../../../store/simulation/useEventsStore";
|
import { useEventsStore } from "../../../../../store/simulation/useEventsStore";
|
||||||
|
import { useProductStore } from "../../../../../store/simulation/useProductStore";
|
||||||
|
import { useSelectedProduct } from "../../../../../store/simulation/useSimulationStore";
|
||||||
import useModuleStore, { useSubModuleStore } from "../../../../../store/useModuleStore";
|
import useModuleStore, { useSubModuleStore } from "../../../../../store/useModuleStore";
|
||||||
import { TransformControls } from "@react-three/drei";
|
import { TransformControls } from "@react-three/drei";
|
||||||
import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys";
|
import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys";
|
||||||
import { useSelectedEventSphere, useSelectedEventData, } from "../../../../../store/simulation/useSimulationStore";
|
import { useSelectedEventSphere, useSelectedEventData, } from "../../../../../store/simulation/useSimulationStore";
|
||||||
import { useThree } from "@react-three/fiber";
|
import { useThree } from "@react-three/fiber";
|
||||||
import { usePlayButtonStore } from "../../../../../store/usePlayButtonStore";
|
import { usePlayButtonStore } from "../../../../../store/usePlayButtonStore";
|
||||||
|
import { upsertProductOrEventApi } from "../../../../../services/simulation/UpsertProductOrEventApi";
|
||||||
|
|
||||||
function PointsCreator() {
|
function PointsCreator() {
|
||||||
const { gl, raycaster, scene, pointer, camera } = useThree();
|
const { gl, raycaster, scene, pointer, camera } = useThree();
|
||||||
const { subModule } = useSubModuleStore();
|
const { subModule } = useSubModuleStore();
|
||||||
const { events, updatePoint, getPointByUuid, getEventByModelUuid } = useEventsStore();
|
const { events, updatePoint, getPointByUuid, getEventByModelUuid } = useEventsStore();
|
||||||
|
const { getEventByModelUuid: getEventByModelUuidFromProduct, updatePoint: updatePointFromProduct, getEventByModelUuid: getEventByModelUuidFromProduct2 } = useProductStore();
|
||||||
|
const { selectedProduct } = useSelectedProduct();
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
const transformRef = useRef<any>(null);
|
const transformRef = useRef<any>(null);
|
||||||
const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);
|
const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);
|
||||||
@@ -20,6 +25,23 @@ function PointsCreator() {
|
|||||||
const { setSelectedEventData, clearSelectedEventData } = useSelectedEventData();
|
const { setSelectedEventData, clearSelectedEventData } = useSelectedEventData();
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
|
|
||||||
|
const email = localStorage.getItem('email')
|
||||||
|
const organization = (email!.split("@")[1]).split(".")[0];
|
||||||
|
|
||||||
|
const updateBackend = (
|
||||||
|
productName: string,
|
||||||
|
productId: string,
|
||||||
|
organization: string,
|
||||||
|
eventData: EventsSchema
|
||||||
|
) => {
|
||||||
|
upsertProductOrEventApi({
|
||||||
|
productName: productName,
|
||||||
|
productId: productId,
|
||||||
|
organization: organization,
|
||||||
|
eventDatas: eventData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedEventSphere) {
|
if (selectedEventSphere) {
|
||||||
const eventData = getEventByModelUuid(
|
const eventData = getEventByModelUuid(
|
||||||
@@ -68,11 +90,30 @@ function PointsCreator() {
|
|||||||
selectedEventSphere.position.y,
|
selectedEventSphere.position.y,
|
||||||
selectedEventSphere.position.z,
|
selectedEventSphere.position.z,
|
||||||
];
|
];
|
||||||
updatePoint(
|
|
||||||
selectedEventSphere.userData.modelUuid,
|
const event = getEventByModelUuidFromProduct(selectedProduct.productId, selectedEventSphere.userData.modelUuid);
|
||||||
selectedEventSphere.userData.pointUuid,
|
|
||||||
point
|
if (event && selectedProduct.productId !== '') {
|
||||||
);
|
const updatedEvent = updatePointFromProduct(
|
||||||
|
selectedProduct.productId,
|
||||||
|
selectedEventSphere.userData.modelUuid,
|
||||||
|
selectedEventSphere.userData.pointUuid,
|
||||||
|
point
|
||||||
|
)
|
||||||
|
if (updatedEvent) {
|
||||||
|
updatePoint(
|
||||||
|
selectedEventSphere.userData.modelUuid,
|
||||||
|
selectedEventSphere.userData.pointUuid,
|
||||||
|
point
|
||||||
|
)
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
updatedEvent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -126,14 +167,20 @@ function PointsCreator() {
|
|||||||
<>
|
<>
|
||||||
<group name="EventPointsGroup" visible={!isPlaying}>
|
<group name="EventPointsGroup" visible={!isPlaying}>
|
||||||
{events.map((event, index) => {
|
{events.map((event, index) => {
|
||||||
if (event.type === "transfer") {
|
const updatedEvent = selectedProduct.productId !== ''
|
||||||
|
? getEventByModelUuidFromProduct2(selectedProduct.productId, event.modelUuid)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const usedEvent = updatedEvent || event;
|
||||||
|
|
||||||
|
if (usedEvent.type === "transfer") {
|
||||||
return (
|
return (
|
||||||
<group
|
<group
|
||||||
key={`${index}-${event.modelUuid}`}
|
key={`${index}-${usedEvent.modelUuid}`}
|
||||||
position={event.position}
|
position={usedEvent.position}
|
||||||
rotation={event.rotation}
|
rotation={usedEvent.rotation}
|
||||||
>
|
>
|
||||||
{event.points.map((point, j) => (
|
{usedEvent.points.map((point, j) => (
|
||||||
<mesh
|
<mesh
|
||||||
name="Event-Sphere"
|
name="Event-Sphere"
|
||||||
uuid={point.uuid}
|
uuid={point.uuid}
|
||||||
@@ -147,7 +194,7 @@ function PointsCreator() {
|
|||||||
key={`${index}-${point.uuid}`}
|
key={`${index}-${point.uuid}`}
|
||||||
position={new THREE.Vector3(...point.position)}
|
position={new THREE.Vector3(...point.position)}
|
||||||
userData={{
|
userData={{
|
||||||
modelUuid: event.modelUuid,
|
modelUuid: usedEvent.modelUuid,
|
||||||
pointUuid: point.uuid,
|
pointUuid: point.uuid,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -157,27 +204,28 @@ function PointsCreator() {
|
|||||||
))}
|
))}
|
||||||
</group>
|
</group>
|
||||||
);
|
);
|
||||||
} else if (event.type === "vehicle") {
|
} else if (usedEvent.type === "vehicle") {
|
||||||
|
const point = usedEvent.point;
|
||||||
return (
|
return (
|
||||||
<group
|
<group
|
||||||
key={`${index}-${event.modelUuid}`}
|
key={`${index}-${usedEvent.modelUuid}`}
|
||||||
position={event.position}
|
position={usedEvent.position}
|
||||||
rotation={event.rotation}
|
rotation={usedEvent.rotation}
|
||||||
>
|
>
|
||||||
<mesh
|
<mesh
|
||||||
name="Event-Sphere"
|
name="Event-Sphere"
|
||||||
uuid={event.point.uuid}
|
uuid={point.uuid}
|
||||||
ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
|
ref={(el) => (sphereRefs.current[point.uuid] = el!)}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setSelectedEventSphere(
|
setSelectedEventSphere(
|
||||||
sphereRefs.current[event.point.uuid]
|
sphereRefs.current[point.uuid]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
position={new THREE.Vector3(...event.point.position)}
|
position={new THREE.Vector3(...point.position)}
|
||||||
userData={{
|
userData={{
|
||||||
modelUuid: event.modelUuid,
|
modelUuid: usedEvent.modelUuid,
|
||||||
pointUuid: event.point.uuid,
|
pointUuid: point.uuid,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<sphereGeometry args={[0.1, 16, 16]} />
|
<sphereGeometry args={[0.1, 16, 16]} />
|
||||||
@@ -185,27 +233,28 @@ function PointsCreator() {
|
|||||||
</mesh>
|
</mesh>
|
||||||
</group>
|
</group>
|
||||||
);
|
);
|
||||||
} else if (event.type === "roboticArm") {
|
} else if (usedEvent.type === "roboticArm") {
|
||||||
|
const point = usedEvent.point;
|
||||||
return (
|
return (
|
||||||
<group
|
<group
|
||||||
key={`${index}-${event.modelUuid}`}
|
key={`${index}-${usedEvent.modelUuid}`}
|
||||||
position={event.position}
|
position={usedEvent.position}
|
||||||
rotation={event.rotation}
|
rotation={usedEvent.rotation}
|
||||||
>
|
>
|
||||||
<mesh
|
<mesh
|
||||||
name="Event-Sphere"
|
name="Event-Sphere"
|
||||||
uuid={event.point.uuid}
|
uuid={point.uuid}
|
||||||
ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
|
ref={(el) => (sphereRefs.current[point.uuid] = el!)}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setSelectedEventSphere(
|
setSelectedEventSphere(
|
||||||
sphereRefs.current[event.point.uuid]
|
sphereRefs.current[point.uuid]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
position={new THREE.Vector3(...event.point.position)}
|
position={new THREE.Vector3(...point.position)}
|
||||||
userData={{
|
userData={{
|
||||||
modelUuid: event.modelUuid,
|
modelUuid: usedEvent.modelUuid,
|
||||||
pointUuid: event.point.uuid,
|
pointUuid: point.uuid,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<sphereGeometry args={[0.1, 16, 16]} />
|
<sphereGeometry args={[0.1, 16, 16]} />
|
||||||
@@ -213,27 +262,28 @@ function PointsCreator() {
|
|||||||
</mesh>
|
</mesh>
|
||||||
</group>
|
</group>
|
||||||
);
|
);
|
||||||
} else if (event.type === "machine") {
|
} else if (usedEvent.type === "machine") {
|
||||||
|
const point = usedEvent.point;
|
||||||
return (
|
return (
|
||||||
<group
|
<group
|
||||||
key={`${index}-${event.modelUuid}`}
|
key={`${index}-${usedEvent.modelUuid}`}
|
||||||
position={event.position}
|
position={usedEvent.position}
|
||||||
rotation={event.rotation}
|
rotation={usedEvent.rotation}
|
||||||
>
|
>
|
||||||
<mesh
|
<mesh
|
||||||
name="Event-Sphere"
|
name="Event-Sphere"
|
||||||
uuid={event.point.uuid}
|
uuid={point.uuid}
|
||||||
ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
|
ref={(el) => (sphereRefs.current[point.uuid] = el!)}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setSelectedEventSphere(
|
setSelectedEventSphere(
|
||||||
sphereRefs.current[event.point.uuid]
|
sphereRefs.current[point.uuid]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
position={new THREE.Vector3(...event.point.position)}
|
position={new THREE.Vector3(...point.position)}
|
||||||
userData={{
|
userData={{
|
||||||
modelUuid: event.modelUuid,
|
modelUuid: usedEvent.modelUuid,
|
||||||
pointUuid: event.point.uuid,
|
pointUuid: point.uuid,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<sphereGeometry args={[0.1, 16, 16]} />
|
<sphereGeometry args={[0.1, 16, 16]} />
|
||||||
@@ -241,27 +291,28 @@ function PointsCreator() {
|
|||||||
</mesh>
|
</mesh>
|
||||||
</group>
|
</group>
|
||||||
);
|
);
|
||||||
} else if (event.type === "storageUnit") {
|
} else if (usedEvent.type === "storageUnit") {
|
||||||
|
const point = usedEvent.point;
|
||||||
return (
|
return (
|
||||||
<group
|
<group
|
||||||
key={`${index}-${event.modelUuid}`}
|
key={`${index}-${usedEvent.modelUuid}`}
|
||||||
position={event.position}
|
position={usedEvent.position}
|
||||||
rotation={event.rotation}
|
rotation={usedEvent.rotation}
|
||||||
>
|
>
|
||||||
<mesh
|
<mesh
|
||||||
name="Event-Sphere"
|
name="Event-Sphere"
|
||||||
uuid={event.point.uuid}
|
uuid={point.uuid}
|
||||||
ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
|
ref={(el) => (sphereRefs.current[point.uuid] = el!)}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setSelectedEventSphere(
|
setSelectedEventSphere(
|
||||||
sphereRefs.current[event.point.uuid]
|
sphereRefs.current[point.uuid]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
position={new THREE.Vector3(...event.point.position)}
|
position={new THREE.Vector3(...point.position)}
|
||||||
userData={{
|
userData={{
|
||||||
modelUuid: event.modelUuid,
|
modelUuid: usedEvent.modelUuid,
|
||||||
pointUuid: event.point.uuid,
|
pointUuid: point.uuid,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<sphereGeometry args={[0.1, 16, 16]} />
|
<sphereGeometry args={[0.1, 16, 16]} />
|
||||||
@@ -274,6 +325,7 @@ function PointsCreator() {
|
|||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
{selectedEventSphere && transformMode && (
|
{selectedEventSphere && transformMode && (
|
||||||
<TransformControls
|
<TransformControls
|
||||||
ref={transformRef}
|
ref={transformRef}
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ import { useSelectedAction, useSelectedAsset } from "../../../../store/simulatio
|
|||||||
import { useProductStore } from "../../../../store/simulation/useProductStore";
|
import { useProductStore } from "../../../../store/simulation/useProductStore";
|
||||||
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
|
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
|
||||||
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
|
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
|
||||||
import { handleAddEventToProduct } from "../../events/points/functions/handleAddEventToProduct";
|
import { handleAddEventToProduct } from "../points/functions/handleAddEventToProduct";
|
||||||
import { QuadraticBezierLine } from "@react-three/drei";
|
import { QuadraticBezierLine } from "@react-three/drei";
|
||||||
import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertProductOrEventApi";
|
import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertProductOrEventApi";
|
||||||
import { useDeleteTool } from "../../../../store/builder/store";
|
import { useDeleteTool } from "../../../../store/builder/store";
|
||||||
import { usePlayButtonStore } from "../../../../store/usePlayButtonStore";
|
import { usePlayButtonStore } from "../../../../store/usePlayButtonStore";
|
||||||
|
import { ArrowOnQuadraticBezier, Arrows } from "../arrows/arrows";
|
||||||
|
|
||||||
interface ConnectionLine {
|
interface ConnectionLine {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -368,6 +369,7 @@ function TriggerConnector() {
|
|||||||
!intersect.object.name.includes("Roof") &&
|
!intersect.object.name.includes("Roof") &&
|
||||||
!intersect.object.name.includes("agv-collider") &&
|
!intersect.object.name.includes("agv-collider") &&
|
||||||
!intersect.object.name.includes("MeasurementReference") &&
|
!intersect.object.name.includes("MeasurementReference") &&
|
||||||
|
!intersect.object.name.includes("ArrowWithTube") &&
|
||||||
!intersect.object.parent?.name.includes("Zone") &&
|
!intersect.object.parent?.name.includes("Zone") &&
|
||||||
!(intersect.object.type === "GridHelper") &&
|
!(intersect.object.type === "GridHelper") &&
|
||||||
!(intersect.object.type === "Line2")
|
!(intersect.object.type === "Line2")
|
||||||
@@ -487,18 +489,29 @@ function TriggerConnector() {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
<Arrows connections={connections} />
|
||||||
|
|
||||||
{currentLine && (
|
{currentLine && (
|
||||||
<QuadraticBezierLine
|
<>
|
||||||
start={currentLine.start.toArray()}
|
<QuadraticBezierLine
|
||||||
end={currentLine.end.toArray()}
|
start={currentLine.start.toArray()}
|
||||||
mid={currentLine.mid.toArray()}
|
end={currentLine.end.toArray()}
|
||||||
color={helperlineColor}
|
mid={currentLine.mid.toArray()}
|
||||||
lineWidth={4}
|
color={helperlineColor}
|
||||||
dashed
|
lineWidth={4}
|
||||||
dashSize={1}
|
dashed
|
||||||
dashScale={20}
|
dashSize={1}
|
||||||
/>
|
dashScale={20}
|
||||||
|
/>
|
||||||
|
<ArrowOnQuadraticBezier
|
||||||
|
start={currentLine.start.toArray()}
|
||||||
|
mid={currentLine.mid.toArray()}
|
||||||
|
end={currentLine.end.toArray()}
|
||||||
|
color={helperlineColor}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
</group>
|
</group>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -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,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -13,7 +13,6 @@ import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore
|
|||||||
import { useStorageUnitStore } from '../../../../../store/simulation/useStorageUnitStore';
|
import { useStorageUnitStore } from '../../../../../store/simulation/useStorageUnitStore';
|
||||||
import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore';
|
import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore';
|
||||||
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
|
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
|
||||||
import { useCheckActiveRoboticArmsInSubsequence } from '../../../simulator/functions/checkActiveRoboticArmsInSubsequence';
|
|
||||||
|
|
||||||
function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
||||||
|
|
||||||
@@ -27,15 +26,14 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
|||||||
const pauseTimeRef = useRef<number | null>(null);
|
const pauseTimeRef = useRef<number | null>(null);
|
||||||
const isPausedRef = useRef<boolean>(false);
|
const isPausedRef = useRef<boolean>(false);
|
||||||
const isSpeedRef = useRef<any>(null);
|
const isSpeedRef = useRef<any>(null);
|
||||||
const isIdleRef = useRef<boolean>(false);
|
|
||||||
let startTime: number;
|
let startTime: number;
|
||||||
|
|
||||||
const { armBots, setArmBotActive, setArmBotState, removeCurrentAction, incrementActiveTime, incrementIdleTime } = useArmBotStore();
|
const { setArmBotActive, setArmBotState, removeCurrentAction, incrementActiveTime, incrementIdleTime } = useArmBotStore();
|
||||||
const { decrementVehicleLoad, removeLastMaterial } = useVehicleStore();
|
const { decrementVehicleLoad, removeLastMaterial } = useVehicleStore();
|
||||||
const { removeLastMaterial: removeLastStorageMaterial, updateCurrentLoad } = useStorageUnitStore();
|
const { removeLastMaterial: removeLastStorageMaterial, updateCurrentLoad } = useStorageUnitStore();
|
||||||
const { setIsVisible, setIsPaused, getMaterialById } = useMaterialStore();
|
const { setIsVisible, setIsPaused, getMaterialById } = useMaterialStore();
|
||||||
const { selectedProduct } = useSelectedProduct();
|
const { selectedProduct } = useSelectedProduct();
|
||||||
const { getActionByUuid, getEventByActionUuid, getEventByModelUuid, getProductById } = useProductStore();
|
const { getActionByUuid, getEventByActionUuid, getEventByModelUuid } = useProductStore();
|
||||||
const { triggerPointActions } = useTriggerHandler();
|
const { triggerPointActions } = useTriggerHandler();
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
const { isReset } = useResetButtonStore();
|
const { isReset } = useResetButtonStore();
|
||||||
@@ -47,7 +45,6 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
|||||||
|
|
||||||
const animationFrameIdRef = useRef<number | null>(null);
|
const animationFrameIdRef = useRef<number | null>(null);
|
||||||
const previousTimeRef = useRef<number | null>(null);
|
const previousTimeRef = useRef<number | null>(null);
|
||||||
const checkActiveRoboticArms = useCheckActiveRoboticArmsInSubsequence();
|
|
||||||
|
|
||||||
const lastRemoved = useRef<{ type: string, materialId: string } | null>(null);
|
const lastRemoved = useRef<{ type: string, materialId: string } | null>(null);
|
||||||
|
|
||||||
@@ -90,20 +87,11 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
|||||||
|
|
||||||
if (armBot.currentAction) {
|
if (armBot.currentAction) {
|
||||||
const action = getActionByUuid(selectedProduct.productId, armBot.currentAction.actionUuid);
|
const action = getActionByUuid(selectedProduct.productId, armBot.currentAction.actionUuid);
|
||||||
const model = getEventByModelUuid(selectedProduct.productId, action?.triggers[0].triggeredAsset?.triggeredModel.modelUuid || '');
|
const model = getEventByModelUuid(selectedProduct.productId, action?.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid || '');
|
||||||
if (action && action.triggers[0].triggeredAsset?.triggeredModel.modelUuid) {
|
if (action && action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid) {
|
||||||
if (!model) return;
|
if (!model) return;
|
||||||
if (model.type === 'transfer') {
|
if (model.type === 'transfer') {
|
||||||
setIsVisible(armBot.currentAction.materialId || '', true);
|
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 === 'machine') {
|
||||||
//
|
//
|
||||||
} else if (model.type === 'vehicle') {
|
} else if (model.type === 'vehicle') {
|
||||||
@@ -116,6 +104,14 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
|||||||
triggerPointActions(action, armBot.currentAction.materialId)
|
triggerPointActions(action, armBot.currentAction.materialId)
|
||||||
removeCurrentAction(armBot.modelUuid)
|
removeCurrentAction(armBot.modelUuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lastRemoved.current) {
|
||||||
|
if (lastRemoved.current.type === 'transfer') {
|
||||||
|
setIsPaused(lastRemoved.current.materialId, true)
|
||||||
|
} else {
|
||||||
|
setIsPaused(lastRemoved.current.materialId, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,13 +382,6 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
|||||||
setCurrentPhase("rest");
|
setCurrentPhase("rest");
|
||||||
setPath([])
|
setPath([])
|
||||||
|
|
||||||
if (lastRemoved.current) {
|
|
||||||
if (lastRemoved.current.type === 'transfer') {
|
|
||||||
setIsPaused(lastRemoved.current.materialId, true)
|
|
||||||
} else {
|
|
||||||
setIsPaused(lastRemoved.current.materialId, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
import { getConveyorSequencesInProduct } from "./getConveyorSequencesForProduct";
|
|
||||||
|
|
||||||
export function findConveyorInSequences(
|
|
||||||
product: {
|
|
||||||
productName: string;
|
|
||||||
productId: string;
|
|
||||||
eventDatas: EventsSchema[];
|
|
||||||
},
|
|
||||||
conveyorUuid: string
|
|
||||||
): {
|
|
||||||
allSequences: EventsSchema[][][];
|
|
||||||
parentSequence: EventsSchema[][];
|
|
||||||
currentSubSequence: EventsSchema[];
|
|
||||||
} | null {
|
|
||||||
// Get all conveyor sequences
|
|
||||||
const allSequences = getConveyorSequencesInProduct(product);
|
|
||||||
|
|
||||||
// Search through all sequences
|
|
||||||
for (const parentSequence of allSequences) {
|
|
||||||
for (const currentSubSequence of parentSequence) {
|
|
||||||
for (const conveyor of currentSubSequence) {
|
|
||||||
// Check if this is the conveyor we're looking for
|
|
||||||
if (conveyor.modelUuid === conveyorUuid) {
|
|
||||||
return {
|
|
||||||
allSequences,
|
|
||||||
parentSequence,
|
|
||||||
currentSubSequence
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also check points in case the UUID matches a point's conveyor
|
|
||||||
if (conveyor.type === 'transfer') {
|
|
||||||
for (const point of conveyor.points) {
|
|
||||||
if (point.uuid === conveyorUuid) {
|
|
||||||
return {
|
|
||||||
allSequences,
|
|
||||||
parentSequence,
|
|
||||||
currentSubSequence
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Conveyor not found
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
@@ -1,49 +1,79 @@
|
|||||||
import { extractTriggersFromPoint } from "./extractTriggersFromPoint";
|
import { extractTriggersFromPoint } from "./extractTriggersFromPoint";
|
||||||
|
|
||||||
|
// Gets all conveyor sequences split by non-transfer events
|
||||||
export function getConveyorSequencesInProduct(
|
export function getConveyorSequencesInProduct(
|
||||||
product: {
|
product: {
|
||||||
productName: string;
|
productName: string;
|
||||||
productId: string;
|
productId: string;
|
||||||
eventDatas: EventsSchema[];
|
eventDatas: EventsSchema[];
|
||||||
}
|
}
|
||||||
): EventsSchema[][][] { // Now returns array of array of arrays
|
): EventsSchema[][][] {
|
||||||
// Get all machine sequences for this product
|
|
||||||
const machineSequences = determineExecutionMachineSequences([product]);
|
const machineSequences = determineExecutionMachineSequences([product]);
|
||||||
|
|
||||||
const allConveyorSequences: EventsSchema[][][] = [];
|
const allConveyorSequences: EventsSchema[][][] = [];
|
||||||
|
|
||||||
// Process each machine sequence separately
|
|
||||||
for (const machineSequence of machineSequences) {
|
for (const machineSequence of machineSequences) {
|
||||||
const conveyorSequencesForThisMachineSequence: EventsSchema[][] = [];
|
const conveyorSequencesForMachine: EventsSchema[][] = [];
|
||||||
let currentConveyorSequence: EventsSchema[] = [];
|
let currentSequence: EventsSchema[] = [];
|
||||||
|
|
||||||
for (const event of machineSequence) {
|
for (const event of machineSequence) {
|
||||||
if (event.type === 'transfer') {
|
if (event.type === 'transfer') {
|
||||||
// Add conveyor to current sequence
|
currentSequence.push(event);
|
||||||
currentConveyorSequence.push(event);
|
} else {
|
||||||
} else if (event.type === 'vehicle') {
|
// Split sequence when non-transfer event is encountered
|
||||||
// Vehicle encountered - split the sequence
|
if (currentSequence.length > 0) {
|
||||||
if (currentConveyorSequence.length > 0) {
|
conveyorSequencesForMachine.push([...currentSequence]);
|
||||||
conveyorSequencesForThisMachineSequence.push([...currentConveyorSequence]);
|
currentSequence = [];
|
||||||
currentConveyorSequence = [];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Other machine types don't affect the conveyor sequence
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add any remaining conveyors in the current sequence
|
// Add the last sequence if it exists
|
||||||
if (currentConveyorSequence.length > 0) {
|
if (currentSequence.length > 0) {
|
||||||
conveyorSequencesForThisMachineSequence.push([...currentConveyorSequence]);
|
conveyorSequencesForMachine.push([...currentSequence]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conveyorSequencesForThisMachineSequence.length > 0) {
|
if (conveyorSequencesForMachine.length > 0) {
|
||||||
allConveyorSequences.push(conveyorSequencesForThisMachineSequence);
|
allConveyorSequences.push(conveyorSequencesForMachine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return allConveyorSequences;
|
return allConveyorSequences;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finds the subsequence containing a specific conveyor
|
||||||
|
export function findConveyorSubsequence(
|
||||||
|
product: {
|
||||||
|
productName: string;
|
||||||
|
productId: 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)
|
// Helper function to get machine sequences (simplified from your example)
|
||||||
function determineExecutionMachineSequences(products: productsSchema): EventsSchema[][] {
|
function determineExecutionMachineSequences(products: productsSchema): EventsSchema[][] {
|
||||||
const pointToEventMap = new Map<string, EventsSchema>();
|
const pointToEventMap = new Map<string, EventsSchema>();
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import TriggerConnector from './connector/triggerConnector'
|
import TriggerConnector from '../events/triggerConnections/triggerConnector'
|
||||||
|
|
||||||
function Trigger() {
|
function Trigger() {
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,18 @@ import { useArmBotStore } from '../../../../store/simulation/useArmBotStore';
|
|||||||
import { useVehicleStore } from '../../../../store/simulation/useVehicleStore';
|
import { useVehicleStore } from '../../../../store/simulation/useVehicleStore';
|
||||||
import { useMachineStore } from '../../../../store/simulation/useMachineStore';
|
import { useMachineStore } from '../../../../store/simulation/useMachineStore';
|
||||||
import { useStorageUnitStore } from '../../../../store/simulation/useStorageUnitStore';
|
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() {
|
export function useTriggerHandler() {
|
||||||
const { handleAction } = useActionHandler();
|
const { handleAction } = useActionHandler();
|
||||||
const { selectedProduct } = useSelectedProduct();
|
const { selectedProduct } = useSelectedProduct();
|
||||||
const { getEventByTriggerUuid, getEventByModelUuid, getActionByUuid, getModelUuidByActionUuid } = useProductStore();
|
const { getEventByTriggerUuid, getEventByModelUuid, getActionByUuid, getModelUuidByActionUuid } = useProductStore();
|
||||||
const { getArmBotById } = useArmBotStore();
|
const { getArmBotById } = useArmBotStore();
|
||||||
|
const { getConveyorById } = useConveyorStore();
|
||||||
|
const { addArmBotToMonitor } = useArmBotEventManager();
|
||||||
|
const { addConveyorToMonitor } = useConveyorEventManager();
|
||||||
const { getVehicleById } = useVehicleStore();
|
const { getVehicleById } = useVehicleStore();
|
||||||
const { getMachineById } = useMachineStore();
|
const { getMachineById } = useMachineStore();
|
||||||
const { getStorageUnitById } = useStorageUnitStore();
|
const { getStorageUnitById } = useStorageUnitStore();
|
||||||
@@ -144,6 +150,10 @@ export function useTriggerHandler() {
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Event Manager Needed
|
// Event Manager Needed
|
||||||
|
setIsPaused(materialId, true);
|
||||||
|
addArmBotToMonitor(armBot.modelUuid,
|
||||||
|
() => handleAction(action, materialId)
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,12 +188,12 @@ export function useTriggerHandler() {
|
|||||||
setIsVisible(materialId, true);
|
setIsVisible(materialId, true);
|
||||||
|
|
||||||
if (action &&
|
if (action &&
|
||||||
action.triggers[0].triggeredAsset?.triggeredModel.modelUuid &&
|
action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid &&
|
||||||
action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid
|
action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid
|
||||||
) {
|
) {
|
||||||
setNextLocation(material.materialId, {
|
setNextLocation(material.materialId, {
|
||||||
modelUuid: action.triggers[0].triggeredAsset?.triggeredModel.modelUuid,
|
modelUuid: action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid,
|
||||||
pointUuid: action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid,
|
pointUuid: action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid,
|
||||||
});
|
});
|
||||||
|
|
||||||
handleAction(action, materialId);
|
handleAction(action, materialId);
|
||||||
@@ -320,12 +330,42 @@ export function useTriggerHandler() {
|
|||||||
if (armBot.isActive === false && armBot.state === 'idle') {
|
if (armBot.isActive === false && armBot.state === 'idle') {
|
||||||
|
|
||||||
// Handle current action from arm bot
|
// 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 {
|
} else {
|
||||||
|
|
||||||
// Event Manager Needed
|
// 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);
|
const material = getMaterialById(materialId);
|
||||||
if (material) {
|
if (material) {
|
||||||
|
|
||||||
// setIsPaused(material.materialId, false);
|
|
||||||
|
|
||||||
setPreviousLocation(material.materialId, {
|
setPreviousLocation(material.materialId, {
|
||||||
modelUuid: material.current.modelUuid,
|
modelUuid: material.current.modelUuid,
|
||||||
pointUuid: material.current.pointUuid,
|
pointUuid: material.current.pointUuid,
|
||||||
@@ -359,22 +397,22 @@ export function useTriggerHandler() {
|
|||||||
const action = getActionByUuid(selectedProduct.productId, trigger.triggeredAsset.triggeredAction.actionUuid);
|
const action = getActionByUuid(selectedProduct.productId, trigger.triggeredAsset.triggeredAction.actionUuid);
|
||||||
|
|
||||||
if (action && action.triggers.length > 0 &&
|
if (action && action.triggers.length > 0 &&
|
||||||
action.triggers[0].triggeredAsset?.triggeredModel.modelUuid &&
|
action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid &&
|
||||||
action.triggers[0].triggeredAsset?.triggeredAction?.actionUuid &&
|
action.triggers[0]?.triggeredAsset?.triggeredAction?.actionUuid &&
|
||||||
action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid) {
|
action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid) {
|
||||||
const model = getEventByModelUuid(selectedProduct.productId, action.triggers[0].triggeredAsset?.triggeredModel.modelUuid);
|
const model = getEventByModelUuid(selectedProduct.productId, action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid);
|
||||||
|
|
||||||
if (model?.type === 'roboticArm') {
|
if (model?.type === 'roboticArm') {
|
||||||
|
|
||||||
handleAction(action, material.materialId);
|
handleAction(action, material.materialId);
|
||||||
|
|
||||||
} else if (model?.type === 'vehicle') {
|
} else if (model?.type === 'vehicle') {
|
||||||
const nextAction = getActionByUuid(selectedProduct.productId, action.triggers[0].triggeredAsset?.triggeredAction.actionUuid);
|
const nextAction = getActionByUuid(selectedProduct.productId, action.triggers[0]?.triggeredAsset?.triggeredAction.actionUuid);
|
||||||
|
|
||||||
if (action) {
|
if (action) {
|
||||||
handleAction(action, material.materialId);
|
handleAction(action, material.materialId);
|
||||||
|
|
||||||
const vehicle = getVehicleById(action.triggers[0].triggeredAsset?.triggeredModel.modelUuid);
|
const vehicle = getVehicleById(action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid);
|
||||||
|
|
||||||
setPreviousLocation(material.materialId, {
|
setPreviousLocation(material.materialId, {
|
||||||
modelUuid: material.current.modelUuid,
|
modelUuid: material.current.modelUuid,
|
||||||
@@ -410,10 +448,19 @@ 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 {
|
} else {
|
||||||
setNextLocation(material.materialId, {
|
setNextLocation(material.materialId, {
|
||||||
modelUuid: action.triggers[0].triggeredAsset?.triggeredModel.modelUuid,
|
modelUuid: action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid,
|
||||||
pointUuid: action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid,
|
pointUuid: action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid,
|
||||||
})
|
})
|
||||||
|
|
||||||
handleAction(action, material.materialId);
|
handleAction(action, material.materialId);
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
|||||||
|
|
||||||
function startUnloadingProcess() {
|
function startUnloadingProcess() {
|
||||||
if (agvDetail.point.action.triggers.length > 0) {
|
if (agvDetail.point.action.triggers.length > 0) {
|
||||||
const trigger = getTriggerByUuid(selectedProduct.productId, agvDetail.point.action.triggers[0].triggerUuid);
|
const trigger = getTriggerByUuid(selectedProduct.productId, agvDetail.point.action.triggers[0]?.triggerUuid);
|
||||||
const model = getEventByModelUuid(selectedProduct.productId, trigger?.triggeredAsset?.triggeredModel?.modelUuid || '');
|
const model = getEventByModelUuid(selectedProduct.productId, trigger?.triggeredAsset?.triggeredModel?.modelUuid || '');
|
||||||
|
|
||||||
if (trigger && model) {
|
if (trigger && model) {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type EventsStore = {
|
|||||||
modelUuid: string,
|
modelUuid: string,
|
||||||
pointUuid: string,
|
pointUuid: string,
|
||||||
updates: Partial<ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema>
|
updates: Partial<ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema>
|
||||||
) => void;
|
) => EventsSchema | undefined;
|
||||||
|
|
||||||
// Action-level actions
|
// Action-level actions
|
||||||
addAction: (
|
addAction: (
|
||||||
@@ -101,17 +101,21 @@ export const useEventsStore = create<EventsStore>()(
|
|||||||
},
|
},
|
||||||
|
|
||||||
updatePoint: (modelUuid, pointUuid, updates) => {
|
updatePoint: (modelUuid, pointUuid, updates) => {
|
||||||
|
let updatedEvent: EventsSchema | undefined;
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
||||||
if (event && 'points' in event) {
|
if (event && 'points' in event) {
|
||||||
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
|
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
|
||||||
if (point) {
|
if (point) {
|
||||||
Object.assign(point, updates);
|
Object.assign(point, updates);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
}
|
}
|
||||||
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
|
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
|
||||||
Object.assign((event as any).point, updates);
|
Object.assign((event as any).point, updates);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return updatedEvent;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Action-level actions
|
// Action-level actions
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ type ProductsStore = {
|
|||||||
modelUuid: string,
|
modelUuid: string,
|
||||||
pointUuid: string,
|
pointUuid: string,
|
||||||
updates: Partial<ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema>
|
updates: Partial<ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema>
|
||||||
) => void;
|
) => EventsSchema | undefined;
|
||||||
|
|
||||||
// Action-level actions
|
// Action-level actions
|
||||||
addAction: (
|
addAction: (
|
||||||
@@ -195,6 +195,7 @@ export const useProductStore = create<ProductsStore>()(
|
|||||||
},
|
},
|
||||||
|
|
||||||
updatePoint: (productId, modelUuid, pointUuid, updates) => {
|
updatePoint: (productId, modelUuid, pointUuid, updates) => {
|
||||||
|
let updatedEvent: EventsSchema | undefined;
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const product = state.products.find(p => p.productId === productId);
|
const product = state.products.find(p => p.productId === productId);
|
||||||
if (product) {
|
if (product) {
|
||||||
@@ -203,12 +204,15 @@ export const useProductStore = create<ProductsStore>()(
|
|||||||
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
|
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
|
||||||
if (point) {
|
if (point) {
|
||||||
Object.assign(point, updates);
|
Object.assign(point, updates);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
}
|
}
|
||||||
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
|
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
|
||||||
Object.assign((event as any).point, updates);
|
Object.assign((event as any).point, updates);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return updatedEvent;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Action-level actions
|
// Action-level actions
|
||||||
|
|||||||
Reference in New Issue
Block a user