-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEventBus.ts
81 lines (72 loc) · 3.04 KB
/
EventBus.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import { DispatchedEvent, EventCallback, DispatchedEventNameTypes } from "@/core/@typings/EventTypes";
import Event from "@/core/events/Event.ts";
import * as R from "ramda";
export default class EventBus {
private listeners: {
[key: string]: EventCallback[]
} = {
default: [
(dispatchedEvent: DispatchedEvent) => {
return;
}
]
};
public addListener(eventName: DispatchedEventNameTypes, callback: EventCallback): void {
let newListOfListeners: EventCallback[];
if (R.has(eventName, this.listeners)) {
const eventsListOfListeners: EventCallback[] = this.listeners[eventName];
newListOfListeners = R.append(callback, eventsListOfListeners);
} else {
newListOfListeners = [callback];
}
this.listeners = R.assoc(eventName, newListOfListeners, this.listeners);
}
/**
* Removes a specific listener from an event. We need to call callback.toString() to check if two different functions are equal, because checking R.equal(function1, function2) didn't work for some reason
* @param event the name of the event
* @param callback the callback function to remove
*/
public removeListener(event: DispatchedEventNameTypes, callback: EventCallback): void {
let newListOfListeners: EventCallback[];
if (R.has(event, this.listeners)) {
const eventsListOfListeners: EventCallback[] = this.listeners[event];
newListOfListeners = R.reject(
R.complement(R.equals(callback.toString())),
eventsListOfListeners
);
} else {
newListOfListeners = [];
}
this.listeners = R.assoc(event, newListOfListeners, this.listeners);
}
private dispatch(eventType: DispatchedEventNameTypes, dispatchedEvent: DispatchedEvent): void {
if (R.has(eventType, this.listeners)) {
const eventsListOfListeners: EventCallback[] = this.listeners[eventType];
const callListener = (listener: EventCallback) => {
listener(dispatchedEvent);
};
R.forEach(callListener, eventsListOfListeners);
}
}
//////////
// other functions that are just useful to have
//////////
public getListeners() {
return this.listeners;
}
public dispatchToAllListeners(event: Event): void {
const originalEventType = event.type;
// we need to cast originalEventType to the any-type so TS doesn't complain
R.forEach(
(type: DispatchedEventNameTypes) => {
this.dispatch(type, {type: originalEventType as any, data: event.data});
},
event.types);
}
public addListenerToMultipleEvents(eventNames: DispatchedEventNameTypes[], callback: EventCallback): void {
const addIndividualListener = (eventName: DispatchedEventNameTypes) => {
this.addListener(eventName, callback);
};
R.forEach(addIndividualListener, eventNames);
}
}