feat: Add useSpawnHandler hook to manage material spawning for conveyor actions in the simulation, including pause/resume logic.

This commit is contained in:
2025-12-23 10:02:32 +05:30
parent 6d49c39e6c
commit c701b08992

View File

@@ -1,4 +1,4 @@
import { useCallback, useEffect, useState } from "react";
import { useCallback, useEffect, useRef } from "react";
import * as THREE from "three";
import { useFrame } from "@react-three/fiber";
import { usePlayButtonStore, useAnimationPlaySpeed, usePauseButtonStore, useResetButtonStore } from "../../../../../store/ui/usePlayButtonStore";
@@ -29,7 +29,7 @@ export function useSpawnHandler() {
const { speed } = useAnimationPlaySpeed();
const { isReset } = useResetButtonStore();
const [activeSpawns, setActiveSpawns] = useState<Map<string, SpawnInstance>>(new Map());
const activeSpawns = useRef<Map<string, SpawnInstance>>(new Map());
const getConveyorPausedState = useCallback(
(action: ConveyorAction) => {
@@ -51,7 +51,7 @@ export function useSpawnHandler() {
);
const clearAllSpawns = useCallback(() => {
setActiveSpawns(new Map());
activeSpawns.current.clear();
}, []);
useEffect(() => {
@@ -109,7 +109,7 @@ export function useSpawnHandler() {
const completedActions: string[] = [];
let hasChanges = false;
activeSpawns.forEach((spawn) => {
activeSpawns.current.forEach((spawn) => {
const isPausedNow = shouldPauseSpawn(spawn.params.action);
if (isPausedNow && !spawn.isPaused) {
@@ -136,12 +136,16 @@ export function useSpawnHandler() {
});
if (isPlaying && !isReset && !isPaused) {
activeSpawns.forEach((spawn, actionUuid) => {
activeSpawns.current.forEach((spawn, actionUuid) => {
if (spawn.isPaused) return;
const { material, intervalMs, totalCount, action } = spawn.params;
if (spawn.spawnCount >= totalCount) return;
if (spawn.spawnCount >= totalCount) {
completedActions.push(actionUuid);
return;
}
// intervalMs is in simulation time, and currentTime is simulation time. No speed adjustment needed.
const adjustedInterval = intervalMs;
const isFirstSpawn = spawn.lastSpawnTime === null;
@@ -186,15 +190,9 @@ export function useSpawnHandler() {
});
}
if (hasChanges || completedActions.length > 0) {
setActiveSpawns((prevSpawns) => {
const newSpawns = new Map(prevSpawns);
completedActions.forEach((actionUuid) => {
newSpawns.delete(actionUuid);
});
return newSpawns;
if (completedActions.length > 0) {
completedActions.forEach((actionUuid) => {
activeSpawns.current.delete(actionUuid);
});
}
});
@@ -205,29 +203,23 @@ export function useSpawnHandler() {
const { material, spawnInterval = 0, spawnCount = 1, actionUuid } = action;
const intervalMs = spawnInterval * 1000;
setActiveSpawns((prevSpawns) => {
const newSpawns = new Map(prevSpawns);
if (activeSpawns.current.has(actionUuid)) {
activeSpawns.current.delete(actionUuid);
}
if (newSpawns.has(actionUuid)) {
newSpawns.delete(actionUuid);
}
newSpawns.set(actionUuid, {
lastSpawnTime: null,
startTime: getSimulationTime(),
spawnCount: 0,
params: {
material,
intervalMs,
totalCount: spawnCount,
action: action,
},
pauseStartTime: 0,
remainingTime: 0,
isPaused: false,
});
return newSpawns;
activeSpawns.current.set(actionUuid, {
lastSpawnTime: null,
startTime: getSimulationTime(),
spawnCount: 0,
params: {
material,
intervalMs,
totalCount: spawnCount,
action: action,
},
pauseStartTime: 0,
remainingTime: 0,
isPaused: false,
});
}, []);