Refactor event handling and state management for StaticMachine and ArmBot types
- Updated `loadInitialFloorItems.ts` to streamline event data processing for StaticMachine and ArmBot types. - Enhanced `copyPasteControls.tsx` and `duplicationControls.tsx` to support StaticMachine and ArmBot event data creation with proper UUID generation. - Modified `moveControls.tsx`, `rotateControls.tsx`, and `transformControls.tsx` to include event data in the state. - Improved `pathConnector.tsx` to handle connections for StaticMachine and ArmBot types, including deletion functionality. - Updated store management to rename `useDeleteModels` to `useDeleteTool` for clarity. - Adjusted type definitions in `worldTypes.d.ts` to include StaticMachine and ArmBot event schemas.
This commit is contained in:
@@ -3,7 +3,7 @@ import React, { useEffect, useRef, useState } from 'react';
|
||||
import * as THREE from 'three';
|
||||
import * as Types from '../../../types/world/worldTypes';
|
||||
import { QuadraticBezierLine } from '@react-three/drei';
|
||||
import { useIsConnecting, useRenderDistance, useSimulationStates, useSocketStore } from '../../../store/store';
|
||||
import { useDeleteTool, useIsConnecting, useRenderDistance, useSimulationStates, useSocketStore } from '../../../store/store';
|
||||
import useModuleStore from '../../../store/useModuleStore';
|
||||
import { usePlayButtonStore } from '../../../store/usePlayButtonStore';
|
||||
import { setEventApi } from '../../../services/factoryBuilder/assest/floorAsset/setEventsApt';
|
||||
@@ -11,6 +11,7 @@ import { setEventApi } from '../../../services/factoryBuilder/assest/floorAsset/
|
||||
function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject<THREE.Group> }) {
|
||||
const { activeModule } = useModuleStore();
|
||||
const { gl, raycaster, scene, pointer, camera } = useThree();
|
||||
const { deleteTool } = useDeleteTool();
|
||||
const { renderDistance } = useRenderDistance();
|
||||
const { setIsConnecting } = useIsConnecting();
|
||||
const { simulationStates, setSimulationStates } = useSimulationStates();
|
||||
@@ -21,6 +22,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
const [firstSelected, setFirstSelected] = useState<{ modelUUID: string; sphereUUID: string; position: THREE.Vector3; isCorner: boolean; } | null>(null);
|
||||
const [currentLine, setCurrentLine] = useState<{ start: THREE.Vector3, end: THREE.Vector3, mid: THREE.Vector3 } | null>(null);
|
||||
const [helperlineColor, setHelperLineColor] = useState<string>('red');
|
||||
const [hoveredLineKey, setHoveredLineKey] = useState<string | null>(null);
|
||||
|
||||
const updatePathConnections = (fromModelUUID: string, fromPointUUID: string, toModelUUID: string, toPointUUID: string) => {
|
||||
const updatedPaths = simulationStates.map(path => {
|
||||
@@ -334,7 +336,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
path.modeluuid === fromModelUUID || path.modeluuid === toModelUUID
|
||||
);
|
||||
|
||||
// updateBackend(updatedPathDetails);
|
||||
updateBackend(updatedPathDetails);
|
||||
};
|
||||
|
||||
const updateBackend = async (updatedPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||
@@ -375,6 +377,38 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
|
||||
socket.emit('v2:model-asset:updateEventData', data);
|
||||
|
||||
} else if (updatedPath.type === 'StaticMachine') {
|
||||
|
||||
// await setEventApi(
|
||||
// organization,
|
||||
// updatedPath.modeluuid,
|
||||
// { type: "StaticMachine", points: updatedPath.points }
|
||||
// );
|
||||
|
||||
const data = {
|
||||
organization: organization,
|
||||
modeluuid: updatedPath.modeluuid,
|
||||
eventData: { type: "StaticMachine", points: updatedPath.points }
|
||||
}
|
||||
|
||||
socket.emit('v2:model-asset:updateEventData', data);
|
||||
|
||||
} else if (updatedPath.type === 'ArmBot') {
|
||||
|
||||
// await setEventApi(
|
||||
// organization,
|
||||
// updatedPath.modeluuid,
|
||||
// { type: "ArmBot", points: updatedPath.points }
|
||||
// );
|
||||
|
||||
const data = {
|
||||
organization: organization,
|
||||
modeluuid: updatedPath.modeluuid,
|
||||
eventData: { type: "ArmBot", points: updatedPath.points }
|
||||
}
|
||||
|
||||
socket.emit('v2:model-asset:updateEventData', data);
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
@@ -589,20 +623,10 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
}
|
||||
|
||||
// All checks passed - make the connection
|
||||
handleAddConnection(
|
||||
firstSelected.modelUUID,
|
||||
firstSelected.sphereUUID,
|
||||
modelUUID,
|
||||
sphereUUID
|
||||
);
|
||||
handleAddConnection(firstSelected.modelUUID, firstSelected.sphereUUID, modelUUID, sphereUUID);
|
||||
} else {
|
||||
// First selection - just store it
|
||||
setFirstSelected({
|
||||
modelUUID,
|
||||
sphereUUID,
|
||||
position: worldPosition,
|
||||
isCorner: isStartOrEnd
|
||||
});
|
||||
setFirstSelected({ modelUUID, sphereUUID, position: worldPosition, isCorner: isStartOrEnd });
|
||||
setIsConnecting(true);
|
||||
}
|
||||
}
|
||||
@@ -615,7 +639,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
}
|
||||
};
|
||||
|
||||
if (activeModule === 'simulation') {
|
||||
if (activeModule === 'simulation' && !deleteTool) {
|
||||
canvasElement.addEventListener("mousedown", onMouseDown);
|
||||
canvasElement.addEventListener("mouseup", onMouseUp);
|
||||
canvasElement.addEventListener("mousemove", onMouseMove);
|
||||
@@ -632,7 +656,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
canvasElement.removeEventListener("mousemove", onMouseMove);
|
||||
canvasElement.removeEventListener("contextmenu", onContextMenu);
|
||||
};
|
||||
}, [camera, scene, raycaster, firstSelected, simulationStates]);
|
||||
}, [camera, scene, raycaster, firstSelected, simulationStates, deleteTool]);
|
||||
|
||||
useFrame(() => {
|
||||
Object.values(groupRefs.current).forEach((group) => {
|
||||
@@ -665,9 +689,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
}
|
||||
}
|
||||
|
||||
const sphereIntersects = raycaster.intersectObjects(pathsGroupRef.current.children, true).filter((obj) =>
|
||||
obj.object.name.includes("events-sphere")
|
||||
);
|
||||
const sphereIntersects = raycaster.intersectObjects(pathsGroupRef.current.children, true).filter((obj) => obj.object.name.includes("events-sphere"));
|
||||
|
||||
if (sphereIntersects.length > 0) {
|
||||
const sphere = sphereIntersects[0].object;
|
||||
@@ -682,15 +704,21 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
const isVehicleToVehicle = firstPath?.type === 'Vehicle' && secondPath?.type === 'Vehicle';
|
||||
|
||||
// Inside the useFrame hook, where we check for snapped spheres:
|
||||
const isConnectable = (pathData.type === 'Vehicle' ||
|
||||
const isConnectable = (
|
||||
pathData.type === 'Vehicle' ||
|
||||
pathData.type === 'ArmBot' ||
|
||||
(pathData.points.length > 0 && (
|
||||
sphereUUID === pathData.points[0].uuid ||
|
||||
sphereUUID === pathData.points[pathData.points.length - 1].uuid
|
||||
))) &&
|
||||
sphereUUID === pathData.points[pathData.points.length - 1].uuid ||
|
||||
(pathData.type === 'Conveyor' && firstPath?.type === 'ArmBot') // Allow ArmBot to connect to middle points
|
||||
))
|
||||
) &&
|
||||
!isVehicleToVehicle &&
|
||||
!(firstPath?.type === 'Conveyor' &&
|
||||
!(
|
||||
firstPath?.type === 'Conveyor' &&
|
||||
pathData.type === 'Conveyor' &&
|
||||
!firstSelected.isCorner);
|
||||
!firstSelected.isCorner
|
||||
);
|
||||
|
||||
// Check for duplicate connection (regardless of path type)
|
||||
const isDuplicateConnection = simulationStates.some(path => {
|
||||
@@ -825,6 +853,127 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
}
|
||||
});
|
||||
|
||||
const removeConnections = (connection1: { model: string; point: string }, connection2: { model: string; point: string }) => {
|
||||
const updatedStates = simulationStates.map(state => {
|
||||
// Handle Conveyor (which has multiple points)
|
||||
if (state.type === 'Conveyor') {
|
||||
const updatedConveyor: Types.ConveyorEventsSchema = {
|
||||
...state,
|
||||
points: state.points.map(point => {
|
||||
// Check if this point is either connection1 or connection2
|
||||
if ((state.modeluuid === connection1.model && point.uuid === connection1.point) ||
|
||||
(state.modeluuid === connection2.model && point.uuid === connection2.point)) {
|
||||
|
||||
return {
|
||||
...point,
|
||||
connections: {
|
||||
...point.connections,
|
||||
targets: point.connections.targets.filter(target => {
|
||||
// Remove the target that matches the other connection
|
||||
return !(
|
||||
(target.modelUUID === connection1.model && target.pointUUID === connection1.point) ||
|
||||
(target.modelUUID === connection2.model && target.pointUUID === connection2.point)
|
||||
);
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
return point;
|
||||
})
|
||||
};
|
||||
return updatedConveyor;
|
||||
}
|
||||
// Handle Vehicle
|
||||
else if (state.type === 'Vehicle') {
|
||||
if ((state.modeluuid === connection1.model && state.points.uuid === connection1.point) ||
|
||||
(state.modeluuid === connection2.model && state.points.uuid === connection2.point)) {
|
||||
|
||||
const updatedVehicle: Types.VehicleEventsSchema = {
|
||||
...state,
|
||||
points: {
|
||||
...state.points,
|
||||
connections: {
|
||||
...state.points.connections,
|
||||
targets: state.points.connections.targets.filter(target => {
|
||||
return !(
|
||||
(target.modelUUID === connection1.model && target.pointUUID === connection1.point) ||
|
||||
(target.modelUUID === connection2.model && target.pointUUID === connection2.point)
|
||||
);
|
||||
})
|
||||
},
|
||||
// Ensure all required Vehicle point properties are included
|
||||
speed: state.points.speed,
|
||||
actions: state.points.actions
|
||||
}
|
||||
};
|
||||
return updatedVehicle;
|
||||
}
|
||||
}
|
||||
// Handle StaticMachine
|
||||
else if (state.type === 'StaticMachine') {
|
||||
if ((state.modeluuid === connection1.model && state.points.uuid === connection1.point) ||
|
||||
(state.modeluuid === connection2.model && state.points.uuid === connection2.point)) {
|
||||
|
||||
const updatedStaticMachine: Types.StaticMachineEventsSchema = {
|
||||
...state,
|
||||
points: {
|
||||
...state.points,
|
||||
connections: {
|
||||
...state.points.connections,
|
||||
targets: state.points.connections.targets.filter(target => {
|
||||
return !(
|
||||
(target.modelUUID === connection1.model && target.pointUUID === connection1.point) ||
|
||||
(target.modelUUID === connection2.model && target.pointUUID === connection2.point)
|
||||
);
|
||||
})
|
||||
},
|
||||
// Ensure all required StaticMachine point properties are included
|
||||
actions: state.points.actions,
|
||||
triggers: state.points.triggers
|
||||
}
|
||||
};
|
||||
return updatedStaticMachine;
|
||||
}
|
||||
}
|
||||
// Handle ArmBot
|
||||
else if (state.type === 'ArmBot') {
|
||||
if ((state.modeluuid === connection1.model && state.points.uuid === connection1.point) ||
|
||||
(state.modeluuid === connection2.model && state.points.uuid === connection2.point)) {
|
||||
|
||||
const updatedArmBot: Types.ArmBotEventsSchema = {
|
||||
...state,
|
||||
points: {
|
||||
...state.points,
|
||||
connections: {
|
||||
...state.points.connections,
|
||||
targets: state.points.connections.targets.filter(target => {
|
||||
return !(
|
||||
(target.modelUUID === connection1.model && target.pointUUID === connection1.point) ||
|
||||
(target.modelUUID === connection2.model && target.pointUUID === connection2.point)
|
||||
);
|
||||
})
|
||||
},
|
||||
// Ensure all required ArmBot point properties are included
|
||||
actions: state.points.actions,
|
||||
triggers: state.points.triggers
|
||||
}
|
||||
};
|
||||
return updatedArmBot;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
});
|
||||
|
||||
const updatedPaths = updatedStates.filter(state =>
|
||||
state.modeluuid === connection1.model || state.modeluuid === connection2.model
|
||||
);
|
||||
|
||||
updateBackend(updatedPaths);
|
||||
|
||||
setSimulationStates(updatedStates);
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<group name='simulationConnectionGroup' visible={!isPlaying}>
|
||||
{simulationStates.flatMap(path => {
|
||||
@@ -832,7 +981,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
return path.points.flatMap(point =>
|
||||
point.connections.targets.map((target, index) => {
|
||||
const targetPath = simulationStates.find(p => p.modeluuid === target.modelUUID);
|
||||
if (targetPath?.type === 'Vehicle') return null;
|
||||
if (targetPath?.type !== 'Conveyor' && targetPath?.type !== 'ArmBot') return null;
|
||||
|
||||
const fromSphere = pathsGroupRef.current?.getObjectByProperty('uuid', point.uuid);
|
||||
const toSphere = pathsGroupRef.current?.getObjectByProperty('uuid', target.pointUUID);
|
||||
@@ -845,11 +994,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
|
||||
const distance = fromWorldPosition.distanceTo(toWorldPosition);
|
||||
const heightFactor = Math.max(0.5, distance * 0.2);
|
||||
const midPoint = new THREE.Vector3(
|
||||
(fromWorldPosition.x + toWorldPosition.x) / 2,
|
||||
Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor,
|
||||
(fromWorldPosition.z + toWorldPosition.z) / 2
|
||||
);
|
||||
const midPoint = new THREE.Vector3((fromWorldPosition.x + toWorldPosition.x) / 2, Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor, (fromWorldPosition.z + toWorldPosition.z) / 2);
|
||||
|
||||
return (
|
||||
<QuadraticBezierLine
|
||||
@@ -858,11 +1003,30 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
start={fromWorldPosition.toArray()}
|
||||
end={toWorldPosition.toArray()}
|
||||
mid={midPoint.toArray()}
|
||||
color="white"
|
||||
color={
|
||||
deleteTool && hoveredLineKey === `${point.uuid}-${target.pointUUID}-${index}`
|
||||
? 'red'
|
||||
: targetPath?.type === 'ArmBot'
|
||||
? '#42a5f5'
|
||||
: 'white'
|
||||
}
|
||||
lineWidth={4}
|
||||
dashed
|
||||
dashed={(deleteTool && hoveredLineKey === `${point.uuid}-${target.pointUUID}-${index}`) ? false : true}
|
||||
dashSize={0.75}
|
||||
dashScale={20}
|
||||
onPointerOver={() => setHoveredLineKey(`${point.uuid}-${target.pointUUID}-${index}`)}
|
||||
onPointerOut={() => setHoveredLineKey(null)}
|
||||
onClick={() => {
|
||||
if (deleteTool) {
|
||||
|
||||
const connection1 = { model: path.modeluuid, point: point.uuid }
|
||||
const connection2 = { model: target.modelUUID, point: target.pointUUID }
|
||||
|
||||
removeConnections(connection1, connection2)
|
||||
|
||||
}
|
||||
}}
|
||||
userData={target}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -884,11 +1048,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
|
||||
const distance = fromWorldPosition.distanceTo(toWorldPosition);
|
||||
const heightFactor = Math.max(0.5, distance * 0.2);
|
||||
const midPoint = new THREE.Vector3(
|
||||
(fromWorldPosition.x + toWorldPosition.x) / 2,
|
||||
Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor,
|
||||
(fromWorldPosition.z + toWorldPosition.z) / 2
|
||||
);
|
||||
const midPoint = new THREE.Vector3((fromWorldPosition.x + toWorldPosition.x) / 2, Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor, (fromWorldPosition.z + toWorldPosition.z) / 2);
|
||||
|
||||
return (
|
||||
<QuadraticBezierLine
|
||||
@@ -897,11 +1057,27 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
start={fromWorldPosition.toArray()}
|
||||
end={toWorldPosition.toArray()}
|
||||
mid={midPoint.toArray()}
|
||||
color="orange"
|
||||
color={
|
||||
deleteTool && hoveredLineKey === `${path.points.uuid}-${target.pointUUID}-${index}`
|
||||
? 'red'
|
||||
: 'orange'
|
||||
}
|
||||
lineWidth={4}
|
||||
dashed
|
||||
dashed={(deleteTool && hoveredLineKey === `${path.points.uuid}-${target.pointUUID}-${index}`) ? false : true}
|
||||
dashSize={0.75}
|
||||
dashScale={20}
|
||||
onPointerOver={() => setHoveredLineKey(`${path.points.uuid}-${target.pointUUID}-${index}`)}
|
||||
onPointerOut={() => setHoveredLineKey(null)}
|
||||
onClick={() => {
|
||||
if (deleteTool) {
|
||||
|
||||
const connection1 = { model: path.modeluuid, point: path.points.uuid }
|
||||
const connection2 = { model: target.modelUUID, point: target.pointUUID }
|
||||
|
||||
removeConnections(connection1, connection2)
|
||||
}
|
||||
}}
|
||||
userData={target}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -925,11 +1101,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
|
||||
const distance = fromWorldPosition.distanceTo(toWorldPosition);
|
||||
const heightFactor = Math.max(0.5, distance * 0.2);
|
||||
const midPoint = new THREE.Vector3(
|
||||
(fromWorldPosition.x + toWorldPosition.x) / 2,
|
||||
Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor,
|
||||
(fromWorldPosition.z + toWorldPosition.z) / 2
|
||||
);
|
||||
const midPoint = new THREE.Vector3((fromWorldPosition.x + toWorldPosition.x) / 2, Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor, (fromWorldPosition.z + toWorldPosition.z) / 2);
|
||||
|
||||
return (
|
||||
<QuadraticBezierLine
|
||||
@@ -938,11 +1110,28 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||
start={fromWorldPosition.toArray()}
|
||||
end={toWorldPosition.toArray()}
|
||||
mid={midPoint.toArray()}
|
||||
color="#42a5f5"
|
||||
color={
|
||||
deleteTool && hoveredLineKey === `${path.points.uuid}-${target.pointUUID}-${index}`
|
||||
? 'red'
|
||||
: '#42a5f5'
|
||||
}
|
||||
lineWidth={4}
|
||||
dashed
|
||||
dashed={(deleteTool && hoveredLineKey === `${path.points.uuid}-${target.pointUUID}-${index}`) ? false : true}
|
||||
dashSize={0.75}
|
||||
dashScale={20}
|
||||
onPointerOver={() => setHoveredLineKey(`${path.points.uuid}-${target.pointUUID}-${index}`)}
|
||||
onPointerOut={() => setHoveredLineKey(null)}
|
||||
onClick={() => {
|
||||
if (deleteTool) {
|
||||
|
||||
const connection1 = { model: path.modeluuid, point: path.points.uuid }
|
||||
const connection2 = { model: target.modelUUID, point: target.pointUUID }
|
||||
|
||||
removeConnections(connection1, connection2)
|
||||
|
||||
}
|
||||
}}
|
||||
userData={target}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user