/*
* Ticker
* Visit http://createjs.com/ for documentation, updates and examples.
*
* Copyright (c) 2010 gskinner.com, inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
// namespace:
this.createjs = this.createjs||{};
(function() {
// constructor:
/**
* The Ticker provides a centralized tick or heartbeat broadcast at a set interval. Listeners can subscribe to the tick
* event to be notified when a set time interval has elapsed.
*
* Note that the interval that the tick event is called is a target interval, and may be broadcast at a slower interval
* during times of high CPU load. The Ticker class uses a static interface (ex. Ticker.getPaused()
) and
* should not be instantiated.
*
*
requestAnimationFrame
if it is supported in the browser.
* If false, Ticker will use setTimeout
. If you use RAF, it is recommended that you set the framerate
* to a divisor of 60 (ex. 15, 20, 30, 60).
* @property useRAF
* @static
* @type {Boolean}
* @default false
**/
Ticker.useRAF = false;
// mix-ins:
// EventDispatcher methods:
Ticker.addEventListener = null;
Ticker.removeEventListener = null;
Ticker.removeAllEventListeners = null;
Ticker.dispatchEvent = null;
Ticker.hasEventListener = null;
Ticker._listeners = null;
createjs.EventDispatcher.initialize(Ticker); // inject EventDispatcher methods.
// private static properties:
/**
* @property _listeners
* @type {Array}
* @protected
**/
Ticker._listeners = null;
/**
* @property _pauseable
* @type {Array}
* @protected
**/
Ticker._pauseable = null;
/**
* @property _paused
* @type {Boolean}
* @protected
**/
Ticker._paused = false;
/**
* @property _inited
* @type {Boolean}
* @protected
**/
Ticker._inited = false;
/**
* @property _startTime
* @type {Number}
* @protected
**/
Ticker._startTime = 0;
/**
* @property _pausedTime
* @type {Number}
* @protected
**/
Ticker._pausedTime=0;
/**
* The number of ticks that have passed
* @property _ticks
* @type {Number}
* @protected
**/
Ticker._ticks = 0;
/**
* The number of ticks that have passed while Ticker has been paused
* @property _pausedTicks
* @type {Number}
* @protected
**/
Ticker._pausedTicks = 0;
/**
* @property _interval
* @type {Number}
* @protected
**/
Ticker._interval = 50; // READ-ONLY
/**
* @property _lastTime
* @type {Number}
* @protected
**/
Ticker._lastTime = 0;
/**
* @property _times
* @type {Array}
* @protected
**/
Ticker._times = null;
/**
* @property _tickTimes
* @type {Array}
* @protected
**/
Ticker._tickTimes = null;
/**
* @property _rafActive
* @type {Boolean}
* @protected
**/
Ticker._rafActive = false;
/**
* @property _timeoutID
* @type {Number}
* @protected
**/
Ticker._timeoutID = null;
// public static methods:
/**
* Adds a listener for the tick event. The listener must be either an object exposing a tick
method,
* or a function. The listener will be called once each tick / interval. The interval is specified via the
* .setInterval(ms)
method.
* The tick method or function is passed two parameters: the elapsed time between the
* previous tick and the current one, and a boolean indicating whether Ticker is paused.
* @method addListener
* @static
* @param {Object} o The object or function to add as a listener.
* @param {Boolean} pauseable If false, the listener will continue to have tick called
* even when Ticker is paused via Ticker.pause(). Default is true.
* @deprecated In favour of the "tick" event. Will be removed in a future version. User "addEventListener"
* instead.
**/
Ticker.addListener = function(o, pauseable) {
if (o == null) { return; }
Ticker.removeListener(o);
Ticker._pauseable[Ticker._listeners.length] = (pauseable == null) ? true : pauseable;
Ticker._listeners.push(o);
}
/**
* Initializes or resets the timer, clearing all associated listeners and fps measuring data, starting the tick.
* This is called automatically when the first listener is added.
* @method init
* @static
**/
Ticker.init = function() {
Ticker._inited = true;
Ticker._times = [];
Ticker._tickTimes = [];
Ticker._pauseable = [];
Ticker._listeners = [];
Ticker._times.push(Ticker._lastTime = Ticker._startTime = Ticker._getTime());
Ticker.setInterval(Ticker._interval);
}
/**
* Removes the specified listener.
* @method removeListener
* @static
* @param {Object} o The object or function to remove from listening from the tick event.
* @deprecated In favour of the "tick" event. Will be removed in a future version. Use "removeEventListener"
* instead.
**/
Ticker.removeListener = function(o) {
var listeners = Ticker._listeners;
if (!listeners) { return; }
var index = listeners.indexOf(o);
if (index != -1) {
listeners.splice(index, 1);
Ticker._pauseable.splice(index, 1);
}
}
/**
* Removes all listeners.
* @method removeAllListeners
* @static
* @deprecated In favour of the "tick" event. Will be removed in a future version. Use "removeAllEventListeners"
* instead.
**/
Ticker.removeAllListeners = function() {
Ticker._listeners = [];
Ticker._pauseable = [];
}
/**
* Sets the target time (in milliseconds) between ticks. Default is 50 (20 FPS).
*
* Note actual time between ticks may be more than requested depending on CPU load.
* @method setInterval
* @static
* @param {Number} interval Time in milliseconds between ticks. Default value is 50.
**/
Ticker.setInterval = function(interval) {
Ticker._interval = interval;
if (!Ticker._inited) { return; }
Ticker._setupTick();
}
/**
* Returns the current target time between ticks, as set with {{#crossLink "Ticker/setInterval"}}{{/crossLink}}.
* @method getInterval
* @static
* @return {Number} The current target interval in milliseconds between tick events.
**/
Ticker.getInterval = function() {
return Ticker._interval;
}
/**
* Sets the target frame rate in frames per second (FPS). For example, with an interval of 40, getFPS()
* will return 25 (1000ms per second divided by 40 ms per tick = 25fps).
* @method setFPS
* @static
* @param {Number} value Target number of ticks broadcast per second.
**/
Ticker.setFPS = function(value) {
Ticker.setInterval(1000/value);
}
/**
* Returns the target frame rate in frames per second (FPS). For example, with an interval of 40, getFPS()
* will return 25 (1000ms per second divided by 40 ms per tick = 25fps).
* @method getFPS
* @static
* @return {Number} The current target number of frames / ticks broadcast per second.
**/
Ticker.getFPS = function() {
return 1000/Ticker._interval;
}
/**
* Returns the actual frames / ticks per second.
* @method getMeasuredFPS
* @static
* @param {Number} [ticks] The number of previous ticks over which to measure the actual frames / ticks per second.
* Defaults to the number of ticks per second.
* @return {Number} The actual frames / ticks per second. Depending on performance, this may differ
* from the target frames per second.
**/
Ticker.getMeasuredFPS = function(ticks) {
if (Ticker._times.length < 2) { return -1; }
// by default, calculate fps for the past 1 second:
if (ticks == null) { ticks = Ticker.getFPS()|0; }
ticks = Math.min(Ticker._times.length-1, ticks);
return 1000/((Ticker._times[0]-Ticker._times[ticks])/ticks);
}
/**
* Changes the "paused" state of the Ticker, which can be retrieved by the {{#crossLink "Ticker/getPaused"}}{{/crossLink}}
* method, and is passed as the "paused" property of the tick
event. When the ticker is paused, all
* listeners will still receive a tick event, but the paused
property will be false.
*
* Note that in EaselJS v0.5.0 and earlier, "pauseable" listeners would not receive the tick
* callback when Ticker was paused. This is no longer the case.
*
*