{"version":3,"file":"Ticker.mjs","sources":["../../src/ticker/Ticker.ts"],"sourcesContent":["import { UPDATE_PRIORITY } from './const';\nimport { TickerListener } from './TickerListener';\n\n/**\n * A callback which can be added to a ticker.\n * ```js\n * ticker.add(() => {\n *    // do something every frame\n * });\n * ```\n * @memberof ticker\n */\nexport type TickerCallback<T> = (this: T, ticker: Ticker) => any;\n\n/**\n * {@link ticker.Ticker|Tickers} provide periodic callbacks based on the system clock.\n * Your game update logic will generally be run in response to a tick once per frame.\n * You can have multiple tickers in use at one time.\n * ```js\n * import { Ticker } from 'pixi.js';\n *\n * const callback = (ticker: Ticker) => {\n *    // do something on the next animation frame\n * };\n *\n * // create a ticker\n * const ticker = new Ticker();\n *\n * // register the callback and start the ticker\n * ticker.add(callback);\n * ticker.start();\n * ```\n *\n * You can always use the {@link ticker.Ticker.shared|shared} ticker that Pixi renders with by default.\n * ```js\n * Ticker.shared.add(callback);\n * ```\n * @namespace ticker\n */\n\n/**\n * A Ticker class that runs an update loop that other objects listen to.\n *\n * This class is composed around listeners meant for execution on the next requested animation frame.\n * Animation frames are requested only when necessary, e.g. When the ticker is started and the emitter has listeners.\n * @class\n * @memberof ticker\n */\nexport class Ticker\n{\n    /**\n     * Target frames per millisecond.\n     * @static\n     */\n    public static targetFPMS = 0.06;\n\n    /** The private shared ticker instance */\n    private static _shared: Ticker;\n    /** The private system ticker instance  */\n    private static _system: Ticker;\n\n    /**\n     * Whether or not this ticker should invoke the method\n     * {@link ticker.Ticker#start|start} automatically when a listener is added.\n     */\n    public autoStart = false;\n    /**\n     * Scalar time value from last frame to this frame.\n     * This value is capped by setting {@link ticker.Ticker#minFPS|minFPS}\n     * and is scaled with {@link ticker.Ticker#speed|speed}.\n     * **Note:** The cap may be exceeded by scaling.\n     */\n    public deltaTime = 1;\n    /**\n     * Scaler time elapsed in milliseconds from last frame to this frame.\n     * This value is capped by setting {@link ticker.Ticker#minFPS|minFPS}\n     * and is scaled with {@link ticker.Ticker#speed|speed}.\n     * **Note:** The cap may be exceeded by scaling.\n     * If the platform supports DOMHighResTimeStamp,\n     * this value will have a precision of 1 µs.\n     * Defaults to target frame time\n     * @default 16.66\n     */\n    public deltaMS: number;\n    /**\n     * Time elapsed in milliseconds from last frame to this frame.\n     * Opposed to what the scalar {@link ticker.Ticker#deltaTime|deltaTime}\n     * is based, this value is neither capped nor scaled.\n     * If the platform supports DOMHighResTimeStamp,\n     * this value will have a precision of 1 µs.\n     * Defaults to target frame time\n     * @default 16.66\n     */\n    public elapsedMS: number;\n    /**\n     * The last time {@link ticker.Ticker#update|update} was invoked.\n     * This value is also reset internally outside of invoking\n     * update, but only when a new animation frame is requested.\n     * If the platform supports DOMHighResTimeStamp,\n     * this value will have a precision of 1 µs.\n     */\n    public lastTime = -1;\n    /**\n     * Factor of current {@link ticker.Ticker#deltaTime|deltaTime}.\n     * @example\n     * // Scales ticker.deltaTime to what would be\n     * // the equivalent of approximately 120 FPS\n     * ticker.speed = 2;\n     */\n    public speed = 1;\n    /**\n     * Whether or not this ticker has been started.\n     * `true` if {@link ticker.Ticker#start|start} has been called.\n     * `false` if {@link ticker.Ticker#stop|Stop} has been called.\n     * While `false`, this value may change to `true` in the\n     * event of {@link ticker.Ticker#autoStart|autoStart} being `true`\n     * and a listener is added.\n     */\n    public started = false;\n\n    /** The first listener. All new listeners added are chained on this. */\n    private _head: TickerListener;\n    /** Internal current frame request ID */\n    private _requestId: number = null;\n    /**\n     * Internal value managed by minFPS property setter and getter.\n     * This is the maximum allowed milliseconds between updates.\n     */\n    private _maxElapsedMS = 100;\n    /**\n     * Internal value managed by minFPS property setter and getter.\n     * This is the minimum allowed milliseconds between updates.\n     */\n    private _minElapsedMS = 0;\n    /** If enabled, deleting is disabled.*/\n    private _protected = false;\n    /** The last time keyframe was executed. Maintains a relatively fixed interval with the previous value. */\n    private _lastFrame = -1;\n    /**\n     * Internal tick method bound to ticker instance.\n     * This is because in early 2015, Function.bind\n     * is still 60% slower in high performance scenarios.\n     * Also separating frame requests from update method\n     * so listeners may be called at any time and with\n     * any animation API, just invoke ticker.update(time).\n     * @param time - Time since last tick.\n     */\n    private readonly _tick: (time: number) => any;\n\n    constructor()\n    {\n        this._head = new TickerListener(null, null, Infinity);\n        this.deltaMS = 1 / Ticker.targetFPMS;\n        this.elapsedMS = 1 / Ticker.targetFPMS;\n\n        this._tick = (time: number): void =>\n        {\n            this._requestId = null;\n\n            if (this.started)\n            {\n                // Invoke listeners now\n                this.update(time);\n                // Listener side effects may have modified ticker state.\n                if (this.started && this._requestId === null && this._head.next)\n                {\n                    this._requestId = requestAnimationFrame(this._tick);\n                }\n            }\n        };\n    }\n\n    /**\n     * Conditionally requests a new animation frame.\n     * If a frame has not already been requested, and if the internal\n     * emitter has listeners, a new frame is requested.\n     * @private\n     */\n    private _requestIfNeeded(): void\n    {\n        if (this._requestId === null && this._head.next)\n        {\n            // ensure callbacks get correct delta\n            this.lastTime = performance.now();\n            this._lastFrame = this.lastTime;\n            this._requestId = requestAnimationFrame(this._tick);\n        }\n    }\n\n    /**\n     * Conditionally cancels a pending animation frame.\n     * @private\n     */\n    private _cancelIfNeeded(): void\n    {\n        if (this._requestId !== null)\n        {\n            cancelAnimationFrame(this._requestId);\n            this._requestId = null;\n        }\n    }\n\n    /**\n     * Conditionally requests a new animation frame.\n     * If the ticker has been started it checks if a frame has not already\n     * been requested, and if the internal emitter has listeners. If these\n     * conditions are met, a new frame is requested. If the ticker has not\n     * been started, but autoStart is `true`, then the ticker starts now,\n     * and continues with the previous conditions to request a new frame.\n     * @private\n     */\n    private _startIfPossible(): void\n    {\n        if (this.started)\n        {\n            this._requestIfNeeded();\n        }\n        else if (this.autoStart)\n        {\n            this.start();\n        }\n    }\n\n    /**\n     * Register a handler for tick events. Calls continuously unless\n     * it is removed or the ticker is stopped.\n     * @param fn - The listener function to be added for updates\n     * @param context - The listener context\n     * @param {number} [priority=UPDATE_PRIORITY.NORMAL] - The priority for emitting\n     * @returns This instance of a ticker\n     */\n    public add<T = any>(fn: TickerCallback<T>, context?: T, priority: number = UPDATE_PRIORITY.NORMAL): this\n    {\n        return this._addListener(new TickerListener(fn, context, priority));\n    }\n\n    /**\n     * Add a handler for the tick event which is only execute once.\n     * @param fn - The listener function to be added for one update\n     * @param context - The listener context\n     * @param {number} [priority=UPDATE_PRIORITY.NORMAL] - The priority for emitting\n     * @returns This instance of a ticker\n     */\n    public addOnce<T = any>(fn: TickerCallback<T>, context?: T, priority: number = UPDATE_PRIORITY.NORMAL): this\n    {\n        return this._addListener(new TickerListener(fn, context, priority, true));\n    }\n\n    /**\n     * Internally adds the event handler so that it can be sorted by priority.\n     * Priority allows certain handler (user, AnimatedSprite, Interaction) to be run\n     * before the rendering.\n     * @private\n     * @param listener - Current listener being added.\n     * @returns This instance of a ticker\n     */\n    private _addListener(listener: TickerListener): this\n    {\n        // For attaching to head\n        let current = this._head.next;\n        let previous = this._head;\n\n        // Add the first item\n        if (!current)\n        {\n            listener.connect(previous);\n        }\n        else\n        {\n            // Go from highest to lowest priority\n            while (current)\n            {\n                if (listener.priority > current.priority)\n                {\n                    listener.connect(previous);\n                    break;\n                }\n                previous = current;\n                current = current.next;\n            }\n\n            // Not yet connected\n            if (!listener.previous)\n            {\n                listener.connect(previous);\n            }\n        }\n\n        this._startIfPossible();\n\n        return this;\n    }\n\n    /**\n     * Removes any handlers matching the function and context parameters.\n     * If no handlers are left after removing, then it cancels the animation frame.\n     * @param fn - The listener function to be removed\n     * @param context - The listener context to be removed\n     * @returns This instance of a ticker\n     */\n    public remove<T = any>(fn: TickerCallback<T>, context?: T): this\n    {\n        let listener = this._head.next;\n\n        while (listener)\n        {\n            // We found a match, lets remove it\n            // no break to delete all possible matches\n            // incase a listener was added 2+ times\n            if (listener.match(fn, context))\n            {\n                listener = listener.destroy();\n            }\n            else\n            {\n                listener = listener.next;\n            }\n        }\n\n        if (!this._head.next)\n        {\n            this._cancelIfNeeded();\n        }\n\n        return this;\n    }\n\n    /**\n     * The number of listeners on this ticker, calculated by walking through linked list\n     * @readonly\n     * @member {number}\n     */\n    get count(): number\n    {\n        if (!this._head)\n        {\n            return 0;\n        }\n\n        let count = 0;\n        let current = this._head;\n\n        while ((current = current.next))\n        {\n            count++;\n        }\n\n        return count;\n    }\n\n    /** Starts the ticker. If the ticker has listeners a new animation frame is requested at this point. */\n    public start(): void\n    {\n        if (!this.started)\n        {\n            this.started = true;\n            this._requestIfNeeded();\n        }\n    }\n\n    /** Stops the ticker. If the ticker has requested an animation frame it is canceled at this point. */\n    public stop(): void\n    {\n        if (this.started)\n        {\n            this.started = false;\n            this._cancelIfNeeded();\n        }\n    }\n\n    /** Destroy the ticker and don't use after this. Calling this method removes all references to internal events. */\n    public destroy(): void\n    {\n        if (!this._protected)\n        {\n            this.stop();\n\n            let listener = this._head.next;\n\n            while (listener)\n            {\n                listener = listener.destroy(true);\n            }\n\n            this._head.destroy();\n            this._head = null;\n        }\n    }\n\n    /**\n     * Triggers an update. An update entails setting the\n     * current {@link ticker.Ticker#elapsedMS|elapsedMS},\n     * the current {@link ticker.Ticker#deltaTime|deltaTime},\n     * invoking all listeners with current deltaTime,\n     * and then finally setting {@link ticker.Ticker#lastTime|lastTime}\n     * with the value of currentTime that was provided.\n     * This method will be called automatically by animation\n     * frame callbacks if the ticker instance has been started\n     * and listeners are added.\n     * @param {number} [currentTime=performance.now()] - the current time of execution\n     */\n    public update(currentTime: number = performance.now()): void\n    {\n        let elapsedMS;\n\n        // If the difference in time is zero or negative, we ignore most of the work done here.\n        // If there is no valid difference, then should be no reason to let anyone know about it.\n        // A zero delta, is exactly that, nothing should update.\n        //\n        // The difference in time can be negative, and no this does not mean time traveling.\n        // This can be the result of a race condition between when an animation frame is requested\n        // on the current JavaScript engine event loop, and when the ticker's start method is invoked\n        // (which invokes the internal _requestIfNeeded method). If a frame is requested before\n        // _requestIfNeeded is invoked, then the callback for the animation frame the ticker requests,\n        // can receive a time argument that can be less than the lastTime value that was set within\n        // _requestIfNeeded. This difference is in microseconds, but this is enough to cause problems.\n        //\n        // This check covers this browser engine timing issue, as well as if consumers pass an invalid\n        // currentTime value. This may happen if consumers opt-out of the autoStart, and update themselves.\n\n        if (currentTime > this.lastTime)\n        {\n            // Save uncapped elapsedMS for measurement\n            elapsedMS = this.elapsedMS = currentTime - this.lastTime;\n\n            // cap the milliseconds elapsed used for deltaTime\n            if (elapsedMS > this._maxElapsedMS)\n            {\n                elapsedMS = this._maxElapsedMS;\n            }\n\n            elapsedMS *= this.speed;\n\n            // If not enough time has passed, exit the function.\n            // Get ready for next frame by setting _lastFrame, but based on _minElapsedMS\n            // adjustment to ensure a relatively stable interval.\n            if (this._minElapsedMS)\n            {\n                const delta = currentTime - this._lastFrame | 0;\n\n                if (delta < this._minElapsedMS)\n                {\n                    return;\n                }\n\n                this._lastFrame = currentTime - (delta % this._minElapsedMS);\n            }\n\n            this.deltaMS = elapsedMS;\n            this.deltaTime = this.deltaMS * Ticker.targetFPMS;\n\n            // Cache a local reference, in-case ticker is destroyed\n            // during the emit, we can still check for head.next\n            const head = this._head;\n\n            // Invoke listeners added to internal emitter\n            let listener = head.next;\n\n            while (listener)\n            {\n                listener = listener.emit(this);\n            }\n\n            if (!head.next)\n            {\n                this._cancelIfNeeded();\n            }\n        }\n        else\n        {\n            this.deltaTime = this.deltaMS = this.elapsedMS = 0;\n        }\n\n        this.lastTime = currentTime;\n    }\n\n    /**\n     * The frames per second at which this ticker is running.\n     * The default is approximately 60 in most modern browsers.\n     * **Note:** This does not factor in the value of\n     * {@link ticker.Ticker#speed|speed}, which is specific\n     * to scaling {@link ticker.Ticker#deltaTime|deltaTime}.\n     * @member {number}\n     * @readonly\n     */\n    get FPS(): number\n    {\n        return 1000 / this.elapsedMS;\n    }\n\n    /**\n     * Manages the maximum amount of milliseconds allowed to\n     * elapse between invoking {@link ticker.Ticker#update|update}.\n     * This value is used to cap {@link ticker.Ticker#deltaTime|deltaTime},\n     * but does not effect the measured value of {@link ticker.Ticker#FPS|FPS}.\n     * When setting this property it is clamped to a value between\n     * `0` and `Ticker.targetFPMS * 1000`.\n     * @member {number}\n     * @default 10\n     */\n    get minFPS(): number\n    {\n        return 1000 / this._maxElapsedMS;\n    }\n\n    set minFPS(fps: number)\n    {\n        // Minimum must be below the maxFPS\n        const minFPS = Math.min(this.maxFPS, fps);\n\n        // Must be at least 0, but below 1 / Ticker.targetFPMS\n        const minFPMS = Math.min(Math.max(0, minFPS) / 1000, Ticker.targetFPMS);\n\n        this._maxElapsedMS = 1 / minFPMS;\n    }\n\n    /**\n     * Manages the minimum amount of milliseconds required to\n     * elapse between invoking {@link ticker.Ticker#update|update}.\n     * This will effect the measured value of {@link ticker.Ticker#FPS|FPS}.\n     * If it is set to `0`, then there is no limit; PixiJS will render as many frames as it can.\n     * Otherwise it will be at least `minFPS`\n     * @member {number}\n     * @default 0\n     */\n    get maxFPS(): number\n    {\n        if (this._minElapsedMS)\n        {\n            return Math.round(1000 / this._minElapsedMS);\n        }\n\n        return 0;\n    }\n\n    set maxFPS(fps: number)\n    {\n        if (fps === 0)\n        {\n            this._minElapsedMS = 0;\n        }\n        else\n        {\n            // Max must be at least the minFPS\n            const maxFPS = Math.max(this.minFPS, fps);\n\n            this._minElapsedMS = 1 / (maxFPS / 1000);\n        }\n    }\n\n    /**\n     * The shared ticker instance used by {@link AnimatedSprite} and by\n     * {@link VideoResource} to update animation frames / video textures.\n     *\n     * It may also be used by {@link Application} if created with the `sharedTicker` option property set to true.\n     *\n     * The property {@link ticker.Ticker#autoStart|autoStart} is set to `true` for this instance.\n     * Please follow the examples for usage, including how to opt-out of auto-starting the shared ticker.\n     * @example\n     * import { Ticker } from 'pixi.js';\n     *\n     * const ticker = Ticker.shared;\n     * // Set this to prevent starting this ticker when listeners are added.\n     * // By default this is true only for the Ticker.shared instance.\n     * ticker.autoStart = false;\n     *\n     * // FYI, call this to ensure the ticker is stopped. It should be stopped\n     * // if you have not attempted to render anything yet.\n     * ticker.stop();\n     *\n     * // Call this when you are ready for a running shared ticker.\n     * ticker.start();\n     * @example\n     * import { autoDetectRenderer, Container } from 'pixi.js';\n     *\n     * // You may use the shared ticker to render...\n     * const renderer = autoDetectRenderer();\n     * const stage = new Container();\n     * document.body.appendChild(renderer.view);\n     * ticker.add((time) => renderer.render(stage));\n     *\n     * // Or you can just update it manually.\n     * ticker.autoStart = false;\n     * ticker.stop();\n     * const animate = (time) => {\n     *     ticker.update(time);\n     *     renderer.render(stage);\n     *     requestAnimationFrame(animate);\n     * };\n     * animate(performance.now());\n     * @member {ticker.Ticker}\n     * @readonly\n     * @static\n     */\n    static get shared(): Ticker\n    {\n        if (!Ticker._shared)\n        {\n            const shared = Ticker._shared = new Ticker();\n\n            shared.autoStart = true;\n            shared._protected = true;\n        }\n\n        return Ticker._shared;\n    }\n\n    /**\n     * The system ticker instance used by {@link BasePrepare} for core timing\n     * functionality that shouldn't usually need to be paused, unlike the `shared`\n     * ticker which drives visual animations and rendering which may want to be paused.\n     *\n     * The property {@link ticker.Ticker#autoStart|autoStart} is set to `true` for this instance.\n     * @member {ticker.Ticker}\n     * @readonly\n     * @static\n     */\n    static get system(): Ticker\n    {\n        if (!Ticker._system)\n        {\n            const system = Ticker._system = new Ticker();\n\n            system.autoStart = true;\n            system._protected = true;\n        }\n\n        return Ticker._system;\n    }\n}\n"],"names":[],"mappings":"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"}