import { FixedStepAccumulator } from "./FixedStepAccumulator.js";
import { Time } from "./Time.js";
export class EngineLoop {
    options;
    onFrame;
    time;
    accumulator;
    running = false;
    rafHandle;
    lastTimestamp;
    constructor(options, onFrame) {
        this.options = options;
        this.onFrame = onFrame;
        this.time = new Time(options.maxDelta, options.timeScale ?? 1);
        this.accumulator = new FixedStepAccumulator(options.fixedDelta, options.maxFixedSteps);
    }
    start() {
        if (this.running)
            return;
        this.running = true;
        if (this.options.mode === "raf") {
            if (typeof requestAnimationFrame !== "function")
                throw new Error("requestAnimationFrame is unavailable.");
            this.lastTimestamp = undefined;
            this.rafHandle = requestAnimationFrame((timestamp) => void this.tickRaf(timestamp));
        }
    }
    stop() {
        if (!this.running)
            return;
        this.running = false;
        if (this.rafHandle !== undefined && typeof cancelAnimationFrame === "function") {
            cancelAnimationFrame(this.rafHandle);
        }
        this.rafHandle = undefined;
    }
    pause() {
        this.stop();
    }
    resume() {
        this.start();
    }
    async step(delta) {
        const time = this.time.update(delta);
        const fixed = this.accumulator.add(time.delta);
        const context = Object.freeze({ time, fixedSteps: fixed.steps, interpolationAlpha: fixed.alpha });
        await this.onFrame(context);
        return context;
    }
    snapshot() {
        return this.time.snapshot();
    }
    async tickRaf(timestamp) {
        if (!this.running)
            return;
        const delta = this.lastTimestamp === undefined ? 0 : (timestamp - this.lastTimestamp) / 1000;
        this.lastTimestamp = timestamp;
        await this.step(delta);
        if (this.running)
            this.rafHandle = requestAnimationFrame((nextTimestamp) => void this.tickRaf(nextTimestamp));
    }
}
//# sourceMappingURL=EngineLoop.js.map