API Documentation for: 1.1.23
Show:

File:DelayedCall.js

/**
*  @module cloudkid
*/
(function(undefined) {

	"use strict";

	var NEXT_ID = 0;

	/**
	*  A class for delaying a call through the OS, instead of relying on setInterval() or setTimeout().
	* 
	*  @class DelayedCall
	*  @constructor
	*  @param {function} callback The function to call when the delay has completed.
	*  @param {int} delay The time to delay the call, in milliseconds.
	*  @param {Boolean} repeat=false If the DelayedCall should automatically repeat itself when completed.
	*  @param {Boolean} autoDestroy=true If the DelayedCall should clean itself up when completed.
	*/
	var DelayedCall = function(callback, delay, repeat, autoDestroy)
	{
		/**
		*  The function to call when the delay is completed.
		*  @private
		*  @property {function} _callback
		*/
		this._callback = callback;
		/**
		*  The delay time, in milliseconds.
		*  @private
		*  @property {int} _delay
		*/
		this._delay = delay;
		/**
		*  The timer counting down from _delay, in milliseconds.
		*  @private
		*  @property {int} _timer
		*/
		this._timer = delay;
		/**
		*  If the DelayedCall should repeat itself automatically.
		*  @private
		*  @property {Boolean} _repeat
		*  @default false
		*/
		this._repeat = !!repeat;
		/**
		*  If the DelayedCall should destroy itself after completing
		*  @private
		*  @property {Boolean} _autoDestroy
		*  @default true
		*/
		this._autoDestroy = autoDestroy === undefined ? true : !!autoDestroy;
		/**
		*  The unique ID used for the update callback for the OS.
		*  @private
		*  @property {String} _updateId
		*/
		this._updateId = "DelayedCall#" + (++NEXT_ID);
		/**
		*  If the DelayedCall is currently paused (not stopped).
		*  @private
		*  @property {Boolean} _paused
		*/
		this._paused = false;

		//save a bound version of the update function
		this._update = this._update.bind(this);
		//start the delay
		cloudkid.OS.instance.addUpdateCallback(this._updateId, this._update);
	};

	var p = DelayedCall.prototype;

	/**
	*  The callback supplied to the OS for an update each frame.
	*  @private
	*  @method _update
	*  @param {int} elapsed The time elapsed since the previous frame.
	*/
	p._update = function(elapsed)
	{
		if(!this._callback)
		{
			this.destroy();
			return;
		}

		this._timer -= elapsed;
		if(this._timer <= 0)
		{
			this._callback();
			if(this._repeat)
				this._timer += this._delay;
			else if(this._autoDestroy)
				this.destroy();
			else
				cloudkid.OS.instance.removeUpdateCallback(this._updateId);
		}
	};

	/**
	*  Restarts the DelayedCall, whether it is running or not.
	*  @public
	*  @method restart
	*/
	p.restart = function()
	{
		if(!this._callback) return;
		var os = cloudkid.OS.instance;
		if(!os.hasUpdateCallback(this._updateId))
			os.addUpdateCallback(this._updateId, this._update);
		this._timer = this._delay;
		this._paused = false;
	};

	/**
	*  Stops the DelayedCall, without destroying it.
	*  @public
	*  @method stop
	*/
	p.stop = function()
	{
		cloudkid.OS.instance.removeUpdateCallback(this._updateId);
		this._paused = false;
	};

	/**
	*  If the DelayedCall is paused or not.
	*  @public
	*  @property {Boolean} paused
	*/
	Object.defineProperty(p, "paused", {
		get: function() { return this._paused; },
		set: function(value)
		{
			if(!this._callback) return;
			var os = cloudkid.OS.instance;
			if(this._paused && !value)
			{
				this._paused = false;
				if(!os.hasUpdateCallback(this._updateId))
					os.addUpdateCallback(this._updateId, this._update);
			}
			else if(value)
			{
				if(os.hasUpdateCallback(this._updateId))
				{
					this._paused = true;
					os.removeUpdateCallback(this._updateId);
				}
			}
		}
	});

	/**
	*  Stops and cleans up the DelayedCall. Do not use it after calling
	*  destroy().
	*  @public
	*  @method destroy
	*/
	p.destroy = function()
	{
		cloudkid.OS.instance.removeUpdateCallback(this._updateId);
		this._callback = null;
	};

	namespace('cloudkid').DelayedCall = DelayedCall;
}());