feat: Add useSpawnHandler hook to manage material spawning for conveyor actions in the simulation, including pause/resume logic.
This commit is contained in:
@@ -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,
|
||||
});
|
||||
}, []);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user