neoforged / Bus

Event firing and listening framework, based on the event bus concept
GNU Lesser General Public License v2.1
3 stars 8 forks source link

`@SubscribeEvent.receiveCanceled` is not respected #32

Open sciwhiz12 opened 1 month ago

sciwhiz12 commented 1 month ago

Event listeners ordinarily do not receive cancelled events. However, they can specifically opt-in to receiving cancelled events through either the receiveCanceled parameter of the IEventBus#addListener methods or the receiveCanceled field of the @SubscribeEvent annotation.

However, code investigation and testing (prompted by @PlatinPython, thanks btw) shows that the receiveCanceled field of the @SubscribeEvent annotation is not respected, thus causing cancelled events to never reach such an annotated listener. (The addListener methods are unaffected as far as I can tell.)

Sample output from the code below:

Sending non-canceled event
StaticListener: Received event; canceled: false
InstanceListener: Received event; canceled: false
Sending canceled event

Sample code:

import net.neoforged.bus.api.*;

class Scratch {
    public static void main(String[] args) {
        final IEventBus bus = BusBuilder.builder().build();
        final TestEvent event = new TestEvent();

        bus.register(StaticListener.class);
        final InstanceListener listener = new InstanceListener();
        bus.register(listener);

        System.out.println("Sending non-canceled event");
        bus.post(event);

        event.setCanceled(true);
        System.out.println("Sending canceled event");
        bus.post(event);
    }

    static class StaticListener {
        @SubscribeEvent(receiveCanceled = true)
        public static void listen(TestEvent event) {
            System.out.println("StaticListener: Received event; canceled: " + event.isCanceled());
        }
    }

    static class InstanceListener {
        @SubscribeEvent(receiveCanceled = true)
        public void listen(TestEvent event) {
            System.out.println("InstanceListener: Received event; canceled: " + event.isCanceled());
        }
    }

    public static class TestEvent extends Event implements ICancellableEvent {
    }
}