feat: Enhance ArmBotState with connections and isActive properties

- Updated ArmBotState interface across multiple files to include connections (source and targets) and isActive properties.
- Implemented logic in ProcessAnimator to check if processes are connected to active ArmBots, preventing future spawns if connected.
- Adjusted animation state handling to account for active ArmBots, stopping animations and resetting states as necessary.
- Refactored related functions for better clarity and maintainability.
This commit is contained in:
2025-04-16 11:39:03 +05:30
parent 5c24d7ca71
commit e0082cb55a
9 changed files with 755 additions and 638 deletions

View File

@@ -1,4 +1,4 @@
import React, { useRef, useEffect, useMemo } from "react";
import React, { useRef, useEffect, useMemo, useCallback } from "react";
import { useLoader, useFrame } from "@react-three/fiber";
import { GLTFLoader } from "three-stdlib";
import * as THREE from "three";
@@ -18,9 +18,13 @@ interface ArmBotState {
status: string;
material: string;
triggerId: string;
connections: {
source: { modelUUID: string; pointUUID: string };
targets: { modelUUID: string; pointUUID: string }[];
};
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
isActive?: boolean;
}
interface ProcessContainerProps {
processes: ProcessData[];
setProcesses: React.Dispatch<React.SetStateAction<any[]>>;
@@ -103,9 +107,33 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
// In processAnimator.tsx - only the relevant spawn logic part that needs fixes
// Add this function to ProcessAnimator component
const isConnectedToActiveArmBot = useCallback(
(processId: any) => {
// Check if any active armbot is connected to this process
return armBots.some((armbot) => {
if (!armbot.isActive) return false;
// Check if this armbot is connected to the process
return armbot.connections?.targets?.some((connection: any) => {
// Find the process that owns this modelUUID
const connectedProcess = processes.find((p) =>
p.paths?.some((path) => path.modeluuid === connection.modelUUID)
);
return connectedProcess?.id === processId;
});
});
},
[armBots, processes]
);
// In processAnimator.tsx - only the relevant spawn logic part that needs fixes
useFrame(() => {
// Spawn logic frame
const currentTime = clockRef.current.getElapsedTime() - elapsedBeforePauseRef.current;
const currentTime =
clockRef.current.getElapsedTime() - elapsedBeforePauseRef.current;
setAnimationStates((prev) => {
const newStates = { ...prev };
@@ -119,6 +147,14 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
return;
}
if (isConnectedToActiveArmBot(process.id)) {
newStates[process.id] = {
...processState,
nextSpawnTime: Infinity, // Prevent future spawns
};
return;
}
const spawnPoint = findSpawnPoint(process);
if (!spawnPoint || !spawnPoint.actions) return;
@@ -133,7 +169,10 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
: parseFloat(spawnAction.spawnInterval as string) || 0;
// Check if this is a zero interval spawn and we already spawned an object
if (spawnInterval === 0 && processState.hasSpawnedZeroIntervalObject === true) {
if (
spawnInterval === 0 &&
processState.hasSpawnedZeroIntervalObject === true
) {
return; // Don't spawn more objects for zero interval
}
@@ -183,6 +222,29 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
const processState = newStates[process.id];
if (!processState) return;
if (isConnectedToActiveArmBot(process.id)) {
newStates[process.id] = {
...processState,
spawnedObjects: Object.entries(processState.spawnedObjects).reduce(
(acc, [id, obj]) => ({
...acc,
[id]: {
...obj,
state: {
...obj.state,
isAnimating: false, // Stop animation
isDelaying: false, // Clear delays
delayComplete: false, // Reset delays
progress: 0, // Reset progress
},
},
}),
{}
),
};
return;
}
if (processState.isProcessDelaying) {
const effectiveDelayTime =
processState.processDelayDuration / speedRef.current;
@@ -338,10 +400,13 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
if (isLastPoint) {
const isAgvPicking = agvRef.current.some(
(agv: any) => agv.processId === process.id && agv.status === "picking"
(agv: any) =>
agv.processId === process.id && agv.status === "picking"
);
const shouldHide = !currentPointData?.actions || !hasNonInheritActions(currentPointData.actions);
const shouldHide =
!currentPointData?.actions ||
!hasNonInheritActions(currentPointData.actions);
if (shouldHide) {
if (isAgvPicking) {
@@ -372,7 +437,8 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
if (tempStackedObjectsRef.current[objectId]) {
const isAgvPicking = agvRef.current.some(
(agv: any) => agv.processId === process.id && agv.status === "picking"
(agv: any) =>
agv.processId === process.id && agv.status === "picking"
);
if (isAgvPicking) {
@@ -391,7 +457,8 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
if (!isLastPoint) {
const nextPoint = path[nextPointIdx];
const distance = path[stateRef.currentIndex].distanceTo(nextPoint);
const distance =
path[stateRef.currentIndex].distanceTo(nextPoint);
const effectiveSpeed = stateRef.speed * speedRef.current;
const movement = effectiveSpeed * delta;
@@ -442,7 +509,6 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
return newStates;
});
});
if (!processedProcesses || processedProcesses.length === 0) {
return null;
}