Template
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
54 lines
1.5 KiB
TypeScript
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();
|
|
});
|
|
}
|