Skip to content

Commit

Permalink
Provide versions of all registration methods with explicit event clas…
Browse files Browse the repository at this point in the history
…s parameters.

Add test variants for explicit-class handlers.
  • Loading branch information
gigaherz committed Apr 17, 2023
1 parent 8466371 commit 69a5fd8
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class EventBusBenchmark {
private Consumer<Object> postStatic;
private Consumer<Object> postDynamic;
private Consumer<Object> postLambda;
private Consumer<Object> postClassLambda;
private Consumer<Object> postCombined;

@SuppressWarnings("unchecked")
Expand All @@ -37,6 +38,7 @@ public void setup() throws Exception {
postDynamic = (Consumer<Object>)cls.getField("postDynamic").get(null);
postLambda = (Consumer<Object>)cls.getField("postLambda").get(null);
postCombined = (Consumer<Object>)cls.getField("postCombined").get(null);
postClassLambda = (Consumer<Object>)cls.getField("postClassLambda").get(null);
}

public static class TestCallback {
Expand Down Expand Up @@ -70,6 +72,13 @@ public int testModLauncherCombined() throws Throwable {
return 0;
}

@Benchmark
public int testModLauncherClassLambda()
{
postClassLambda.accept(ModLauncher);
return 0;
}

// ClassLoader ASM Factory
@Benchmark
public int testClassLoaderDynamic() throws Throwable {
Expand All @@ -94,4 +103,11 @@ public int testClassLoaderCombined() throws Throwable {
postCombined.accept(ClassLoader);
return 0;
}

@Benchmark
public int testClassLoaderClassLambda()
{
postClassLambda.accept(ClassLoader);
return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,10 @@ public int testNoLoaderCombined() {
BenchmarkArmsLength.postCombined(BenchmarkArmsLength.NoLoader);
return 0;
}

@Benchmark
public int testNoLoaderClassLambda() {
BenchmarkArmsLength.postClassLambda(BenchmarkArmsLength.NoLoader);
return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.junit.jupiter.api.Test;

import net.minecraftforge.eventbus.test.general.AbstractEventListenerTest;
import net.minecraftforge.eventbus.test.general.ClassLambdaHandlerTest;
import net.minecraftforge.eventbus.test.general.DeadlockingEventTest;
import net.minecraftforge.eventbus.test.general.EventBusSubtypeFilterTest;
import net.minecraftforge.eventbus.test.general.EventFiringEventTest;
Expand Down Expand Up @@ -69,6 +70,16 @@ public void lambdaGenerics() {
doTest(new LambdaHandlerTest.Generics() {});
}

@Test
public void classLambdaBasic() {
doTest(new ClassLambdaHandlerTest.Basic() {});
}

@Test
public void classLambdaSubClass() {
doTest(new ClassLambdaHandlerTest.SubClassEvent() {});
}

@Disabled
@RepeatedTest(500)
public void deadlockTest() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.junit.jupiter.api.Test;

import net.minecraftforge.eventbus.test.general.AbstractEventListenerTest;
import net.minecraftforge.eventbus.test.general.ClassLambdaHandlerTest;
import net.minecraftforge.eventbus.test.general.DeadlockingEventTest;
import net.minecraftforge.eventbus.test.general.EventBusSubtypeFilterTest;
import net.minecraftforge.eventbus.test.general.EventFiringEventTest;
Expand Down Expand Up @@ -75,6 +76,16 @@ public void lambdaGenerics() {
doTest(new LambdaHandlerTest.Generics() {});
}

@Test
public void classLambdaBasic() {
doTest(new ClassLambdaHandlerTest.Basic() {});
}

@Test
public void classLambdaSubClass() {
doTest(new ClassLambdaHandlerTest.SubClassEvent() {});
}

@Disabled
@RepeatedTest(500)
public void deadlockTest() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package net.minecraftforge.eventbus.test.general;

import net.minecraftforge.eventbus.api.*;
import net.minecraftforge.eventbus.test.ITestHandler;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

import static org.junit.jupiter.api.Assertions.assertTrue;

public abstract class ClassLambdaHandlerTest implements ITestHandler {
boolean hit;

@Override
public void before(Consumer<Class<?>> validator, Supplier<BusBuilder> builder) {
validator.accept(SubEvent.class);
validator.accept(CancellableEvent.class);
hit = false;
}

public void consumeEvent(Event e) { hit = true; }
public void consumeSubEvent(SubEvent e) { hit = true; }

public static class Basic extends ClassLambdaHandlerTest
{
@Override
public void test(Consumer<Class<?>> validator, Supplier<BusBuilder> builder) {
final IEventBus iEventBus = builder.get().build();
// Inline
iEventBus.addListener(Event.class, (e)-> hit = true);
iEventBus.post(new Event());
assertTrue(hit, "Inline Lambda was not called");
hit = false;
// Method reference
iEventBus.addListener(Event.class, this::consumeEvent);
iEventBus.post(new Event());
assertTrue(hit, "Method reference was not called");
hit = false;
}
}

public static class SubClassEvent extends ClassLambdaHandlerTest
{
@Override
public void test(Consumer<Class<?>> validator, Supplier<BusBuilder> builder) {
final IEventBus iEventBus = builder.get().build();
// Inline
iEventBus.addListener(SubEvent.class, (e) -> hit = true);
iEventBus.post(new SubEvent());
assertTrue(hit, "Inline was not called");
hit = false;
iEventBus.post(new Event());
assertTrue(!hit, "Inline was called on root event");
// Method Reference
iEventBus.addListener(SubEvent.class, this::consumeSubEvent);
iEventBus.post(new SubEvent());
assertTrue(hit, "Method reference was not called");
hit = false;
iEventBus.post(new Event());
assertTrue(!hit, "Method reference was called on root event");
}
}

public static class SubEvent extends Event {}

@Cancelable
public static class CancellableEvent extends Event {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ public record Bus(
IEventBus staticSubscriberBus,
IEventBus dynamicSubscriberBus,
IEventBus lambdaSubscriberBus,
IEventBus combinedSubscriberBus
IEventBus combinedSubscriberBus,
IEventBus classLambdaSubscriberBus
) {
public Bus register() {
staticSubscriberBus.register(SubscriberStatic.class);
Expand All @@ -20,6 +21,7 @@ public Bus register() {
combinedSubscriberBus.register(new SubscriberDynamic());
SubscriberLambda.register(lambdaSubscriberBus);
SubscriberLambda.register(combinedSubscriberBus);
SubscriberClassLambda.register(classLambdaSubscriberBus);
return this;
}
};
Expand All @@ -36,12 +38,14 @@ public static Runnable supplier() {
BusBuilder.builder().useModLauncher().build(),
BusBuilder.builder().useModLauncher().build(),
BusBuilder.builder().useModLauncher().build(),
BusBuilder.builder().useModLauncher().build(),
BusBuilder.builder().useModLauncher().build()
).register();
ClassLoader = new Bus(
BusBuilder.builder().build(),
BusBuilder.builder().build(),
BusBuilder.builder().build(),
BusBuilder.builder().build(),
BusBuilder.builder().build()
).register();
};
Expand All @@ -53,13 +57,15 @@ public static Runnable supplier() {
BusBuilder.builder().build(),
BusBuilder.builder().build(),
BusBuilder.builder().build(),
BusBuilder.builder().build(),
BusBuilder.builder().build()
).register();

public static final Consumer<Object> postStatic = BenchmarkArmsLength::postStatic;
public static final Consumer<Object> postDynamic = BenchmarkArmsLength::postDynamic;
public static final Consumer<Object> postLambda = BenchmarkArmsLength::postLambda;
public static final Consumer<Object> postCombined = BenchmarkArmsLength::postCombined;
public static final Consumer<Object> postClassLambda = BenchmarkArmsLength::postLambda;

public static void postStatic(Object bus)
{
Expand All @@ -81,6 +87,11 @@ public static void postCombined(Object bus)
postAll(((Bus)bus).combinedSubscriberBus);
}

public static void postClassLambda(Object bus)
{
postAll(((Bus)bus).classLambdaSubscriberBus);
}

private static void postAll(IEventBus bus)
{
bus.post(new CancelableEvent());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package net.minecraftforge.eventbus.benchmarks.compiled;

import net.minecraftforge.eventbus.api.IEventBus;

public class SubscriberClassLambda
{

public static void register(IEventBus bus)
{
bus.addListener(CancelableEvent.class, SubscriberClassLambda::onCancelableEvent);
bus.addListener(ResultEvent.class, SubscriberClassLambda::onResultEvent);
bus.addListener(EventWithData.class, SubscriberClassLambda::onSimpleEvent);
}

public static void onCancelableEvent(CancelableEvent event)
{

}

public static void onResultEvent(ResultEvent event)
{

}

public static void onSimpleEvent(EventWithData event)
{

}
}
22 changes: 22 additions & 0 deletions src/main/java/net/minecraftforge/eventbus/EventBus.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,24 @@ public <T extends Event> void addListener(final Consumer<T> consumer) {
addListener(EventPriority.NORMAL, consumer);
}

@Override
public <T extends Event> void addListener(final Class<T> eventType, final Consumer<T> consumer) {
checkNotGeneric(eventType);
addListener(EventPriority.NORMAL, eventType, consumer);
}

@Override
public <T extends Event> void addListener(final EventPriority priority, final Consumer<T> consumer) {
checkNotGeneric(consumer);
addListener(priority, false, consumer);
}

@Override
public <T extends Event> void addListener(final EventPriority priority, final Class<T> eventType, final Consumer<T> consumer) {
checkNotGeneric(eventType);
addListener(priority, false, eventType, consumer);
}

@Override
public <T extends Event> void addListener(final EventPriority priority, final boolean receiveCancelled, final Consumer<T> consumer) {
checkNotGeneric(consumer);
Expand All @@ -210,11 +222,21 @@ public <T extends GenericEvent<? extends F>, F> void addGenericListener(final Cl
addGenericListener(genericClassFilter, EventPriority.NORMAL, consumer);
}

@Override
public <T extends GenericEvent<? extends F>, F> void addGenericListener(final Class<F> genericClassFilter, final Class<T> eventType, final Consumer<T> consumer) {
addGenericListener(genericClassFilter, EventPriority.NORMAL, eventType, consumer);
}

@Override
public <T extends GenericEvent<? extends F>, F> void addGenericListener(final Class<F> genericClassFilter, final EventPriority priority, final Consumer<T> consumer) {
addGenericListener(genericClassFilter, priority, false, consumer);
}

@Override
public <T extends GenericEvent<? extends F>, F> void addGenericListener(final Class<F> genericClassFilter, final EventPriority priority, final Class<T> eventType, final Consumer<T> consumer) {
addGenericListener(genericClassFilter, priority, false, eventType, consumer);
}

@Override
public <T extends GenericEvent<? extends F>, F> void addGenericListener(final Class<F> genericClassFilter, final EventPriority priority, final boolean receiveCancelled, final Consumer<T> consumer) {
addListener(priority, passGenericFilter(genericClassFilter).and(passCancelled(receiveCancelled)), consumer);
Expand Down
44 changes: 44 additions & 0 deletions src/main/java/net/minecraftforge/eventbus/api/IEventBus.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ public interface IEventBus {
*/
<T extends Event> void addListener(Consumer<T> consumer);

/**
* Add a consumer listener with default {@link EventPriority#NORMAL} and not recieving cancelled events.
*
* @param eventType The concrete {@link Event} subclass to subscribe to
* @param consumer Callback to invoke when a matching event is received
* @param <T> The {@link Event} subclass to listen for
*/
<T extends Event> void addListener(Class<T> eventType, Consumer<T> consumer);

/**
* Add a consumer listener with the specified {@link EventPriority} and not receiving cancelled events.
*
Expand All @@ -46,6 +55,16 @@ public interface IEventBus {
*/
<T extends Event> void addListener(EventPriority priority, Consumer<T> consumer);

/**
* Add a consumer listener with the specified {@link EventPriority} and not receiving cancelled events.
*
* @param priority {@link EventPriority} for this listener
* @param eventType The concrete {@link Event} subclass to subscribe to
* @param consumer Callback to invoke when a matching event is received
* @param <T> The {@link Event} subclass to listen for
*/
<T extends Event> void addListener(EventPriority priority, Class<T> eventType, Consumer<T> consumer);

/**
* Add a consumer listener with the specified {@link EventPriority} and potentially cancelled events.
*
Expand Down Expand Up @@ -81,6 +100,18 @@ public interface IEventBus {
*/
<T extends GenericEvent<? extends F>, F> void addGenericListener(Class<F> genericClassFilter, Consumer<T> consumer);

/**
* Add a consumer listener for a {@link GenericEvent} subclass, filtered to only be called for the specified
* filter {@link Class}.
*
* @param genericClassFilter A {@link Class} which the {@link GenericEvent} should be filtered for
* @param eventType The concrete {@link Event} subclass to subscribe to
* @param consumer Callback to invoke when a matching event is received
* @param <T> The {@link GenericEvent} subclass to listen for
* @param <F> The {@link Class} to filter the {@link GenericEvent} for
*/
<T extends GenericEvent<? extends F>, F> void addGenericListener(Class<F> genericClassFilter, Class<T> eventType, Consumer<T> consumer);

/**
* Add a consumer listener with the specified {@link EventPriority} and not receiving cancelled events,
* for a {@link GenericEvent} subclass, filtered to only be called for the specified
Expand All @@ -94,6 +125,19 @@ public interface IEventBus {
*/
<T extends GenericEvent<? extends F>, F> void addGenericListener(Class<F> genericClassFilter, EventPriority priority, Consumer<T> consumer);

/**
* Add a consumer listener with the specified {@link EventPriority} and not receiving cancelled events,
* for a {@link GenericEvent} subclass, filtered to only be called for the specified
* filter {@link Class}.
*
* @param genericClassFilter A {@link Class} which the {@link GenericEvent} should be filtered for
* @param priority {@link EventPriority} for this listener
* @param consumer Callback to invoke when a matching event is received
* @param <T> The {@link GenericEvent} subclass to listen for
* @param <F> The {@link Class} to filter the {@link GenericEvent} for
*/
<T extends GenericEvent<? extends F>, F> void addGenericListener(Class<F> genericClassFilter, EventPriority priority, Class<T> eventType, Consumer<T> consumer);

/**
* Add a consumer listener with the specified {@link EventPriority} and potentially cancelled events,
* for a {@link GenericEvent} subclass, filtered to only be called for the specified
Expand Down

0 comments on commit 69a5fd8

Please sign in to comment.