File: dependencies\EventHandler.js
/**
@class EventHandler
@constructor
*/
function EventHandler(){
this._events = {};
}
/**
@method subscribe
@param event {String} Name of the event being subscribed to.
@param callback {Function} Function that will be called back when the specified event is triggered.
@param [subscriber] An optional parameter that specifies an object that's subscribing. When a function is subscribed with an object, that function will be called back with "this" set to the object.
*/
EventHandler.prototype.subscribe = function(event, callback, subscriber){
if(!(event in this._events)){
this._events[event] = new LinkedList();
}
if(!subscriber){
this._events[event].insert(0, [null, callback]);
}else{
this._events[event].insert(0, [subscriber, callback]);
}
};
/**
This is a multi-purpose method. See the example for all the ways it can be overloaded.
@method unsubscribe
@param event
@param [callback]
@param [subscriber]
@example
//Unsubscribing all callbacks for a given event.
eventHandler.unsubscribe('eventName');
//Unsubscribing all callbacks subscribed by the object.
eventHandler.unsubscribe(object);
//Unsubscribing all callbacks an object made for the given event.
eventHandler.unsubscribe('eventName', object);
//Unsubscribing a callback that was subscribed with an object.
eventHandler.unsubscribe('eventName', callback, object);
//Unsubscribing a callback subscribed by itself.
eventHandler.unsubscribe('eventName', callback);
//The last method can't be used to unsubscribe callbacks which were subscribed with an object.
*/
EventHandler.prototype.unsubscribe = function(event, callback, subscriber){
var eventCallbacks;
if(!callback){
switch(typeof event){
case "string":
delete this._events[event];
break;
case "object":
//This function is provided because removing a subscriber is the only operation which requires a loop.
function compareSubscriber(nodeValue){
return nodeValue[0] === event;
}
for(var eventName in this._events){
eventCallbacks = this._events[eventName];
eventCallbacks.removeIf(compareSubscriber, true);
}
break;
}
}else if(!subscriber){
eventCallbacks = this._events[event];
if(!eventCallbacks){
return;
}
switch(typeof callback){
case "function":
eventCallbacks.removeIf(function(nodeValue){
return nodeValue[0] === null && nodeValue[1] === callback;
});
break;
case "object":
eventCallbacks.removeIf(function(nodeValue){
return nodeValue[0] === callback;
}, true);
break;
}
}else{
eventCallbacks = this._events[event];
if(!eventCallbacks){
return;
}
eventCallbacks.removeIf(function(nodeValue){
return nodeValue[0] === subscriber && nodeValue[1] === callback;
});
}
};
/**
Triggers the event, calling all functions that subscribed to it.
@method trigger
@param event {String} The event to be triggered.
@param [eventObject] All functions that were subscribed to the specified event will be called with this as the argument.
*/
EventHandler.prototype.trigger = function(event, eventObject){
var eventCallbacks = this._events[event];
if(!eventCallbacks){
return;
}
for(var node=eventCallbacks.getFirst(); node; node=node.next){
node.value[1].call(node.value[0], eventObject);
}
};