68 lines
2.5 KiB
TypeScript
68 lines
2.5 KiB
TypeScript
import { useCombatStore } from "../game/combatStore";
|
|
import { useGameStore } from "../game/store";
|
|
import { usePartyStore } from "../game/partyStore";
|
|
import { useShellStore } from "../app/shellStore";
|
|
import { emitControllerToken, setExternalControllerMovement } from "../input/controller";
|
|
import { currentCompanionSnapshot, executeCompanionCommand, type DualScreenMessage } from "./dualScreenSync";
|
|
import { createRateLimitedPublisher } from "./rateLimitedPublisher";
|
|
import { useUiLayoutStore } from "../game/uiLayoutStore";
|
|
import { useDpsMeterStore } from "../game/dpsMeterStore";
|
|
|
|
export function connectAuthoritativeDualScreen(
|
|
channel: BroadcastChannel,
|
|
initialMessage: MessageEvent<DualScreenMessage>,
|
|
): () => void {
|
|
let companionReady = initialMessage.data.type === "companion-ready";
|
|
const publish = () => channel.postMessage({
|
|
type: "app-state",
|
|
snapshot: currentCompanionSnapshot(),
|
|
} satisfies DualScreenMessage);
|
|
const gamePublisher = createRateLimitedPublisher(() => {
|
|
if (companionReady) publish();
|
|
}, 100);
|
|
const unsubscribeShell = useShellStore.subscribe(() => {
|
|
if (companionReady) publish();
|
|
});
|
|
const unsubscribeGame = useGameStore.subscribe(() => {
|
|
if (companionReady) gamePublisher.request();
|
|
});
|
|
const unsubscribeCombat = useCombatStore.subscribe(() => {
|
|
if (companionReady) gamePublisher.request();
|
|
});
|
|
const unsubscribeParty = usePartyStore.subscribe(() => {
|
|
if (companionReady) gamePublisher.request();
|
|
});
|
|
const unsubscribeUi = useUiLayoutStore.subscribe(() => {
|
|
if (companionReady) gamePublisher.request();
|
|
});
|
|
const unsubscribeDps = useDpsMeterStore.subscribe(() => {
|
|
if (companionReady) gamePublisher.request();
|
|
});
|
|
channel.onmessage = (event: MessageEvent<DualScreenMessage>) => {
|
|
if (event.data.type === "companion-ready") {
|
|
companionReady = true;
|
|
publish();
|
|
} else if (event.data.type === "companion-closing") {
|
|
companionReady = false;
|
|
gamePublisher.cancel();
|
|
} else if (event.data.type === "command") {
|
|
executeCompanionCommand(event.data.command);
|
|
publish();
|
|
} else if (event.data.type === "controller-token") {
|
|
emitControllerToken(event.data.event);
|
|
} else if (event.data.type === "controller-motion") {
|
|
setExternalControllerMovement(event.data.movement);
|
|
}
|
|
};
|
|
if (companionReady) publish();
|
|
return () => {
|
|
unsubscribeShell();
|
|
unsubscribeGame();
|
|
unsubscribeCombat();
|
|
unsubscribeParty();
|
|
unsubscribeUi();
|
|
unsubscribeDps();
|
|
gamePublisher.dispose();
|
|
};
|
|
}
|