Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.function.Consumer;

import net.minecraftforge.fml.common.ModContainer;

Expand All @@ -32,10 +33,10 @@ public class ASMEventHandler implements IEventListener
{
private static final boolean GETCONTEXT = Boolean.parseBoolean(System.getProperty("fml.LogContext", "false"));

private final IEventListener handler;
private final Consumer<Event> handler;
private final SubscribeEvent subInfo;
private ModContainer owner;
private String readable;
private final ModContainer owner;
private final String readable;

@Deprecated
public ASMEventHandler(Object target, Method method, ModContainer owner) throws Exception
Expand All @@ -58,7 +59,7 @@ public ASMEventHandler(Object target, Method method, ModContainer owner, boolean
var filter = parameterized.getActualTypeArguments()[0];
this.handler = event -> {
if (filter == ((IGenericEvent<?>) event).getGenericType()) {
rawHandler.invoke(event);
rawHandler.accept(event);
}
};
} else {
Expand All @@ -75,7 +76,7 @@ public void invoke(Event event)
{
if (!event.isCancelable() || !event.isCanceled() || subInfo.receiveCanceled())
{
handler.invoke(event);
handler.accept(event);
}
}
if (GETCONTEXT)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ public void register(Object target)
}
}

/// Some mods will intentionally call this method with illegal `method` object (whose param type is `Object` instead of subclass of `Event`), and we have to allow this stupid move
private void register(Class<?> eventType, Object target, Method method, final ModContainer owner)
{
try
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,29 @@
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

/**
* @author ZZZank
*/
class EventListenerFactory {
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();

public static IEventListener createRawListener(Method method, boolean isStatic, Object instance) {
public static Consumer<Event> createRawListener(Method method, boolean isStatic, Object instance) {
// no caching is applied here because in EventBus scenario, caching will only be useful
// when two instance-based listeners of the same class are registered, which is an
// incredibly rare usage in 1.12 Forge environment
var listenerFactory = createListenerFactory(method, isStatic, instance);

try {
return isStatic
? (IEventListener) listenerFactory.invokeExact()
: (IEventListener) listenerFactory.invokeExact(instance);
@SuppressWarnings("unchecked")
var rawListener = isStatic
? (Consumer<Event>) listenerFactory.invokeExact()
: (Consumer<Event>) listenerFactory.invokeExact(instance);
return rawListener;
} catch (Throwable t) {
throw new RuntimeException(t);
}
Expand Down Expand Up @@ -60,8 +64,11 @@ private static MethodHandle createListenerFactory(
}

interface Constants {
Class<?> CLAZZ = IEventListener.class;
Method METHOD = CLAZZ.getMethods()[0];
Class<?> CLAZZ = Consumer.class;
Method METHOD = Arrays.stream(CLAZZ.getMethods())
.filter(m -> "accept".equals(m.getName()))
.findFirst()
.orElseThrow();
String METHOD_NAME = METHOD.getName();
MethodType METHOD_TYPE = MethodType.methodType(METHOD.getReturnType(), METHOD.getParameterTypes());
MethodType RETURNS_IT = MethodType.methodType(CLAZZ);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package net.minecraftforge.fml.common.eventhandler;

import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.ModContainer;
import net.minecraftforge.fml.common.eventhandler.impl.AbnormalListeners;
import net.minecraftforge.fml.common.eventhandler.impl.ExampleEvent;
import net.minecraftforge.fml.common.eventhandler.impl.InstanceListeners;
import net.minecraftforge.fml.common.eventhandler.impl.StaticListeners;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Method;
import java.util.List;

/**
Expand Down Expand Up @@ -58,4 +61,29 @@ public void registerAbnormal() {

Assertions.assertTrue(AbnormalListeners.nonVoid, "listener with non-void return type is valid");
}

@Test
public void registerIllegalParamType() throws Exception {
var bus = new EventBus();

var listener = new AbnormalListeners.IllegalParamType();

var method = EventBus.class.getDeclaredMethod(
"register",
Class.class, Object.class, Method.class, ModContainer.class
);
method.setAccessible(true);
method.invoke(
bus,
ExampleEvent.class,
listener,
AbnormalListeners.IllegalParamType.class.getMethod("onEvent", Object.class),
Loader.instance().getMinecraftModContainer()
);

var event = new ExampleEvent();
bus.post(event);

Assertions.assertEquals(event.id, listener.captured);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,14 @@ public static Object nonVoidReturn(ExampleEvent event) {
return null;
}
}

public static class IllegalParamType {
public Integer captured = null;

@SubscribeEvent
public void onEvent(Object event) {
var casted = (ExampleEvent) event;
captured = casted.id;
}
}
}