126 lines
3.0 KiB
TypeScript
126 lines
3.0 KiB
TypeScript
import { logger } from '../core';
|
|
|
|
/**
|
|
* Event emitter that can be scoped by plugin name or core.
|
|
*/
|
|
export class ScopedEventEmitter {
|
|
protected listeners: {[key: string]: any[]};
|
|
|
|
/**
|
|
* Add an event listener on `name` scope for event `event`. Alias of `on`.
|
|
* @param name Event scope
|
|
* @param event Event name
|
|
* @param func Listener
|
|
* @param once Listen once
|
|
* @see on
|
|
*/
|
|
public addEventListener = this.on;
|
|
|
|
constructor() {
|
|
this.listeners = {};
|
|
}
|
|
|
|
/**
|
|
* Add an event listener on `name` scope for event `event`.
|
|
* @param name Event scope
|
|
* @param event Event name
|
|
* @param func Listener
|
|
* @param once Listen once
|
|
*/
|
|
public on(name: string, event: string, func: any, once = false): void {
|
|
if (!func || !event || !name) {
|
|
throw new Error('missing arguments');
|
|
}
|
|
|
|
if (!this.listeners[name]) {
|
|
this.listeners[name] = [];
|
|
}
|
|
|
|
this.listeners[name].push({
|
|
event, func, name, once,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Add an one-off event listener on `name` scope for event `event`.
|
|
* @param name Event scope
|
|
* @param event Event name
|
|
* @param func Listener
|
|
*/
|
|
public once(name: string, event: string, func: any): void {
|
|
this.on(name, event, func, true);
|
|
}
|
|
|
|
/**
|
|
* Emit an event `event` to all listeners in all scopes.
|
|
* @param event Event name
|
|
* @param args Data
|
|
*/
|
|
public emit(event: string, ...args: any[]): void {
|
|
for (const name in this.listeners) {
|
|
for (const i in this.listeners[name]) {
|
|
if (!this.listeners[name]) {
|
|
break;
|
|
}
|
|
const listener = this.listeners[name][i];
|
|
|
|
if (listener.event === event && listener.func) {
|
|
try {
|
|
listener.func(...args);
|
|
} catch (e: any) {
|
|
logger.error('An error occured in one of the listeners for "%s":',
|
|
event, e.stack);
|
|
}
|
|
|
|
if (listener.once) {
|
|
this.listeners[name].splice(parseInt(i, 10), 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Emit an event `event` to listeners listening for scope `name`.
|
|
* @param name Scope name
|
|
* @param event Event name
|
|
* @param args Data
|
|
*/
|
|
public emitTo(name: string, event: string, ...args: any[]): void {
|
|
if (!this.listeners[name]) {
|
|
return;
|
|
}
|
|
|
|
for (const i in this.listeners[name]) {
|
|
if (!this.listeners[name]) {
|
|
break;
|
|
}
|
|
|
|
const listener = this.listeners[name][i];
|
|
|
|
if (listener.event === event && listener.func) {
|
|
try {
|
|
listener.func(...args);
|
|
} catch (e: any) {
|
|
logger.error('An error occured in one of the listeners for "%s", stream "%s":',
|
|
event, name, e.stack);
|
|
}
|
|
|
|
if (listener.once) {
|
|
this.listeners[name].splice(parseInt(i, 10), 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove all listeners for scope `name`.
|
|
* @param name Scope name
|
|
*/
|
|
public removeName(name: string): void {
|
|
if (this.listeners[name]) {
|
|
delete this.listeners[name];
|
|
}
|
|
}
|
|
}
|