diff --git a/client/src/features/visualizer-threejs/VisualizerInstance.tsx b/client/src/features/visualizer-threejs/VisualizerInstance.tsx index b25b7cf27..9ac8a62dd 100644 --- a/client/src/features/visualizer-threejs/VisualizerInstance.tsx +++ b/client/src/features/visualizer-threejs/VisualizerInstance.tsx @@ -80,13 +80,13 @@ const VisualizerInstance: React.FC> = useEffect(() => { const handleVisibilityChange = async () => { if (document.hidden) { - await feedSubscriptionStop(); + await feedSubscriptionFinalize(); setIsPlaying(false); } }; const handleBlur = async () => { - await feedSubscriptionStop(); + await feedSubscriptionFinalize(); setIsPlaying(false); }; @@ -118,13 +118,9 @@ const VisualizerInstance: React.FC> = return; } - if (isPlaying) { - feedSubscriptionStart(); - } else { - await feedSubscriptionStop(); - } + feedSubscriptionStart(); })(); - }, [feedService, isPlaying, runListeners]); + }, [feedService, runListeners]); /** * Control width and height of canvas @@ -157,18 +153,46 @@ const VisualizerInstance: React.FC> = setRunListeners(false); setIsPlaying(false); resetConfigState(); - await feedSubscriptionStop(); + await feedSubscriptionFinalize(); setFeedService(ServiceFactory.get(`feed-${network}`)); })(); }, [network]); + useEffect(() => { + if (!runListeners) { + return; + } + setIsPlaying(true); + + return () => { + bpsCounter.stop(); + }; + }, [runListeners]); + + const feedSubscriptionStart = () => { + if (!feedService) { + return; + } + feedService.subscribeBlocks(onNewBlock, onBlockMetadataUpdate); + + bpsCounter.start(); + }; + + const feedSubscriptionFinalize = async () => { + if (!feedService) { + return; + } + await feedService.unsubscribeBlocks(); + bpsCounter.reset(); + }; + /** * Subscribe to updates * @param blockData The new block data */ const onNewBlock = (blockData: IFeedBlockData) => { const emitterObj = emitterRef.current; - if (emitterObj && blockData) { + if (emitterObj && blockData && isPlaying) { const emitterBox = new Box3().setFromObject(emitterObj); const emitterCenter = new THREE.Vector3(); @@ -220,33 +244,6 @@ const VisualizerInstance: React.FC> = } } - useEffect(() => { - if (!runListeners) { - return; - } - setIsPlaying(true); - - return () => { - bpsCounter.stop(); - }; - }, [runListeners]); - - const feedSubscriptionStart = () => { - if (!feedService) { - return; - } - feedService.subscribeBlocks(onNewBlock, onBlockMetadataUpdate); - bpsCounter.start(); - }; - - const feedSubscriptionStop = async () => { - if (!feedService) { - return; - } - await feedService.unsubscribeBlocks(); - bpsCounter.reset(); - }; - return ( []; addToColorQueue: (blockId: string, color: Color) => void; - removeFromColorQueue: (blockId: string) => void; + removeFromColorQueue: (blockIds: string[]) => void; // Map of blockId to index in Tangle 'InstancedMesh' blockIdToIndex: Map; @@ -155,11 +155,13 @@ export const useTangleStore = create()( colorQueue: [...state.colorQueue, { id, color }], })); }, - removeFromColorQueue: (blockId: string) => { - set((state) => ({ - ...state, - colorQueue: state.colorQueue.filter((block) => block.id !== blockId), - })); + removeFromColorQueue: (blockIds) => { + if (blockIds.length > 0) { + set((state) => ({ + ...state, + colorQueue: state.colorQueue.filter((block) => !blockIds.includes(block.id)), + })); + } }, updateBlockIdToIndex: (blockId: string, index: number) => { set((state) => { diff --git a/client/src/features/visualizer-threejs/useRenderTangle.tsx b/client/src/features/visualizer-threejs/useRenderTangle.tsx index 092429ede..4e6e93604 100644 --- a/client/src/features/visualizer-threejs/useRenderTangle.tsx +++ b/client/src/features/visualizer-threejs/useRenderTangle.tsx @@ -28,18 +28,6 @@ export const useRenderTangle = () => { const blockIdToPosition = useTangleStore((s) => s.blockIdToPosition); const blockIdToAnimationPosition = useTangleStore((s) => s.blockIdToAnimationPosition); - const updateBlockColor = (blockId: string, color: THREE.Color): void => { - const indexToUpdate = blockIdToIndex.get(blockId); - - if (indexToUpdate) { - tangleMeshRef.current.setColorAt(indexToUpdate, color); - if (tangleMeshRef.current.instanceColor) { - tangleMeshRef.current.instanceColor.needsUpdate = true; - } - removeFromColorQueue(blockId); - } - }; - function updateInstancedMeshPosition( instancedMesh: THREE.InstancedMesh, index: number, @@ -175,12 +163,23 @@ export const useRenderTangle = () => { }, [blockQueue, blockIdToAnimationPosition]); useEffect(() => { - if (colorQueue.length === 0) { - return; - } + if (colorQueue.length > 0) { + const removeIds: string[] = []; + for (const { id, color } of colorQueue) { + const indexToUpdate = blockIdToIndex.get(id); + + if (indexToUpdate) { + tangleMeshRef.current.setColorAt(indexToUpdate, color); + + if (tangleMeshRef.current.instanceColor) { + tangleMeshRef.current.instanceColor.needsUpdate = true; + } + + removeIds.push(id); + } + } - for (const { id, color } of colorQueue) { - updateBlockColor(id, color); + removeFromColorQueue(removeIds); } - }, [colorQueue]); + }, [colorQueue, blockIdToIndex]); };