added event handler
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useFrame } from '@react-three/fiber';
|
||||
import { usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../store/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../products/productContext';
|
||||
|
||||
export function useCraneEventManager() {
|
||||
const { craneStore, productStore, assetStore, craneEventManagerRef } = useSceneContext();
|
||||
const { getCraneById, setCurrentPhase, removeCurrentAction } = craneStore();
|
||||
const { getAssetById } = assetStore();
|
||||
const { getActionByUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
const { isReset } = useResetButtonStore();
|
||||
|
||||
useEffect(() => {
|
||||
if ((isReset || !isPlaying) && craneEventManagerRef.current) {
|
||||
craneEventManagerRef.current.craneStates = [];
|
||||
}
|
||||
}, [isReset, isPlaying]);
|
||||
|
||||
const addCraneToMonitor = (craneId: string, callback: () => void, actionUuid: string) => {
|
||||
const crane = getCraneById(craneId);
|
||||
const action = getActionByUuid(selectedProduct.productUuid, actionUuid) as CraneAction | undefined;
|
||||
|
||||
if (!crane || !action || action.actionType !== 'pickAndDrop' || !craneEventManagerRef.current) return;
|
||||
|
||||
let state = craneEventManagerRef.current.craneStates.find(c => c.craneId === craneId);
|
||||
if (!state) {
|
||||
state = {
|
||||
craneId,
|
||||
pendingActions: [],
|
||||
currentAction: null,
|
||||
isProcessing: false
|
||||
};
|
||||
craneEventManagerRef.current.craneStates.push(state);
|
||||
}
|
||||
|
||||
state.pendingActions.push({
|
||||
actionUuid,
|
||||
callback
|
||||
});
|
||||
|
||||
if (!state.isProcessing) {
|
||||
processNextAction(state);
|
||||
}
|
||||
};
|
||||
|
||||
const processNextAction = (state: CraneEventState) => {
|
||||
if (state.pendingActions.length === 0) {
|
||||
state.currentAction = null;
|
||||
return;
|
||||
}
|
||||
|
||||
state.isProcessing = true;
|
||||
state.currentAction = state.pendingActions.shift() || null;
|
||||
};
|
||||
|
||||
const completeCurrentAction = (state: CraneEventState) => {
|
||||
processNextAction(state);
|
||||
};
|
||||
|
||||
useFrame(() => {
|
||||
if (!craneEventManagerRef.current || craneEventManagerRef.current.craneStates.length === 0 || !isPlaying || isPaused) return;
|
||||
|
||||
for (const craneState of craneEventManagerRef.current.craneStates) {
|
||||
if (!craneState.currentAction || !craneState.isProcessing) continue;
|
||||
|
||||
const { craneId, currentAction } = craneState;
|
||||
const crane = getCraneById(craneId);
|
||||
const craneAsset = getAssetById(craneId);
|
||||
const currentCraneAction = getActionByUuid(selectedProduct.productUuid, crane?.currentAction?.actionUuid || '') as CraneAction | undefined;
|
||||
|
||||
if (!crane || !craneAsset || !currentCraneAction) continue;
|
||||
if (crane.isActive || crane.state !== "idle") continue;
|
||||
|
||||
if (currentCraneAction.actionType === 'pickAndDrop' && crane.currentLoad < currentCraneAction.maxPickUpCount) {
|
||||
if (currentAction.actionUuid !== crane.currentAction?.actionUuid) {
|
||||
setCurrentPhase(crane.modelUuid, 'init');
|
||||
removeCurrentAction(crane.modelUuid);
|
||||
}
|
||||
|
||||
craneState.isProcessing = false;
|
||||
currentAction.callback();
|
||||
|
||||
setTimeout(() => {
|
||||
completeCurrentAction(craneState);
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
|
||||
return {
|
||||
addCraneToMonitor
|
||||
};
|
||||
}
|
||||
@@ -12,7 +12,7 @@ function PillarJibAnimator({
|
||||
onAnimationComplete
|
||||
}: {
|
||||
crane: CraneStatus;
|
||||
points: [THREE.Vector3, THREE.Vector3];
|
||||
points: [THREE.Vector3, THREE.Vector3] | null;
|
||||
animationPhase: string;
|
||||
setAnimationPhase: (phase: string) => void;
|
||||
onAnimationComplete: (action: string) => void;
|
||||
@@ -45,7 +45,7 @@ function PillarJibAnimator({
|
||||
const trolley = model.getObjectByName('trolley');
|
||||
const hook = model.getObjectByName('hook');
|
||||
|
||||
if (!base || !trolley || !hook) return;
|
||||
if (!base || !trolley || !hook || !points) return;
|
||||
|
||||
const baseWorld = new THREE.Vector3();
|
||||
base.getWorldPosition(baseWorld);
|
||||
|
||||
@@ -1,13 +1,34 @@
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import * as THREE from 'three'
|
||||
import { usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
|
||||
import PillarJibAnimator from '../animator/pillarJibAnimator'
|
||||
import PillarJibHelper from '../helper/pillarJibHelper'
|
||||
|
||||
function PillarJibInstance({ crane }: { crane: CraneStatus }) {
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { craneStore, productStore } = useSceneContext();
|
||||
const { getActionByUuid, getEventByModelUuid, getTriggerByUuid } = productStore();
|
||||
const { getCraneById } = craneStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const [currentPhase, setCurrentPhase] = useState<string>('idle');
|
||||
const [animationPhase, setAnimationPhase] = useState<string>('idle');
|
||||
const [points, setPoints] = useState<[THREE.Vector3, THREE.Vector3] | null>(null);
|
||||
|
||||
const position1: [number, number, number] = [5, 1, -4];
|
||||
const position2: [number, number, number] = [-2, 2, -2];
|
||||
useEffect(() => {
|
||||
if (isPlaying) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, crane?.currentAction?.actionUuid || '');
|
||||
if (!action || action.actionType !== 'pickAndDrop') return;
|
||||
|
||||
if (!crane.isActive && currentPhase === 'idle' && crane.currentMaterials.length > 0 && action.maxPickUpCount <= crane.currentMaterials.length) {
|
||||
console.log('crane: ', crane);
|
||||
|
||||
}
|
||||
}
|
||||
}, [crane, currentPhase])
|
||||
|
||||
const handleAnimationComplete = (action: string) => {
|
||||
if (action === 'picking') {
|
||||
@@ -27,10 +48,7 @@ function PillarJibInstance({ crane }: { crane: CraneStatus }) {
|
||||
<PillarJibAnimator
|
||||
key={crane.modelUuid}
|
||||
crane={crane}
|
||||
points={[
|
||||
new THREE.Vector3(...position1),
|
||||
new THREE.Vector3(...position2)
|
||||
]}
|
||||
points={points}
|
||||
animationPhase={animationPhase}
|
||||
setAnimationPhase={setAnimationPhase}
|
||||
onAnimationComplete={handleAnimationComplete}
|
||||
|
||||
Reference in New Issue
Block a user