diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java b/src/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java index 1523e61a88..41edc0a661 100644 --- a/src/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java +++ b/src/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java @@ -22,6 +22,7 @@ package net.minecraftforge.fml.common.eventhandler; import static org.objectweb.asm.Opcodes.*; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.HashMap; import net.minecraftforge.fml.common.ModContainer; @@ -51,7 +52,10 @@ public class ASMEventHandler implements IEventListener public ASMEventHandler(Object target, Method method, ModContainer owner) throws Exception { this.owner = owner; - handler = (IEventListener)createWrapper(method).getConstructor(Object.class).newInstance(target); + if (Modifier.isStatic(method.getModifiers())) + handler = (IEventListener)createWrapper(method).newInstance(); + else + handler = (IEventListener)createWrapper(method).getConstructor(Object.class).newInstance(target); subInfo = method.getAnnotation(SubscribeEvent.class); readable = "ASM: " + target + " " + method.getName() + Type.getMethodDescriptor(method); } @@ -87,6 +91,7 @@ public class ASMEventHandler implements IEventListener ClassWriter cw = new ClassWriter(0); MethodVisitor mv; + boolean isStatic = Modifier.isStatic(callback.getModifiers()); String name = getUniqueName(callback); String desc = name.replace('.', '/'); String instType = Type.getInternalName(callback.getDeclaringClass()); @@ -104,16 +109,20 @@ public class ASMEventHandler implements IEventListener cw.visitSource(".dynamic", null); { - cw.visitField(ACC_PUBLIC, "instance", "Ljava/lang/Object;", null, null).visitEnd(); + if (!isStatic) + cw.visitField(ACC_PUBLIC, "instance", "Ljava/lang/Object;", null, null).visitEnd(); } { - mv = cw.visitMethod(ACC_PUBLIC, "", "(Ljava/lang/Object;)V", null, null); + mv = cw.visitMethod(ACC_PUBLIC, "", isStatic ? "()V" : "(Ljava/lang/Object;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 1); - mv.visitFieldInsn(PUTFIELD, desc, "instance", "Ljava/lang/Object;"); + if (!isStatic) + { + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitFieldInsn(PUTFIELD, desc, "instance", "Ljava/lang/Object;"); + } mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); @@ -122,11 +131,14 @@ public class ASMEventHandler implements IEventListener mv = cw.visitMethod(ACC_PUBLIC, "invoke", HANDLER_FUNC_DESC, null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, desc, "instance", "Ljava/lang/Object;"); - mv.visitTypeInsn(CHECKCAST, instType); + if (!isStatic) + { + mv.visitFieldInsn(GETFIELD, desc, "instance", "Ljava/lang/Object;"); + mv.visitTypeInsn(CHECKCAST, instType); + } mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, eventType); - mv.visitMethodInsn(INVOKEVIRTUAL, instType, callback.getName(), Type.getMethodDescriptor(callback), false); + mv.visitMethodInsn(isStatic ? INVOKESTATIC : INVOKEVIRTUAL, instType, callback.getName(), Type.getMethodDescriptor(callback), false); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java b/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java index 17b8137a97..7a83be48ed 100644 --- a/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java +++ b/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java @@ -21,6 +21,7 @@ package net.minecraftforge.fml.common.eventhandler; import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Map; import java.util.Set; @@ -37,6 +38,7 @@ import org.apache.logging.log4j.Level; import com.google.common.base.Preconditions; import com.google.common.base.Throwables; import com.google.common.collect.MapMaker; +import com.google.common.collect.Sets; import com.google.common.reflect.TypeToken; public class EventBus implements IEventExceptionHandler @@ -75,9 +77,16 @@ public class EventBus implements IEventExceptionHandler activeModContainer = Loader.instance().getMinecraftModContainer(); } listenerOwners.put(target, activeModContainer); - Set> supers = TypeToken.of(target.getClass()).getTypes().rawTypes(); - for (Method method : target.getClass().getMethods()) + boolean isStatic = target.getClass() == Class.class; + @SuppressWarnings("unchecked") + Set> supers = isStatic ? Sets.newHashSet((Class)target) : TypeToken.of(target.getClass()).getTypes().rawTypes(); + for (Method method : (isStatic ? (Class)target : target.getClass()).getMethods()) { + if (isStatic && !Modifier.isStatic(method.getModifiers())) + continue; + else if (!isStatic && Modifier.isStatic(method.getModifiers())) + continue; + for (Class cls : supers) { try diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/ListenerList.java b/src/main/java/net/minecraftforge/fml/common/eventhandler/ListenerList.java index d13077cd1b..a257af7154 100644 --- a/src/main/java/net/minecraftforge/fml/common/eventhandler/ListenerList.java +++ b/src/main/java/net/minecraftforge/fml/common/eventhandler/ListenerList.java @@ -21,6 +21,7 @@ package net.minecraftforge.fml.common.eventhandler; import java.util.*; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; public class ListenerList @@ -139,6 +140,8 @@ public class ListenerList private IEventListener[] listeners; private ArrayList> priorities; private ListenerListInst parent; + private List children; + private ListenerListInst() { @@ -160,12 +163,15 @@ public class ListenerList priorities.clear(); parent = null; listeners = null; + if (children != null) + children.clear(); } private ListenerListInst(ListenerListInst parent) { this(); this.parent = parent; + this.parent.addChild(this); } /** @@ -205,7 +211,24 @@ public class ListenerList protected boolean shouldRebuild() { - return rebuild || (parent != null && parent.shouldRebuild()); + return rebuild;// || (parent != null && parent.shouldRebuild()); + } + + protected void forceRebuild() + { + this.rebuild = true; + if (this.children != null) + { + for (ListenerListInst child : this.children) + child.forceRebuild(); + } + } + + private void addChild(ListenerListInst child) + { + if (this.children == null) + this.children = Lists.newArrayList(); + this.children.add(child); } /** @@ -235,7 +258,7 @@ public class ListenerList public void register(EventPriority priority, IEventListener listener) { priorities.get(priority.ordinal()).add(listener); - rebuild = true; + this.forceRebuild(); } public void unregister(IEventListener listener) @@ -244,7 +267,7 @@ public class ListenerList { if (list.remove(listener)) { - rebuild = true; + this.forceRebuild(); } } } diff --git a/src/test/java/net/minecraftforge/test/PlayerInteractEventTest.java b/src/test/java/net/minecraftforge/test/PlayerInteractEventTest.java index 271086f15b..c10fcd6fff 100644 --- a/src/test/java/net/minecraftforge/test/PlayerInteractEventTest.java +++ b/src/test/java/net/minecraftforge/test/PlayerInteractEventTest.java @@ -32,6 +32,7 @@ public class PlayerInteractEventTest { logger = event.getModLog(); MinecraftForge.EVENT_BUS.register(this); + MinecraftForge.EVENT_BUS.register(PlayerInteractEventTest.class); // Test Static event listeners } @SubscribeEvent(receiveCanceled = true) // this triggers after the subclasses below, and we'd like to log them all @@ -142,7 +143,7 @@ public class PlayerInteractEventTest } @SubscribeEvent - public void interactNormal(PlayerInteractEvent.EntityInteract evt) + public static void interactNormal(PlayerInteractEvent.EntityInteract evt) { if (!ENABLE) return;