Events - mgismissing/cosmos GitHub Wiki

MakeCode Arcade's way of handling events is calling a class-dependent onEvent function that links that event to a new function. The main problem with this approach is that if adding another event handler is required, the onEvent function has to be called again and the entire event handler list redefined. This does not scale well for very large projects and it will very likely start to get impractical once we want to add a lot of handlers for one single event.

The solution is simple: define a custom event listener class that holds an expandable list of event handlers and bind that to the onEvent function. When we want to add a new event handler, we simply add it to that list and remove it when it's not needed anymore.

One of the main advantages of this method is that it's now possible to create custom classes that add their own custom event listeners.

Using events

In this specific example two functions are required to run when the button A is pressed: myFuncA and myFuncB.

The first thing we need to define when using the Cosmos event system is one or more event listeners. We then bind them to the onEvent functions and run every event handler in their list:

let controllerEventListener: EventListener = new EventListener()
controller.anyButton.onEvent(ControllerButtonEvent.Pressed, () => { controllerEventListener.handle_events() })

Next, we will need to register one EventHandler for each function to the EventListener object and save their IDs in case we want to later remove them:

let myFuncAEventHandler_id: number = controllerEventListener.add_handler(new ControllerEventHandler(controller.A, ControllerButtonEvent.Pressed, () => { myFuncA() }))
let myFuncBEventHandler_id: number = controllerEventListener.add_handler(new ControllerEventHandler(controller.A, ControllerButtonEvent.Pressed, () => { myFuncB() }))

In this case the ControllerEventHandler is what suited our needs better because it supports filtering by which button has been pressed and in what way (pressed or released) before running our functions. If you can't find the EventHandler class you need, define a new one:

class MyEventHandler extends EventHandler {
    confirm: boolean
    constructor(confirm: boolean, handler: () => void) {
        super(handler)
        this.confirm = confirm
    }

    run() {
    if (this.confirm) {
        super.run()
    }
}