core/src/util/events.ts

126 lines
3.0 KiB
TypeScript
Raw Permalink Normal View History

2020-12-06 13:40:06 +00:00
import { logger } from '../core';
2021-10-02 08:07:01 +00:00
/**
* Event emitter that can be scoped by plugin name or core.
*/
2020-11-21 15:41:08 +00:00
export class ScopedEventEmitter {
2024-04-07 19:06:01 +00:00
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
*/
2020-11-21 15:41:08 +00:00
public addEventListener = this.on;
constructor() {
this.listeners = {};
}
2024-04-07 19:06:01 +00:00
/**
* 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
*/
2020-11-21 15:41:08 +00:00
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,
});
}
2024-04-07 19:06:01 +00:00
/**
* Add an one-off event listener on `name` scope for event `event`.
* @param name Event scope
* @param event Event name
* @param func Listener
*/
2020-11-21 15:41:08 +00:00
public once(name: string, event: string, func: any): void {
this.on(name, event, func, true);
}
2024-04-07 19:06:01 +00:00
/**
* Emit an event `event` to all listeners in all scopes.
* @param event Event name
* @param args Data
*/
2020-11-21 15:41:08 +00:00
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) {
2020-12-06 13:40:06 +00:00
try {
listener.func(...args);
2021-09-03 17:23:22 +00:00
} catch (e: any) {
2020-12-06 13:40:06 +00:00
logger.error('An error occured in one of the listeners for "%s":',
event, e.stack);
}
2020-11-21 15:41:08 +00:00
if (listener.once) {
this.listeners[name].splice(parseInt(i, 10), 1);
}
}
}
}
}
2024-04-07 19:06:01 +00:00
/**
* Emit an event `event` to listeners listening for scope `name`.
* @param name Scope name
* @param event Event name
* @param args Data
*/
2020-11-21 15:41:08 +00:00
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) {
2020-12-06 13:40:06 +00:00
try {
listener.func(...args);
2021-09-03 17:23:22 +00:00
} catch (e: any) {
2020-12-06 13:40:06 +00:00
logger.error('An error occured in one of the listeners for "%s", stream "%s":',
event, name, e.stack);
}
2020-11-21 15:41:08 +00:00
if (listener.once) {
this.listeners[name].splice(parseInt(i, 10), 1);
}
}
}
}
2024-04-07 19:06:01 +00:00
/**
* Remove all listeners for scope `name`.
* @param name Scope name
*/
2020-11-21 15:41:08 +00:00
public removeName(name: string): void {
if (this.listeners[name]) {
delete this.listeners[name];
}
}
}