@awayjs/core
Version:
AwayJS core classes
136 lines (109 loc) • 3.5 kB
text/typescript
import { EventBase } from './EventBase';
/**
* Base export class for dispatching events
*
* @export class away.events.EventDispatcher
*
*/
export class EventDispatcher {
private _listenerObjects: Record<string, ListenerObject> = {};
private _t: any;
constructor(target: any = null) {
this._t = target || this;
}
/**
* Add an event listener
* @method addEventListener
* @param {String} type of event to add a listener for
* @param {Function} listener function
*/
public addEventListener(type: string, listener: (event: EventBase) => void): void {
let l: ListenerObject = this._listenerObjects[type];
if (l === undefined)
l = this._listenerObjects[type] = new ListenerObject();
l.addEventListener(listener);
}
/**
* Remove an event listener
* @method removeEventListener
* @param {String} type of event to remove a listener for
* @param {Function} listener function
*/
public removeEventListener(type: string, listener: (event: EventBase) => void): void {
const l: ListenerObject = this._listenerObjects[type];
if (l) {
l.removeEventListener(listener);
if (l.numListeners == 0)
delete this._listenerObjects[type];
}
}
/**
* Dispatch an event
* @method dispatchEvent
* @param {Event} event to dispatch
*/
public dispatchEvent(event: EventBase, target: any = null): void {
const l: ListenerObject = this._listenerObjects[event.type];
if (l) {
event.target = target || this._t;
event.currentTarget = this._t;
l.dispatchEvent(event);
}
}
/**
* check if an object has an event listener assigned to it
* @method hasListener
* @param {String} type of event to remove a listener for
* @param {Function} listener function
*/
public hasEventListener(type: string, listener?: (event: EventBase) => void): boolean {
if (this._listenerObjects[type] === undefined)
return false;
if (listener != null)
return this._listenerObjects[type].getEventListenerIndex(listener) !== -1;
return this._listenerObjects[type].numListeners > 0;
}
protected removeAllEventListeners() {
this._listenerObjects = {};
}
}
export class ListenerObject {
private _index: number = 0;
private _listeners: Array<(event: EventBase) => void> = new Array<(event: EventBase) => void>();
public numListeners: number = 0;
public addEventListener(listener: (event: EventBase) => void): void {
//check if listener already added
if (this._listeners.indexOf(listener) !== -1)
return;
this._listeners.push(listener);
this.numListeners++;
}
public removeEventListener(listener: (event: EventBase) => void): void {
//check if listener exists
const index: number = this._listeners.indexOf(listener);
if (index === -1)
return;
this._listeners.splice(index, 1);
//deals with removing a listener mid-way through dispatching listeners
if (index <= this._index)
this._index--;
this.numListeners--;
}
public dispatchEvent(event: EventBase): void {
const len: number = this.numListeners;
for (this._index = 0; this._index < len && this._index < this.numListeners; this._index++) {
this._listeners[this._index](event);
if (!event._iAllowedToImmediatlyPropagate) {
break;
}
}
}
/**
* get Event Listener Index in array. Returns -1 if no listener is added
* @method getEventListenerIndex
* @param {Function} listener function
*/
public getEventListenerIndex(listener: (event: EventBase) => void): number {
return this._listeners.indexOf(listener);
}
}