Add support for generic filtering of events.
Please DO NOT use this in performance sensitive environments where you will have tons of things added to the listener list. If that's the case define sub-classes as they have completely separate lists and will thus be more efficient when firing the event.
This commit is contained in:
parent
c58a66a816
commit
1107088acb
|
@ -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<T> extends GenericEvent<T>
|
||||
{
|
||||
private final Object obj;
|
||||
private final T obj;
|
||||
private final Map<ResourceLocation, ICapabilityProvider> caps = Maps.newLinkedHashMap();
|
||||
private final Map<ResourceLocation, ICapabilityProvider> view = Collections.unmodifiableMap(caps);
|
||||
public AttachCapabilitiesEvent(Object obj)
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Deprecated
|
||||
public AttachCapabilitiesEvent(T obj)
|
||||
{
|
||||
this((Class<T>)Object.class, obj);
|
||||
}
|
||||
public AttachCapabilitiesEvent(Class<T> 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<net.minecraft.tileentity.TileEntity>
|
||||
{
|
||||
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<net.minecraft.entity.Entity>
|
||||
{
|
||||
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<net.minecraft.item.Item>
|
||||
{
|
||||
@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<net.minecraft.world.World>
|
||||
{
|
||||
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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<IEventListener> others = listeners.get(target);
|
||||
|
|
|
@ -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<T> extends Event implements IGenericEvent<T>
|
||||
{
|
||||
private Class<T> type;
|
||||
protected GenericEvent(Class<T> type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getGenericType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
|
@ -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<T>
|
||||
{
|
||||
Type getGenericType();
|
||||
}
|
|
@ -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<TileEntity> 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
|
||||
|
|
Loading…
Reference in New Issue