1 | import {makeEventsEmitter} from "./utils";
|
2 |
|
3 | import {EventEmitter, Events} from "./api";
|
4 | import {delayedPromise} from "./promise-utils";
|
5 |
|
6 |
|
7 | export interface EventHandler<S extends keyof Events> {
|
8 | types: S[];
|
9 | filter: (e: Events[S]) => boolean;
|
10 | apply: (e: Events[S]) => Events[S] | void;
|
11 | }
|
12 |
|
13 | interface RegisteredEventHandler extends EventHandler<any> {
|
14 | timer: NodeJS.Timer;
|
15 | }
|
16 |
|
17 | export class EventsManager {
|
18 | public readonly events: EventEmitter = makeEventsEmitter();
|
19 | private eventHandlers = new Set<RegisteredEventHandler>();
|
20 |
|
21 | constructor(private options: { delay?: number } = {}) {
|
22 |
|
23 | }
|
24 |
|
25 | emit(e: Events[keyof Events]) {
|
26 | if (this.options.delay) {
|
27 | delayedPromise(this.options.delay)
|
28 | .then(() => this._emit(e));
|
29 | } else {
|
30 | this._emit(e);
|
31 | }
|
32 | }
|
33 |
|
34 | addEventHandler<S extends keyof Events>(handler: EventHandler<S>, timeout?: number) {
|
35 | let _handler = handler as RegisteredEventHandler;
|
36 | if (timeout) {
|
37 | (_handler).timer = setTimeout(() => this.eventHandlers.delete(_handler), timeout);
|
38 | }
|
39 | this.eventHandlers.add(_handler);
|
40 | }
|
41 |
|
42 | removeEventHandler<S extends keyof Events>(handler: EventHandler<S>) {
|
43 | this.eventHandlers.delete(handler as RegisteredEventHandler);
|
44 | clearTimeout((handler as RegisteredEventHandler).timer);
|
45 | }
|
46 |
|
47 | private _emit(e: Events[keyof Events]) {
|
48 | this.eventHandlers.forEach(handler => {
|
49 | if (e && ~handler.types.indexOf(e.type) && handler.filter(e)) {
|
50 | e = handler.apply(e);
|
51 | }
|
52 | });
|
53 | if (e) {
|
54 | (this.events as any).emit(e.type, e);
|
55 | }
|
56 | }
|
57 | }
|