Files
yx-react-template/src/utils/audio/GameAudioProvider.tsx
T
2026-09-08 14:07:42 +08:00

54 lines
1.5 KiB
TypeScript

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<GameAudioManager>();
export function GameAudioProvider({
children,
manager: injectedManager,
}: GameAudioProviderProps) {
const managerRef = useRef<GameAudioManager | null>(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 (
<GameAudioContext.Provider value={manager}>
{children}
</GameAudioContext.Provider>
);
}
if (import.meta.hot) {
import.meta.hot.dispose(() => {
for (const manager of activeManagers) manager.stopAll();
activeManagers.clear();
});
}