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()
}
}