Skip to content

Exception thrown when posting a Cancellable child event that inherits a non-cancellable parent InheritableEvent #90

Open
@PaintNinja

Description

@PaintNinja

Consider the following event code:

public sealed interface ExampleEvent extends InheritableEvent {
    EventBus<ExampleEvent> BUS = EventBus.create(ExampleEvent.class);
        
    record Pre() implements Cancellable, ExampleEvent {
        public static final CancellableEventBus<Pre> BUS = CancellableEventBus.create(Pre.class);
    }
        
    record Post() implements ExampleEvent {
        public static final EventBus<Post> BUS = EventBus.create(Post.class);
    }
}

Crash report: https://gist.github.com/mysticdrew/170e70612dc7ddbdb33168377f209752
Relevant exception stacktrace:

java.lang.IllegalStateException: Unexpected listener type: class net.minecraftforge.eventbus.internal.EventListenerImpl$ConsumerListener
	at SECURE-BOOTSTRAP/net.minecraftforge.eventbus/net.minecraftforge.eventbus.internal.InvokerFactoryUtils.unwrapPredicates(InvokerFactoryUtils.java:55) ~[eventbus-7.0-beta.8.jar!/:7.0-beta.8]
	at SECURE-BOOTSTRAP/net.minecraftforge.eventbus/net.minecraftforge.eventbus.internal.InvokerFactory.createCancellableInvoker(InvokerFactory.java:205) ~[eventbus-7.0-beta.8.jar!/:7.0-beta.8]
	at SECURE-BOOTSTRAP/net.minecraftforge.eventbus/net.minecraftforge.eventbus.internal.InvokerFactory.createCancellableMonitoringInvoker(InvokerFactory.java:116) ~[eventbus-7.0-beta.8.jar!/:7.0-beta.8]
	at SECURE-BOOTSTRAP/net.minecraftforge.eventbus/net.minecraftforge.eventbus.internal.CancellableEventBusImpl.buildInvoker(CancellableEventBusImpl.java:142) ~[eventbus-7.0-beta.8.jar!/:7.0-beta.8]
	at SECURE-BOOTSTRAP/net.minecraftforge.eventbus/net.minecraftforge.eventbus.internal.CancellableEventBusImpl.buildInvoker(CancellableEventBusImpl.java:24) ~[eventbus-7.0-beta.8.jar!/:7.0-beta.8]
	at SECURE-BOOTSTRAP/net.minecraftforge.eventbus/net.minecraftforge.eventbus.internal.AbstractEventBusImpl.getInvoker(AbstractEventBusImpl.java:130) ~[eventbus-7.0-beta.8.jar!/:7.0-beta.8]
	at SECURE-BOOTSTRAP/net.minecraftforge.eventbus/net.minecraftforge.eventbus.internal.CancellableEventBusImpl.post(CancellableEventBusImpl.java:104) ~[eventbus-7.0-beta.8.jar!/:7.0-beta.8]

The issue is the conversion from Consumer to EventListener is done inside EventBusImpl without considering the possibility of Cancellable children, which need a WrappedConsumerListener instead of a ConsumerListener. The proper fix is to figure out a good way of accounting for that. A dumb fix that’ll work but use more memory is to always use a WrappedConsumerListener. The hotfix I’ll be doing for now is manually checking for a ConsumerListener inside unwrapPredicates() and do the conversion on the fly.

The issue with doing it on the fly is that it might not allow for cancellation checks to always be skipped in cases where it should, as the system doesn't yet have the knowledge that an ordinary ConsumerListener is never cancelling.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions