2019-01-26 23:41:03 +01:00
|
|
|
/**
|
|
|
|
|
* We define here a simple event bus: it can
|
|
|
|
|
* - emit events
|
|
|
|
|
* - add/remove listeners.
|
|
|
|
|
*
|
2019-05-08 11:23:48 +02:00
|
|
|
* This is a useful pattern of communication in many cases. For OWL, each
|
|
|
|
|
* components and stores are event buses.
|
2019-01-26 23:41:03 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
// Types
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
2019-01-26 18:12:54 +01:00
|
|
|
export type Callback = (...args: any[]) => void;
|
2019-01-24 10:24:59 +01:00
|
|
|
|
2019-01-26 23:41:03 +01:00
|
|
|
export interface Subscription {
|
2019-01-24 10:24:59 +01:00
|
|
|
owner: any;
|
|
|
|
|
callback: Callback;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-26 23:41:03 +01:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
// EventBus
|
|
|
|
|
//------------------------------------------------------------------------------
|
2019-01-31 13:19:30 +01:00
|
|
|
|
2019-01-24 13:17:40 +01:00
|
|
|
export class EventBus {
|
2019-02-27 13:48:36 +01:00
|
|
|
subscriptions: { [eventType: string]: Subscription[] } = {};
|
2019-01-24 10:24:59 +01:00
|
|
|
|
2019-01-24 10:58:46 +01:00
|
|
|
/**
|
|
|
|
|
* Add a listener for the 'eventType' events.
|
|
|
|
|
*
|
|
|
|
|
* Note that the 'owner' of this event can be anything, but will more likely
|
2019-06-20 09:42:33 +02:00
|
|
|
* be a component or a class. The idea is that the callback will be called with
|
2019-01-24 10:58:46 +01:00
|
|
|
* the proper owner bound.
|
|
|
|
|
*
|
|
|
|
|
* Also, the owner should be kind of unique. This will be used to remove the
|
|
|
|
|
* listener.
|
|
|
|
|
*/
|
2019-01-24 10:24:59 +01:00
|
|
|
on(eventType: string, owner: any, callback: Callback) {
|
2019-02-03 13:56:36 +01:00
|
|
|
if (!callback) {
|
|
|
|
|
throw new Error("Missing callback");
|
|
|
|
|
}
|
2019-01-24 10:24:59 +01:00
|
|
|
if (!this.subscriptions[eventType]) {
|
|
|
|
|
this.subscriptions[eventType] = [];
|
|
|
|
|
}
|
|
|
|
|
this.subscriptions[eventType].push({
|
|
|
|
|
owner,
|
2020-04-21 15:08:53 +02:00
|
|
|
callback,
|
2019-01-24 10:24:59 +01:00
|
|
|
});
|
|
|
|
|
}
|
2019-01-24 10:58:46 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Remove a listener
|
|
|
|
|
*/
|
2019-01-24 10:24:59 +01:00
|
|
|
off(eventType: string, owner: any) {
|
|
|
|
|
const subs = this.subscriptions[eventType];
|
|
|
|
|
if (subs) {
|
2020-04-21 15:08:53 +02:00
|
|
|
this.subscriptions[eventType] = subs.filter((s) => s.owner !== owner);
|
2019-01-24 10:24:59 +01:00
|
|
|
}
|
|
|
|
|
}
|
2019-01-24 10:58:46 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Emit an event of type 'eventType'. Any extra arguments will be passed to
|
|
|
|
|
* the listeners callback.
|
|
|
|
|
*/
|
2019-01-24 10:24:59 +01:00
|
|
|
trigger(eventType: string, ...args: any[]) {
|
|
|
|
|
const subs = this.subscriptions[eventType] || [];
|
2019-05-28 14:04:08 +02:00
|
|
|
for (let i = 0, iLen = subs.length; i < iLen; i++) {
|
|
|
|
|
const sub = subs[i];
|
2019-01-24 10:58:46 +01:00
|
|
|
sub.callback.call(sub.owner, ...args);
|
2019-01-24 10:24:59 +01:00
|
|
|
}
|
|
|
|
|
}
|
2019-02-02 18:17:21 +01:00
|
|
|
|
2019-03-06 14:52:31 +01:00
|
|
|
/**
|
|
|
|
|
* Remove all subscriptions.
|
|
|
|
|
*/
|
2019-02-02 18:17:21 +01:00
|
|
|
clear() {
|
|
|
|
|
this.subscriptions = {};
|
|
|
|
|
}
|
2019-01-24 10:24:59 +01:00
|
|
|
}
|