105 lines
2.9 KiB
TypeScript
105 lines
2.9 KiB
TypeScript
|
|
/**
|
|
* Allowed event name.
|
|
*/
|
|
type EventName = string | number | symbol;
|
|
type EventHandler<Value> = (value?: Value) => any;
|
|
|
|
/**
|
|
* An internally used event emitter model.
|
|
*/
|
|
class EventEmitter<EventMap extends Record<EventName, any> = {}> {
|
|
|
|
private eventMap = new Map<keyof EventMap, Set<Function>>;
|
|
|
|
/**
|
|
* Add a listener for a given event.
|
|
* @param event - event name.
|
|
* @param handler - event handler.
|
|
*/
|
|
public addListener<T extends keyof EventMap>(event: T, handler: EventHandler<EventMap[T]>): void {
|
|
let handlerSet = this.eventMap.get(event);
|
|
if (!handlerSet) {
|
|
handlerSet = new Set();
|
|
this.eventMap.set(event, handlerSet);
|
|
}
|
|
handlerSet.add(handler);
|
|
}
|
|
|
|
/**
|
|
* Alias of `EventEmitter.addListener`.
|
|
*/
|
|
public declare on: <T extends keyof EventMap>(event: T, handler: EventHandler<EventMap[T]>) => void;
|
|
|
|
/**
|
|
* Remove the listeners of a given event.
|
|
* @param event - event name.
|
|
* @param handler - event handler.
|
|
*/
|
|
public removeListener<T extends keyof EventMap>(event: T, handler: EventHandler<EventMap[T]>) {
|
|
let handlerSet = this.eventMap.get(event);
|
|
if (handlerSet) {
|
|
handlerSet.delete(handler);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Alias of `EventEmitter.removeListener`.
|
|
*/
|
|
public declare off: <T extends keyof EventMap>(event: T, handler: EventHandler<EventMap[T]>) => void;
|
|
|
|
/**
|
|
* Remove all listeners of a given event.
|
|
* @param event - event name.
|
|
* @param handler - event handler.
|
|
*/
|
|
public removeAllListener<T extends keyof EventMap>(event: T) {
|
|
this.eventMap.set(event, new Set());
|
|
}
|
|
|
|
/**
|
|
* Alias of `EventEmitter.removeAllListener`.
|
|
*/
|
|
public declare offAll: <T extends keyof EventMap>(event: T) => void;
|
|
|
|
/**
|
|
* emit event.
|
|
*/
|
|
public emit<T extends keyof EventMap>(...param: EventMap[T] extends void ? [T] : [T, EventMap[T]]) {
|
|
let handlerSet = this.eventMap.get(param[0]);
|
|
if (handlerSet) {
|
|
for (const handler of handlerSet) {
|
|
handler(param[1]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove all listeners.
|
|
*/
|
|
public clearAllListener() {
|
|
this.eventMap.clear();
|
|
this.eventMap = new Map();
|
|
}
|
|
|
|
/**
|
|
* Get the number of listeners for a given event.
|
|
* @param event - event name.
|
|
*/
|
|
public listenerCount<T extends keyof EventMap>(event: T): number {
|
|
let handlerSet = this.eventMap.get(event);
|
|
if (handlerSet) {
|
|
return handlerSet.size;
|
|
}
|
|
else {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Register alias.
|
|
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
|
|
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
|
|
EventEmitter.prototype.offAll = EventEmitter.prototype.removeAllListener;
|
|
|
|
export { EventEmitter }; |