feat: Add simulation analyzer component with comprehensive tracking and performance metrics.
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
import { useEffect, useCallback, useRef } from "react";
|
||||
import { useSceneContext } from "../../scene/sceneContext";
|
||||
import { useAnimationPlaySpeed, usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
||||
|
||||
function Analyzer() {
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { conveyorStore, machineStore, armBotStore, humanStore, vehicleStore, craneStore, storageUnitStore, materialStore, analysisStore, humanEventManagerRef } = useSceneContext();
|
||||
const { speed } = useAnimationPlaySpeed();
|
||||
const { conveyorStore, machineStore, armBotStore, humanStore, vehicleStore, craneStore, storageUnitStore, materialStore, analysisStore, humanEventManagerRef, getSimulationTime } =
|
||||
useSceneContext();
|
||||
|
||||
const { conveyors } = conveyorStore();
|
||||
const { machines } = machineStore();
|
||||
@@ -14,10 +17,8 @@ function Analyzer() {
|
||||
const { cranes } = craneStore();
|
||||
const { storageUnits } = storageUnitStore();
|
||||
const { materials, materialHistory, getMaterialsByModel } = materialStore();
|
||||
const { speed } = useAnimationPlaySpeed();
|
||||
|
||||
const { setAnalysis, setAnalyzing, analysis } = analysisStore();
|
||||
const { getSimulationTime } = useSceneContext();
|
||||
|
||||
// ============================================================================
|
||||
// COMPREHENSIVE TRACKING REFS FOR PERFORMANCE METRICS
|
||||
@@ -2277,15 +2278,15 @@ function Analyzer() {
|
||||
|
||||
// Trigger analysis when assets or materials change
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return;
|
||||
if (!isPlaying || isPaused) return;
|
||||
|
||||
// Perform analysis when any asset or material state changes
|
||||
performAnalysisRef.current();
|
||||
}, [conveyors, vehicles, armBots, machines, humans, cranes, materials, isPlaying]);
|
||||
}, [conveyors, vehicles, armBots, machines, humans, cranes, materials, isPlaying, isPaused]);
|
||||
|
||||
// Perform initial analysis and set up interval
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return;
|
||||
if (!isPlaying || isPaused) return;
|
||||
|
||||
// Set up periodic analysis (every 1 second)
|
||||
analysisIntervalRef.current = setInterval(() => {
|
||||
@@ -2297,11 +2298,11 @@ function Analyzer() {
|
||||
clearInterval(analysisIntervalRef.current);
|
||||
}
|
||||
};
|
||||
}, [isPlaying]);
|
||||
}, [isPlaying, isPaused]);
|
||||
|
||||
// Monitor material changes and track additions/removals
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return;
|
||||
if (!isPlaying || isPaused) return;
|
||||
|
||||
// Track material movements by comparing current materials with previous state
|
||||
materials.forEach((material) => {
|
||||
@@ -2341,11 +2342,11 @@ function Analyzer() {
|
||||
}
|
||||
}
|
||||
});
|
||||
}, [materials, isPlaying, trackMaterialAddition, trackMaterialRemoval]);
|
||||
}, [materials, isPlaying, isPaused, trackMaterialAddition, trackMaterialRemoval]);
|
||||
|
||||
// Monitor asset state changes
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return;
|
||||
if (!isPlaying || isPaused) return;
|
||||
|
||||
const allAssets = [
|
||||
...conveyors.map((c) => ({ id: c.modelUuid, state: c.state, isActive: !c.isPaused, type: "conveyor" as const })),
|
||||
@@ -2378,11 +2379,11 @@ function Analyzer() {
|
||||
// Update previous state
|
||||
updatePreviousAssetState(asset.id, asset.state, asset.isActive, currentMaterialCount);
|
||||
});
|
||||
}, [conveyors, machines, armBots, vehicles, humans, cranes, storageUnits, isPlaying, getMaterialsByModel, trackStateChange, trackBottleneckEvent, updatePreviousAssetState]);
|
||||
}, [conveyors, machines, armBots, vehicles, humans, cranes, storageUnits, isPlaying, isPaused, getMaterialsByModel, trackStateChange, trackBottleneckEvent, updatePreviousAssetState]);
|
||||
|
||||
// Monitor ArmBot action changes to track cycles
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return;
|
||||
if (!isPlaying || isPaused) return;
|
||||
|
||||
armBots.forEach((armBot) => {
|
||||
const previousActionUuid = previousArmBotActionsRef.current[armBot.modelUuid];
|
||||
@@ -2423,11 +2424,11 @@ function Analyzer() {
|
||||
|
||||
previousArmBotActionsRef.current[armBot.modelUuid] = currentActionUuid;
|
||||
});
|
||||
}, [armBots, isPlaying]);
|
||||
}, [armBots, isPlaying, isPaused]);
|
||||
|
||||
// Monitor Machine action changes to track cycles
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return;
|
||||
if (!isPlaying || isPaused) return;
|
||||
|
||||
machines.forEach((machine) => {
|
||||
const previousActionUuid = previousMachineActionsRef.current[machine.modelUuid];
|
||||
@@ -2450,11 +2451,11 @@ function Analyzer() {
|
||||
|
||||
previousMachineActionsRef.current[machine.modelUuid] = currentActionUuid;
|
||||
});
|
||||
}, [machines, isPlaying]);
|
||||
}, [machines, isPlaying, isPaused]);
|
||||
|
||||
// Monitor Storage load changes to track store/retrieve operations
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return;
|
||||
if (!isPlaying || isPaused) return;
|
||||
|
||||
storageUnits.forEach((storage) => {
|
||||
const previousLoad = previousStorageLoadsRef.current[storage.modelUuid] || 0;
|
||||
@@ -2478,11 +2479,11 @@ function Analyzer() {
|
||||
|
||||
previousStorageLoadsRef.current[storage.modelUuid] = currentLoad;
|
||||
});
|
||||
}, [storageUnits, isPlaying]);
|
||||
}, [storageUnits, isPlaying, isPaused]);
|
||||
|
||||
// Monitor Human action changes from EventManager
|
||||
useEffect(() => {
|
||||
if (!isPlaying || !humanEventManagerRef.current) return;
|
||||
if (!isPlaying || isPaused || !humanEventManagerRef.current) return;
|
||||
|
||||
const interval = setInterval(() => {
|
||||
if (!humanEventManagerRef.current) return;
|
||||
@@ -2525,11 +2526,11 @@ function Analyzer() {
|
||||
}, 100);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [isPlaying, humanEventManagerRef]);
|
||||
}, [isPlaying, isPaused, humanEventManagerRef]);
|
||||
|
||||
// Periodic WIP and throughput snapshots
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return;
|
||||
if (!isPlaying || isPaused) return;
|
||||
|
||||
const snapshotInterval = setInterval(() => {
|
||||
const allAssetIds = [
|
||||
@@ -2548,11 +2549,11 @@ function Analyzer() {
|
||||
}, 1000); // Every 1 seconds
|
||||
|
||||
return () => clearInterval(snapshotInterval);
|
||||
}, [conveyors, machines, armBots, vehicles, humans, cranes, storageUnits, isPlaying, updateWIPSnapshot]);
|
||||
}, [conveyors, machines, armBots, vehicles, humans, cranes, storageUnits, isPlaying, isPaused, updateWIPSnapshot]);
|
||||
|
||||
// Monitor Vehicle phase changes to track completed trips
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return;
|
||||
if (!isPlaying || isPaused) return;
|
||||
|
||||
vehicles.forEach((vehicle) => {
|
||||
const previousPhase = previousVehiclePhasesRef.current[vehicle.modelUuid];
|
||||
@@ -2574,11 +2575,11 @@ function Analyzer() {
|
||||
|
||||
previousVehiclePhasesRef.current[vehicle.modelUuid] = currentPhase;
|
||||
});
|
||||
}, [vehicles, isPlaying]);
|
||||
}, [vehicles, isPlaying, isPaused]);
|
||||
|
||||
// Monitor Crane phase changes to track completed cycles, loads, and lifts
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return;
|
||||
if (!isPlaying || isPaused) return;
|
||||
|
||||
cranes.forEach((crane) => {
|
||||
const previousPhase = previousCranePhasesRef.current[crane.modelUuid];
|
||||
@@ -2616,7 +2617,7 @@ function Analyzer() {
|
||||
|
||||
previousCranePhasesRef.current[crane.modelUuid] = currentPhase;
|
||||
});
|
||||
}, [cranes, isPlaying]);
|
||||
}, [cranes, isPlaying, isPaused]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user