You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

Context

Since  menu  type plugins are siblings in the DOMTree, it is not possible for menu  type plugins to communicate with each other. Next to the menu  type plugin, it is not possible to communicate from an editor  type plugin to another editor  type plugin or a menu  type plugin.


Example use-case

An end-user selects 2 IED's in 1 plug-in. In order to make a connection between IED's, the user want to open the selection in an another plug.


Also, since addons are not extending from a HTMLElement, addons cannot subscribe to events themselves.

HTML events are only going upwards in the DOMTree, not downwards and/or to siblings.

Decision


If we want plug-ins for OpenSCD to be asynchronous accessible to each other, OpenSCD-Core should make use of a central event-bus.
Instead of dispatching an event on the plug-in itself, the plug-in can dispatch an event on the central event-bus. This will take care of the current problems we're facing:


Addons 

Addons can listen to CustomEvents being caught by the OpenSCD HTML Element. This will solve the communication problem from a plug-in or addon to a different addon.

Plug-ins communicating between themselves are not solved by this solution.



```ts
export  class EventBus implements EventTarget {

    private  _eventListeners: Map<string, EventListenerOrEventListenerObject[]>;

    constructor() {
        this._eventListeners = new  Map<string, EventListenerOrEventListenerObject[]>();
    }

    addEventListener(type: string, callback: EventListenerOrEventListenerObject): void {
        if (!this._eventListeners.has(type)) {
            this._eventListeners.set(type, []);
        }

        this._eventListeners.get(type)!.push(callback);
    }
    
    dispatchEvent(event: Event): boolean {
        if (this._eventListeners.has(event.type)) {
            this._eventListeners
                .get(event.type)
                !.forEach((cb) =>
                    typeof  cb === 'function' ? cb(event) : cb.handleEvent(event)
                );

            return  true;
        }

        return  false;
    }

    removeEventListener(type: string, callback: EventListenerOrEventListenerObject): void {
        if (this._eventListeners.has(type)) {
            this._eventListeners.set(type, this._eventListeners.get(type)!.filter((cb) =>  cb !== callback));
        }
    }

}
```


Alternatives


Find a (seperate solution) for all problems mentioned.

Pro's:


Con's




Consequences

Implementing a central event-bus means that current OSCD plugins need some refactoring to dispatch events to the event-bus instead of dispatching events on itself.

  • No labels