(function() {
/**
* EventEmitter utility.
* @constructor
*/
tracking.EventEmitter = function() {};
/**
* Holds event listeners scoped by event type.
* @type {object}
* @private
*/
tracking.EventEmitter.prototype.events_ = null;
/**
* Adds a listener to the end of the listeners array for the specified event.
* @param {string} event
* @param {function} listener
* @return {object} Returns emitter, so calls can be chained.
*/
tracking.EventEmitter.prototype.addListener = function(event, listener) {
if (typeof listener !== 'function') {
throw new TypeError('Listener must be a function');
}
if (!this.events_) {
this.events_ = {};
}
this.emit('newListener', event, listener);
if (!this.events_[event]) {
this.events_[event] = [];
}
this.events_[event].push(listener);
return this;
};
/**
* Returns an array of listeners for the specified event.
* @param {string} event
* @return {array} Array of listeners.
*/
tracking.EventEmitter.prototype.listeners = function(event) {
return this.events_ && this.events_[event];
};
/**
* Execute each of the listeners in order with the supplied arguments.
* @param {string} event
* @param {*} opt_args [arg1], [arg2], [...]
* @return {boolean} Returns true if event had listeners, false otherwise.
*/
tracking.EventEmitter.prototype.emit = function(event) {
var listeners = this.listeners(event);
if (listeners) {
var args = Array.prototype.slice.call(arguments, 1);
for (var i = 0; i < listeners.length; i++) {
if (listeners[i]) {
listeners[i].apply(this, args);
}
}
return true;
}
return false;
};
/**
* Adds a listener to the end of the listeners array for the specified event.
* @param {string} event
* @param {function} listener
* @return {object} Returns emitter, so calls can be chained.
*/
tracking.EventEmitter.prototype.on = tracking.EventEmitter.prototype.addListener;
/**
* Adds a one time listener for the event. This listener is invoked only the
* next time the event is fired, after which it is removed.
* @param {string} event
* @param {function} listener
* @return {object} Returns emitter, so calls can be chained.
*/
tracking.EventEmitter.prototype.once = function(event, listener) {
var self = this;
self.on(event, function handlerInternal() {
self.removeListener(event, handlerInternal);
listener.apply(this, arguments);
});
};
/**
* Removes all listeners, or those of the specified event. It's not a good
* idea to remove listeners that were added elsewhere in the code,
* especially when it's on an emitter that you didn't create.
* @param {string} event
* @return {object} Returns emitter, so calls can be chained.
*/
tracking.EventEmitter.prototype.removeAllListeners = function(opt_event) {
if (!this.events_) {
return this;
}
if (opt_event) {
delete this.events_[opt_event];
} else {
delete this.events_;
}
return this;
};
/**
* Remove a listener from the listener array for the specified event.
* Caution: changes array indices in the listener array behind the listener.
* @param {string} event
* @param {function} listener
* @return {object} Returns emitter, so calls can be chained.
*/
tracking.EventEmitter.prototype.removeListener = function(event, listener) {
if (typeof listener !== 'function') {
throw new TypeError('Listener must be a function');
}
if (!this.events_) {
return this;
}
var listeners = this.listeners(event);
if (Array.isArray(listeners)) {
var i = listeners.indexOf(listener);
if (i < 0) {
return this;
}
listeners.splice(i, 1);
}
return this;
};
/**
* By default EventEmitters will print a warning if more than 10 listeners
* are added for a particular event. This is a useful default which helps
* finding memory leaks. Obviously not all Emitters should be limited to 10.
* This function allows that to be increased. Set to zero for unlimited.
* @param {number} n The maximum number of listeners.
*/
tracking.EventEmitter.prototype.setMaxListeners = function() {
throw new Error('Not implemented');
};
}());