import { onNextFrame, defaultTimestep } from "./on-next-frame";
import { createRenderStep } from "./create-render-step";
var maxElapsed = 40;
var useDefaultElapsed = true;
var runNextFrame = false;
var isProcessing = false;
var frame = {
    delta: 0,
    timestamp: 0,
};
var stepsOrder = [
    "read",
    "update",
    "preRender",
    "render",
    "postRender",
];
var steps = stepsOrder.reduce(function (acc, key) {
    acc[key] = createRenderStep(function () { return (runNextFrame = true); });
    return acc;
}, {});
var sync = stepsOrder.reduce(function (acc, key) {
    var step = steps[key];
    acc[key] = function (process, keepAlive, immediate) {
        if (keepAlive === void 0) { keepAlive = false; }
        if (immediate === void 0) { immediate = false; }
        if (!runNextFrame)
            startLoop();
        return step.schedule(process, keepAlive, immediate);
    };
    return acc;
}, {});
var cancelSync = stepsOrder.reduce(function (acc, key) {
    acc[key] = steps[key].cancel;
    return acc;
}, {});
var flushSync = stepsOrder.reduce(function (acc, key) {
    acc[key] = function () { return steps[key].process(frame); };
    return acc;
}, {});
var processStep = function (stepId) { return steps[stepId].process(frame); };
var processFrame = function (timestamp) {
    runNextFrame = false;
    frame.delta = useDefaultElapsed
        ? defaultTimestep
        : Math.max(Math.min(timestamp - frame.timestamp, maxElapsed), 1);
    frame.timestamp = timestamp;
    isProcessing = true;
    stepsOrder.forEach(processStep);
    isProcessing = false;
    if (runNextFrame) {
        useDefaultElapsed = false;
        onNextFrame(processFrame);
    }
};
var startLoop = function () {
    runNextFrame = true;
    useDefaultElapsed = true;
    if (!isProcessing)
        onNextFrame(processFrame);
};
var getFrameData = function () { return frame; };
export default sync;
export { cancelSync, flushSync, getFrameData };
//# sourceMappingURL=index.js.map