SilkMC / silk

Silk is a Minecraft API for Kotlin - targetting Fabric, Quilt and Paper
https://silkmc.net/silk/docs/
GNU General Public License v3.0
113 stars 14 forks source link

core: use immutable event results #29

Open F0Xde opened 2 years ago

F0Xde commented 2 years ago

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:

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.