import { useEffect, useRef } from "react"; import type { GameAudioManager } from "./audio.types"; import { GameAudioContext } from "./audioContext"; import { createAudioManager } from "./audioManager"; import type { GameAudioProviderProps } from "./GameAudioProvider.types"; import { createHowlerAudioEngine } from "./howlerEngine"; const activeManagers = new Set(); export function GameAudioProvider({ children, manager: injectedManager, }: GameAudioProviderProps) { const managerRef = useRef(null); if (!managerRef.current) { managerRef.current = injectedManager ?? createAudioManager({ engine: createHowlerAudioEngine() }); } const manager = managerRef.current; useEffect(() => { activeManagers.add(manager); const handleVisibilityChange = () => { manager.handleVisibilityChange(document.hidden); }; const handlePageHide = () => manager.stopAll(); document.addEventListener("visibilitychange", handleVisibilityChange); window.addEventListener("pagehide", handlePageHide); handleVisibilityChange(); return () => { document.removeEventListener("visibilitychange", handleVisibilityChange); window.removeEventListener("pagehide", handlePageHide); activeManagers.delete(manager); manager.stopAll(); }; }, [manager]); return ( {children} ); } if (import.meta.hot) { import.meta.hot.dispose(() => { for (const manager of activeManagers) manager.stopAll(); activeManagers.clear(); }); }