/*global define*/ define(['Core/DeveloperError'], function( DeveloperError) { "use strict"; /** * A generic utility class for managing subscribers for a particular event. * This class is usually instantiated inside of a container class and * exposed as a property for others to subscribe to. * * @alias Event * @constructor * * @example * MyObject.prototype.myListener = function(arg1, arg2) { * this.myArg1Copy = arg1; * this.myArg2Copy = arg2; * } * * var myObjectInstance = new MyObject(); * var evt = new Cesium.Event(); * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); * evt.raiseEvent('1', '2'); * evt.removeEventListener(MyObject.prototype.myListener); */ var Event = function() { this._listeners = []; this._scopes = []; }; /** * Gets the number of listeners currently subscribed to the event. * * @memberof Event * * @returns {Number} The number of subscribed listeners. */ Event.prototype.getNumberOfListeners = function() { return this._listeners.length; }; /** * Registers a callback function to be executed whenever the event is raised. * An optional scope can be provided to serve as the <code>this</code> pointer * in which the function will execute. * @memberof Event * * @param {Function} listener The function to be executed when the event is raised. * @param {Object} [scope] An optional object scope to serve as the <code>this</code> * pointer in which the listener function will execute. * * @returns {Function} A function that will remove this event listener when invoked. * * @see Event#raiseEvent * @see Event#removeEventListener * * @exception {DeveloperError} listener is required and must be a function. */ Event.prototype.addEventListener = function(listener, scope) { //>>includeStart('debug', pragmas.debug); if (typeof listener !== 'function') { throw new DeveloperError('listener is required and must be a function.'); } //>>includeEnd('debug'); this._listeners.push(listener); this._scopes.push(scope); var event = this; return function() { event.removeEventListener(listener, scope); }; }; /** * Unregisters a previously registered callback. * @memberof Event * * @param {Function} listener The function to be unregistered. * @param {Object} [scope] The scope that was originally passed to addEventListener. * * @see Event#addEventListener * @see Event#raiseEvent * * @exception {DeveloperError} listener is required and must be a function. * @exception {DeveloperError} listener is not subscribed. */ Event.prototype.removeEventListener = function(listener, scope) { //>>includeStart('debug', pragmas.debug); if (typeof listener !== 'function') { throw new DeveloperError('listener is required and must be a function.'); } //>>includeEnd('debug'); var thisListeners = this._listeners; var thisScopes = this._scopes; var index = -1; for (var i = 0; i < thisListeners.length; i++) { if (thisListeners[i] === listener && thisScopes[i] === scope) { index = i; break; } } //>>includeStart('debug', pragmas.debug); if (index === -1) { throw new DeveloperError('listener is not subscribed.'); } //>>includeEnd('debug'); thisListeners.splice(index, 1); this._scopes.splice(index, 1); }; /** * Raises the event by calling each registered listener with all supplied arguments. * @memberof Event * * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. * * @see Event#addEventListener * @see Event#removeEventListener */ Event.prototype.raiseEvent = function() { var listeners = this._listeners; var scopes = this._scopes; var length = listeners.length; for (var i = 0; i < length; i++) { listeners[i].apply(scopes[i], arguments); } }; return Event; });