45 lines
1.1 KiB
TypeScript
45 lines
1.1 KiB
TypeScript
import { Director } from "./director";
|
|||
|
|
import { useOfficeStore } from "@/store/office-store";
|
||
|
|
import { liveConnect, liveDisconnect } from "@/gateway/live";
|
||
|
|
|
||
|
|
let director = new Director();
|
||
|
|
let running = false;
|
||
|
|
|
||
|
|
export function getDirector() {
|
||
|
|
return director;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Switch between the scripted simulation and the live transcript feed. */
|
||
|
|
export function setMode(mode: "sim" | "live") {
|
||
|
|
const S = useOfficeStore.getState();
|
||
|
|
if (S.mode === mode) return;
|
||
|
|
S.clearWorld();
|
||
|
|
S.setMode(mode);
|
||
|
|
if (mode === "sim") {
|
||
|
|
liveDisconnect();
|
||
|
|
director = new Director();
|
||
|
|
} else {
|
||
|
|
liveConnect();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Single rAF loop: advances the store clock/movements, then the director's FSMs. */
|
||
|
|
export function startRuntime() {
|
||
|
|
if (running) return;
|
||
|
|
running = true;
|
||
|
|
|
||
|
|
let last = performance.now();
|
||
|
|
const frame = (now: number) => {
|
||
|
|
const raw = Math.min((now - last) / 1000, 0.1);
|
||
|
|
last = now;
|
||
|
|
const S = useOfficeStore.getState();
|
||
|
|
if (!S.paused) {
|
||
|
|
const dt = raw * S.speed;
|
||
|
|
S.tick(dt);
|
||
|
|
if (S.mode === "sim") director.update(dt);
|
||
|
|
}
|
||
|
|
requestAnimationFrame(frame);
|
||
|
|
};
|
||
|
|
requestAnimationFrame(frame);
|
||
|
|
}
|