| 1 |
- {"version":3,"file":"ticker.min.mjs","sources":["../../src/const.ts","../../src/settings.ts","../../src/TickerListener.ts","../../src/Ticker.ts","../../src/TickerPlugin.ts"],"sourcesContent":["/**\n * Represents the update priorities used by internal PIXI classes when registered with\n * the {@link PIXI.Ticker} object. Higher priority items are updated first and lower\n * priority items, such as render, should go later.\n * @static\n * @constant\n * @name UPDATE_PRIORITY\n * @memberof PIXI\n * @enum {number}\n * @property {number} [INTERACTION=50] Highest priority, used for {@link PIXI.InteractionManager}\n * @property {number} [HIGH=25] High priority updating, {@link PIXI.VideoBaseTexture} and {@link PIXI.AnimatedSprite}\n * @property {number} [NORMAL=0] Default priority for ticker events, see {@link PIXI.Ticker#add}.\n * @property {number} [LOW=-25] Low priority used for {@link PIXI.Application} rendering.\n * @property {number} [UTILITY=-50] Lowest priority used for {@link PIXI.BasePrepare} utility.\n */\nexport enum UPDATE_PRIORITY\n// eslint-disable-next-line @typescript-eslint/indent\n{\n INTERACTION = 50,\n HIGH = 25,\n NORMAL = 0,\n LOW = -25,\n UTILITY = -50,\n}\n","import { settings } from '@pixi/settings';\n\n/**\n * Target frames per millisecond.\n * @static\n * @name TARGET_FPMS\n * @memberof PIXI.settings\n * @type {number}\n * @default 0.06\n */\nsettings.TARGET_FPMS = 0.06;\n\nexport { settings };\n","import type { TickerCallback } from './Ticker';\n\n/**\n * Internal class for handling the priority sorting of ticker handlers.\n * @private\n * @class\n * @memberof PIXI\n */\nexport class TickerListener<T = any>\n{\n /** The current priority. */\n public priority: number;\n /** The next item in chain. */\n public next: TickerListener = null;\n /** The previous item in chain. */\n public previous: TickerListener = null;\n\n /** The handler function to execute. */\n private fn: TickerCallback<T>;\n /** The calling to execute. */\n private context: T;\n /** If this should only execute once. */\n private once: boolean;\n /** `true` if this listener has been destroyed already. */\n private _destroyed = false;\n\n /**\n * Constructor\n * @private\n * @param fn - The listener function to be added for one update\n * @param context - The listener context\n * @param priority - The priority for emitting\n * @param once - If the handler should fire once\n */\n constructor(fn: TickerCallback<T>, context: T = null, priority = 0, once = false)\n {\n this.fn = fn;\n this.context = context;\n this.priority = priority;\n this.once = once;\n }\n\n /**\n * Simple compare function to figure out if a function and context match.\n * @private\n * @param fn - The listener function to be added for one update\n * @param context - The listener context\n * @returns `true` if the listener match the arguments\n */\n match(fn: TickerCallback<T>, context: any = null): boolean\n {\n return this.fn === fn && this.context === context;\n }\n\n /**\n * Emit by calling the current function.\n * @private\n * @param deltaTime - time since the last emit.\n * @returns Next ticker\n */\n emit(deltaTime: number): TickerListener\n {\n if (this.fn)\n {\n if (this.context)\n {\n this.fn.call(this.context, deltaTime);\n }\n else\n {\n (this as TickerListener<any>).fn(deltaTime);\n }\n }\n\n const redirect = this.next;\n\n if (this.once)\n {\n this.destroy(true);\n }\n\n // Soft-destroying should remove\n // the next reference\n if (this._destroyed)\n {\n this.next = null;\n }\n\n return redirect;\n }\n\n /**\n * Connect to the list.\n * @private\n * @param previous - Input node, previous listener\n */\n connect(previous: TickerListener): void\n {\n this.previous = previous;\n if (previous.next)\n {\n previous.next.previous = this;\n }\n this.next = previous.next;\n previous.next = this;\n }\n\n /**\n * Destroy and don't use after this.\n * @private\n * @param hard - `true` to remove the `next` reference, this\n * is considered a hard destroy. Soft destroy maintains the next reference.\n * @returns The listener to redirect while emitting or removing.\n */\n destroy(hard = false): TickerListener\n {\n this._destroyed = true;\n this.fn = null;\n this.context = null;\n\n // Disconnect, hook up next and previous\n if (this.previous)\n {\n this.previous.next = this.next;\n }\n\n if (this.next)\n {\n this.next.previous = this.previous;\n }\n\n // Redirect to the next item\n const redirect = this.next;\n\n // Remove references\n this.next = hard ? null : redirect;\n this.previous = null;\n\n return redirect;\n }\n}\n","import { settings } from './settings';\nimport { UPDATE_PRIORITY } from './const';\nimport { TickerListener } from './TickerListener';\n\nexport type TickerCallback<T> = (this: T, dt: number) => any;\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 PIXI\n */\nexport class Ticker\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 PIXI.Ticker#start} automatically\n * 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 PIXI.Ticker#minFPS}\n * and is scaled with {@link PIXI.Ticker#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 PIXI.Ticker#minFPS}\n * and is scaled with {@link PIXI.Ticker#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 PIXI.Ticker#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 PIXI.Ticker#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 PIXI.Ticker#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 PIXI.Ticker#start} has been called.\n * `false` if {@link PIXI.Ticker#stop} has been called.\n * While `false`, this value may change to `true` in the\n * event of {@link PIXI.Ticker#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 _tick: (time: number) => any;\n\n constructor()\n {\n this._head = new TickerListener(null, null, Infinity);\n this.deltaMS = 1 / settings.TARGET_FPMS;\n this.elapsedMS = 1 / settings.TARGET_FPMS;\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=PIXI.UPDATE_PRIORITY.NORMAL] - The priority for emitting\n * @returns This instance of a ticker\n */\n add<T = any>(fn: TickerCallback<T>, context?: T, priority = 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=PIXI.UPDATE_PRIORITY.NORMAL] - The priority for emitting\n * @returns This instance of a ticker\n */\n addOnce<T = any>(fn: TickerCallback<T>, context?: T, priority = 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 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 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 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 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 PIXI.Ticker#elapsedMS},\n * the current {@link PIXI.Ticker#deltaTime},\n * invoking all listeners with current deltaTime,\n * and then finally setting {@link PIXI.Ticker#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 update(currentTime = 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 * settings.TARGET_FPMS;\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.deltaTime);\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 PIXI.Ticker#speed}, which is specific\n * to scaling {@link PIXI.Ticker#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 PIXI.Ticker#update}.\n * This value is used to cap {@link PIXI.Ticker#deltaTime},\n * but does not effect the measured value of {@link PIXI.Ticker#FPS}.\n * When setting this property it is clamped to a value between\n * `0` and `PIXI.settings.TARGET_FPMS * 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 / settings.TARGET_FPMS\n const minFPMS = Math.min(Math.max(0, minFPS) / 1000, settings.TARGET_FPMS);\n\n this._maxElapsedMS = 1 / minFPMS;\n }\n\n /**\n * Manages the minimum amount of milliseconds required to\n * elapse between invoking {@link PIXI.Ticker#update}.\n * This will effect the measured value of {@link PIXI.Ticker#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 PIXI.AnimatedSprite} and by\n * {@link PIXI.VideoResource} to update animation frames / video textures.\n *\n * It may also be used by {@link PIXI.Application} if created with the `sharedTicker` option property set to true.\n *\n * The property {@link PIXI.Ticker#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 * let ticker = PIXI.Ticker.shared;\n * // Set this to prevent starting this ticker when listeners are added.\n * // By default this is true only for the PIXI.Ticker.shared instance.\n * ticker.autoStart = false;\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 * // Call this when you are ready for a running shared ticker.\n * ticker.start();\n * @example\n * // You may use the shared ticker to render...\n * let renderer = PIXI.autoDetectRenderer();\n * let stage = new PIXI.Container();\n * document.body.appendChild(renderer.view);\n * ticker.add(function (time) {\n * renderer.render(stage);\n * });\n * @example\n * // Or you can just update it manually.\n * ticker.autoStart = false;\n * ticker.stop();\n * function animate(time) {\n * ticker.update(time);\n * renderer.render(stage);\n * requestAnimationFrame(animate);\n * }\n * animate(performance.now());\n * @member {PIXI.Ticker}\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 PIXI.InteractionManager} and by\n * {@link PIXI.BasePrepare} for core timing functionality that shouldn't usually need to be paused,\n * unlike the `shared` ticker which drives visual animations and rendering which may want to be paused.\n *\n * The property {@link PIXI.Ticker#autoStart} is set to `true` for this instance.\n * @member {PIXI.Ticker}\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","import type { ExtensionMetadata } from '@pixi/extensions';\nimport { ExtensionType } from '@pixi/extensions';\nimport { UPDATE_PRIORITY } from './const';\nimport { Ticker } from './Ticker';\n\n/**\n * Middleware for for Application Ticker.\n * @example\n * import {TickerPlugin} from '@pixi/ticker';\n * import {Application} from '@pixi/app';\n * import {extensions} from '@pixi/extensions';\n * extensions.add(TickerPlugin);\n * @class\n * @memberof PIXI\n */\nexport class TickerPlugin\n{\n /** @ignore */\n static extension: ExtensionMetadata = ExtensionType.Application;\n\n static start: () => void;\n static stop: () => void;\n static _ticker: Ticker;\n static ticker: Ticker;\n\n /**\n * Initialize the plugin with scope of application instance\n * @static\n * @private\n * @param {object} [options] - See application options\n */\n static init(options?: GlobalMixins.IApplicationOptions): void\n {\n // Set default\n options = Object.assign({\n autoStart: true,\n sharedTicker: false,\n }, options);\n\n // Create ticker setter\n Object.defineProperty(this, 'ticker',\n {\n set(ticker)\n {\n if (this._ticker)\n {\n this._ticker.remove(this.render, this);\n }\n this._ticker = ticker;\n if (ticker)\n {\n ticker.add(this.render, this, UPDATE_PRIORITY.LOW);\n }\n },\n get()\n {\n return this._ticker;\n },\n });\n\n /**\n * Convenience method for stopping the render.\n * @method\n * @memberof PIXI.Application\n * @instance\n */\n this.stop = (): void =>\n {\n this._ticker.stop();\n };\n\n /**\n * Convenience method for starting the render.\n * @method\n * @memberof PIXI.Application\n * @instance\n */\n this.start = (): void =>\n {\n this._ticker.start();\n };\n\n /**\n * Internal reference to the ticker.\n * @type {PIXI.Ticker}\n * @name _ticker\n * @memberof PIXI.Application#\n * @private\n */\n this._ticker = null;\n\n /**\n * Ticker for doing render updates.\n * @type {PIXI.Ticker}\n * @name ticker\n * @memberof PIXI.Application#\n * @default PIXI.Ticker.shared\n */\n this.ticker = options.sharedTicker ? Ticker.shared : new Ticker();\n\n // Start the rendering\n if (options.autoStart)\n {\n this.start();\n }\n }\n\n /**\n * Clean up the ticker, scoped to application.\n * @static\n * @private\n */\n static destroy(): void\n {\n if (this._ticker)\n {\n const oldTicker = this._ticker;\n\n this.ticker = null;\n oldTicker.destroy();\n }\n }\n}\n"],"names":["UPDATE_PRIORITY","settings","TARGET_FPMS","TickerListener","fn","context","priority","once","this","next","previous","_destroyed","prototype","match","emit","deltaTime","call","redirect","destroy","connect","hard","Ticker","_this","autoStart","lastTime","speed","started","_requestId","_maxElapsedMS","_minElapsedMS","_protected","_lastFrame","_head","Infinity","deltaMS","elapsedMS","_tick","time","update","requestAnimationFrame","_requestIfNeeded","performance","now","_cancelIfNeeded","cancelAnimationFrame","_startIfPossible","start","add","NORMAL","_addListener","addOnce","listener","current","remove","Object","defineProperty","get","count","stop","currentTime","delta","head","set","fps","minFPS","Math","min","maxFPS","minFPMS","max","round","_shared","shared","_system","system","TickerPlugin","init","options","assign","sharedTicker","ticker","_ticker","render","LOW","oldTicker","extension","ExtensionType","Application"],"mappings":"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"}
|