silk
silk copied to clipboard
core: use immutable event results
Currently mutable events are implemented via subclasses of EventScope
which need to use EventScopeProperty
in order to make mutation impossible without access to a MutableEventScope
.
This PR explores a different solution using immutable objects instead. To make this possible event listeners now only have access to an EventScope<E, R>
in their context, which has been repurposed to hold both the event instance of type E
and the event result of type R
. Non-mutating listeners are registered via listen
like before, while mutating listeners need to use listenMut
. An example usage could be:
Events.myEvent.listen {
if (result is Active) {
doStuff(event)
}
}
Events.myEvent.listenMut {
if (event.someProperty) {
doStuff(event)
Cancelled // cancel the event
} else result // return the current result
}
As seen above, the included Cancellable
type was changed to a sealed interface with two subclasses, Active
and Cancelled
, instead of having a mutable boolean property to indicate cancellation.
I have also changed the generic parameter T
for the type of event instance to E
so it better reflects the meaning together with R
, and have made immutable events use Unit
as their result type which is now possible without a bound on the result type.
TODO:
- [ ] Add utility methods for creating cancellable events without having to pass a result supplier every time
Note that all names are bikesheddable and I have not yet adjusted the documentation comments because that this is only a draft and I wanted to get some general opinions first.