import { Events } from './events'; import { EngineError } from '../errors'; export class Emitter { events = new Map(); silent = false; constructor (source: Events | Emitter) { this.events = source instanceof Emitter ? source.events : source.handlers; } on (eventNames: K | K[], handler: (args: EventTypes[K]) => any) { const events = Array.isArray(eventNames) ? eventNames : eventNames.split(' '); events.forEach(eventName => { const event = this.events.get(eventName); if (!event) { throw new Error(EngineError.EventNameUndefined + eventName); } event.push(handler); }); return this; } trigger (eventName: K, params: EventTypes[K] | {} = {}) { const event = this.events.get(eventName); if (!event) { throw new Error(EngineError.EventTriggerFailed + eventName); } return event.reduce((accumulator: boolean, handler: Function) => handler(params) !== false && accumulator, true); } bind (eventName: string) { if (this.events.get(eventName)) { throw new Error(EngineError.EventAlreadyBound + eventName); } this.events.set(eventName, []); } // TO DO: is this used anywhere? exist (eventName: string) { return Array.isArray(this.events.get(eventName)); } }