mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 16:27:47 +00:00
Added support for using static methods as event listeners, Register the .class instead of an instance.
And added an improvement to calltime listener rebuilding.
This commit is contained in:
1 parent
57ed697cab
commit
5f234fdcf8
4 files changed
+60
-15
No files matched your search
@@ -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, "<init>", "(Ljava/lang/Object;)V", null, null);
|
||||
mv = cw.visitMethod(ACC_PUBLIC, "<init>", isStatic ? "()V" : "(Ljava/lang/Object;)V", null, null);
|
||||
mv.visitCode();
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()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();
|
||||
|
||||
@@ -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<? extends Class<?>> supers = TypeToken.of(target.getClass()).getTypes().rawTypes();
|
||||
for (Method method : target.getClass().getMethods())
|
||||
boolean isStatic = target.getClass() == Class.class;
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<? extends Class<?>> 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
|
||||
|
||||
@@ -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<ArrayList<IEventListener>> priorities;
|
||||
private ListenerListInst parent;
|
||||
private List<ListenerListInst> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user