human to conveyor, conveyor to human multiple actions completed
This commit is contained in:
@@ -6,65 +6,92 @@ import { useSceneContext } from '../../../scene/sceneContext';
|
||||
type ConveyorCallback = {
|
||||
conveyorId: string;
|
||||
callback: () => void;
|
||||
except: string[];
|
||||
};
|
||||
|
||||
export function useConveyorEventManager() {
|
||||
const { conveyorStore } = useSceneContext();
|
||||
const { getConveyorById } = conveyorStore();
|
||||
const callbacksRef = useRef<ConveyorCallback[]>([]);
|
||||
const { materialStore } = useSceneContext();
|
||||
const { getMaterialsByCurrentModelUuid } = materialStore();
|
||||
const callbacksRef = useRef<Map<string, ConveyorCallback[]>>(new Map());
|
||||
const isCooldownRef = useRef<Map<string, boolean>>(new Map());
|
||||
const isMonitoringRef = useRef(false);
|
||||
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
const { isReset } = useResetButtonStore();
|
||||
|
||||
useEffect(() => {
|
||||
if (isReset) {
|
||||
callbacksRef.current = [];
|
||||
callbacksRef.current.clear();
|
||||
isCooldownRef.current.clear();
|
||||
isMonitoringRef.current = false;
|
||||
}
|
||||
}, [isReset])
|
||||
}, [isReset]);
|
||||
|
||||
// Add a new conveyor to monitor
|
||||
const addConveyorToMonitor = (conveyorId: string, callback: () => void) => {
|
||||
// Avoid duplicates
|
||||
if (!callbacksRef.current.some((entry) => entry.conveyorId === conveyorId)) {
|
||||
callbacksRef.current.push({ conveyorId, callback });
|
||||
const addConveyorToMonitor = (conveyorId: string, callback: () => void, except?: string[]) => {
|
||||
if (!callbacksRef.current.has(conveyorId)) {
|
||||
callbacksRef.current.set(conveyorId, []);
|
||||
}
|
||||
|
||||
// Start monitoring if not already running
|
||||
if (!isMonitoringRef.current) {
|
||||
isMonitoringRef.current = true;
|
||||
}
|
||||
callbacksRef.current.get(conveyorId)!.push({ conveyorId, callback, except: except || [] });
|
||||
isMonitoringRef.current = true;
|
||||
};
|
||||
|
||||
// Remove a conveyor from monitoring
|
||||
const removeConveyorFromMonitor = (conveyorId: string) => {
|
||||
callbacksRef.current = callbacksRef.current.filter(
|
||||
(entry) => entry.conveyorId !== conveyorId
|
||||
);
|
||||
|
||||
// Stop monitoring if no more conveyors to track
|
||||
if (callbacksRef.current.length === 0) {
|
||||
callbacksRef.current.delete(conveyorId);
|
||||
isCooldownRef.current.delete(conveyorId);
|
||||
if (callbacksRef.current.size === 0) {
|
||||
isMonitoringRef.current = false;
|
||||
}
|
||||
};
|
||||
|
||||
// Check conveyor states every frame
|
||||
useFrame(() => {
|
||||
if (!isMonitoringRef.current || callbacksRef.current.length === 0 || !isPlaying || isPaused) return;
|
||||
if (!isMonitoringRef.current || !isPlaying || isPaused) return;
|
||||
|
||||
callbacksRef.current.forEach(({ conveyorId, callback }) => {
|
||||
const conveyor = getConveyorById(conveyorId);
|
||||
if (conveyor?.isPaused === false) {
|
||||
callback();
|
||||
removeConveyorFromMonitor(conveyorId); // Remove after triggering
|
||||
callbacksRef.current.forEach((queue, conveyorId) => {
|
||||
if (!queue || queue.length === 0) return;
|
||||
if (isCooldownRef.current.get(conveyorId)) return;
|
||||
|
||||
const { callback, except } = queue[0];
|
||||
const conveyorMaterials = getMaterialsByCurrentModelUuid(conveyorId);
|
||||
|
||||
let conditionMet = false;
|
||||
|
||||
if (!conveyorMaterials || conveyorMaterials.length === 0) {
|
||||
conditionMet = true;
|
||||
} else {
|
||||
const pausedMaterials = conveyorMaterials.filter(m => m.isPaused);
|
||||
|
||||
if (pausedMaterials.length === 0) {
|
||||
conditionMet = true;
|
||||
} else {
|
||||
const allPausedInExcept = pausedMaterials.filter(m => !except.includes(m.materialId));
|
||||
if (allPausedInExcept.length === 0) {
|
||||
conditionMet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (conditionMet) {
|
||||
queue.shift();
|
||||
if (callback) callback();
|
||||
|
||||
if (queue.length === 0) {
|
||||
removeConveyorFromMonitor(conveyorId);
|
||||
} else {
|
||||
isCooldownRef.current.set(conveyorId, true);
|
||||
setTimeout(() => {
|
||||
isCooldownRef.current.set(conveyorId, false);
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Cleanup on unmount
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
callbacksRef.current = [];
|
||||
callbacksRef.current.clear();
|
||||
isCooldownRef.current.clear();
|
||||
isMonitoringRef.current = false;
|
||||
};
|
||||
}, []);
|
||||
@@ -73,4 +100,4 @@ export function useConveyorEventManager() {
|
||||
addConveyorToMonitor,
|
||||
removeConveyorFromMonitor,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user