diff --git a/src/main/java/net/minecraftforge/event/AttachCapabilitiesEvent.java b/src/main/java/net/minecraftforge/event/AttachCapabilitiesEvent.java index fd8bfa05de..eb0dcc414b 100644 --- a/src/main/java/net/minecraftforge/event/AttachCapabilitiesEvent.java +++ b/src/main/java/net/minecraftforge/event/AttachCapabilitiesEvent.java @@ -26,7 +26,7 @@ import com.google.common.collect.Maps; import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.capabilities.ICapabilityProvider; -import net.minecraftforge.fml.common.eventhandler.Event; +import net.minecraftforge.fml.common.eventhandler.GenericEvent; /** * Fired whenever an object with Capabilities support {currently TileEntity/Item/Entity) @@ -35,20 +35,28 @@ import net.minecraftforge.fml.common.eventhandler.Event; * Please note that as this is fired for ALL object creations efficient code is recommended. * And if possible use one of the sub-classes to filter your intended objects. */ -public class AttachCapabilitiesEvent extends Event +public class AttachCapabilitiesEvent extends GenericEvent { - private final Object obj; + private final T obj; private final Map caps = Maps.newLinkedHashMap(); private final Map view = Collections.unmodifiableMap(caps); - public AttachCapabilitiesEvent(Object obj) + + @SuppressWarnings("unchecked") + @Deprecated + public AttachCapabilitiesEvent(T obj) { + this((Class)Object.class, obj); + } + public AttachCapabilitiesEvent(Class type, T obj) + { + super(type); this.obj = obj; } /** * Retrieves the object that is being created, Not much state is set. */ - public Object getObject() + public T getObject() { return this.obj; } @@ -80,12 +88,13 @@ public class AttachCapabilitiesEvent extends Event /** * A version of the parent event which is only fired for Tile Entities. */ - public static class TileEntity extends AttachCapabilitiesEvent + @Deprecated + public static class TileEntity extends AttachCapabilitiesEvent { private final net.minecraft.tileentity.TileEntity te; public TileEntity(net.minecraft.tileentity.TileEntity te) { - super(te); + super(net.minecraft.tileentity.TileEntity.class, te); this.te = te; } public net.minecraft.tileentity.TileEntity getTileEntity() @@ -97,12 +106,13 @@ public class AttachCapabilitiesEvent extends Event /** * A version of the parent event which is only fired for Entities. */ - public static class Entity extends AttachCapabilitiesEvent + @Deprecated + public static class Entity extends AttachCapabilitiesEvent { private final net.minecraft.entity.Entity entity; public Entity(net.minecraft.entity.Entity entity) { - super(entity); + super(net.minecraft.entity.Entity.class, entity); this.entity = entity; } public net.minecraft.entity.Entity getEntity() @@ -114,16 +124,18 @@ public class AttachCapabilitiesEvent extends Event /** * A version of the parent event which is only fired for ItemStacks. */ - public static class Item extends AttachCapabilitiesEvent + public static class Item extends AttachCapabilitiesEvent { + @Deprecated private final net.minecraft.item.ItemStack stack; private final net.minecraft.item.Item item; public Item(net.minecraft.item.Item item, net.minecraft.item.ItemStack stack) { - super(item); + super(net.minecraft.item.Item.class, item); this.item = item; this.stack = stack; } + @Deprecated public net.minecraft.item.Item getItem() { return this.item; @@ -137,12 +149,13 @@ public class AttachCapabilitiesEvent extends Event /** * A version of the parent event which is only fired for Worlds. */ - public static class World extends AttachCapabilitiesEvent + @Deprecated + public static class World extends AttachCapabilitiesEvent { private final net.minecraft.world.World world; public World(net.minecraft.world.World world) { - super(world); + super(net.minecraft.world.World.class, world); this.world = world; } public net.minecraft.world.World getWorld() 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 41edc0a661..9394b4191e 100644 --- a/src/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java +++ b/src/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java @@ -23,6 +23,7 @@ import static org.objectweb.asm.Opcodes.*; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; import java.util.HashMap; import net.minecraftforge.fml.common.ModContainer; @@ -34,7 +35,6 @@ import org.objectweb.asm.Type; import com.google.common.collect.Maps; - public class ASMEventHandler implements IEventListener { private static int IDs = 0; @@ -48,8 +48,15 @@ public class ASMEventHandler implements IEventListener private final SubscribeEvent subInfo; private ModContainer owner; private String readable; + private java.lang.reflect.Type filter = null; + @Deprecated public ASMEventHandler(Object target, Method method, ModContainer owner) throws Exception + { + this(target, method, owner, false); + } + + public ASMEventHandler(Object target, Method method, ModContainer owner, boolean isGeneric) throws Exception { this.owner = owner; if (Modifier.isStatic(method.getModifiers())) @@ -58,8 +65,19 @@ public class ASMEventHandler implements IEventListener handler = (IEventListener)createWrapper(method).getConstructor(Object.class).newInstance(target); subInfo = method.getAnnotation(SubscribeEvent.class); readable = "ASM: " + target + " " + method.getName() + Type.getMethodDescriptor(method); + if (isGeneric) + { + java.lang.reflect.Type type = method.getGenericParameterTypes()[0]; + System.currentTimeMillis(); + if (type instanceof ParameterizedType) + { + filter = ((ParameterizedType)type).getActualTypeArguments()[0]; + System.currentTimeMillis(); + } + } } + @SuppressWarnings("rawtypes") @Override public void invoke(Event event) { @@ -69,7 +87,10 @@ public class ASMEventHandler implements IEventListener { if (!event.isCancelable() || !event.isCanceled() || subInfo.receiveCanceled()) { - handler.invoke(event); + if (filter == null || filter == ((IGenericEvent)event).getGenericType()) + { + handler.invoke(event); + } } } if (GETCONTEXT) 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 7a83be48ed..651e3d4637 100644 --- a/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java +++ b/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java @@ -129,7 +129,7 @@ public class EventBus implements IEventExceptionHandler Constructor ctr = eventType.getConstructor(); ctr.setAccessible(true); Event event = (Event)ctr.newInstance(); - ASMEventHandler listener = new ASMEventHandler(target, method, owner); + ASMEventHandler listener = new ASMEventHandler(target, method, owner, IGenericEvent.class.isAssignableFrom(eventType)); event.getListenerList().register(busID, listener.getPriority(), listener); ArrayList others = listeners.get(target); diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/GenericEvent.java b/src/main/java/net/minecraftforge/fml/common/eventhandler/GenericEvent.java new file mode 100644 index 0000000000..8e6f07bcf2 --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/common/eventhandler/GenericEvent.java @@ -0,0 +1,36 @@ +/* + * Minecraft Forge + * Copyright (c) 2016. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package net.minecraftforge.fml.common.eventhandler; + +import java.lang.reflect.Type; + +public class GenericEvent extends Event implements IGenericEvent +{ + private Class type; + protected GenericEvent(Class type) + { + this.type = type; + } + + @Override + public Type getGenericType() + { + return type; + } +} diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/IGenericEvent.java b/src/main/java/net/minecraftforge/fml/common/eventhandler/IGenericEvent.java new file mode 100644 index 0000000000..9b0e5572ed --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/common/eventhandler/IGenericEvent.java @@ -0,0 +1,26 @@ +/* + * Minecraft Forge + * Copyright (c) 2016. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package net.minecraftforge.fml.common.eventhandler; + +import java.lang.reflect.Type; + +public interface IGenericEvent +{ + Type getGenericType(); +} diff --git a/src/test/java/net/minecraftforge/test/TestCapabilityMod.java b/src/test/java/net/minecraftforge/test/TestCapabilityMod.java index 1c14bd0b4d..3ecc79dce1 100644 --- a/src/test/java/net/minecraftforge/test/TestCapabilityMod.java +++ b/src/test/java/net/minecraftforge/test/TestCapabilityMod.java @@ -112,6 +112,20 @@ public class TestCapabilityMod event.addCapability(new ResourceLocation("TestCapabilityMod:DummyCap"), new Provider(event.getTileEntity())); } + @SuppressWarnings("rawtypes") + @SubscribeEvent + public void attachEvent(AttachCapabilitiesEvent event) //Test Raw type gets everything still. + { + System.currentTimeMillis(); + } + + @SubscribeEvent + public void attachTileEntity(AttachCapabilitiesEvent event) + { + if (!(event.getObject() instanceof TileEntity)) + throw new IllegalArgumentException("Generic event handler failed! Exprected Tile Entity got " + event.getObject()); + } + // Capabilities SHOULD be interfaces, NOT concrete classes, this allows for // the most flexibility for the implementors. public static interface IExampleCapability