Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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.

...


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.


Code Block
```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

Instead of the central EventBus, we can let plugins dispatch events on the plugin itself. If a plugin needs an event from another plugin, It can listen to an event being dispatched to Open-SCD Core .

...

Due to WebApi restrictions, Events that are emitted by one of the plugins are only bubbling up directly (https://www.freecodecamp.org/news/event-bubbling-in-javascript/)



draw.io Diagram
bordertrue
diagramNameAlternative
simpleViewerfalse
width
linksauto
tbstyletop
lboxtrue
diagramWidth641
revision2


Pro's:

No new Code needs to be introduced

...

This is only working for HTMLElements (Plugins).

It is possible to stop the event from bubbling further inside a plugin. This means that a plugin can negate an event that should be handled by a different plugin. (Plugin A sends an event (that should be read by Plugin B), Plugin C is listening to this event and stops the event from going further (event.preventDefault()). Because of Plugin C, plugin B never gets the event).


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.