2012-08-05 05:45:31 +00:00
|
|
|
package net.minecraftforge.event;
|
|
|
|
|
2012-09-12 00:49:21 +00:00
|
|
|
import java.lang.reflect.Constructor;
|
2012-08-05 05:45:31 +00:00
|
|
|
import java.lang.reflect.Method;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import com.google.common.reflect.TypeToken;
|
|
|
|
|
|
|
|
public class EventBus
|
|
|
|
{
|
|
|
|
private static int maxID = 0;
|
|
|
|
|
|
|
|
private ConcurrentHashMap<Object, ArrayList<IEventListener>> listeners = new ConcurrentHashMap<Object, ArrayList<IEventListener>>();
|
|
|
|
private final int busID = maxID++;
|
|
|
|
|
|
|
|
public EventBus()
|
|
|
|
{
|
|
|
|
ListenerList.resize(busID + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void register(Object target)
|
|
|
|
{
|
|
|
|
Set<? extends Class<?>> supers = TypeToken.of(target.getClass()).getTypes().rawTypes();
|
|
|
|
for (Method method : target.getClass().getMethods())
|
|
|
|
{
|
|
|
|
for (Class<?> cls : supers)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Method real = cls.getDeclaredMethod(method.getName(), method.getParameterTypes());
|
|
|
|
if (real.isAnnotationPresent(ForgeSubscribe.class))
|
|
|
|
{
|
|
|
|
Class<?>[] parameterTypes = method.getParameterTypes();
|
|
|
|
if (parameterTypes.length != 1)
|
|
|
|
{
|
|
|
|
throw new IllegalArgumentException(
|
|
|
|
"Method " + method + " has @ForgeSubscribe annotation, but requires " + parameterTypes.length +
|
|
|
|
" arguments. Event handler methods must require a single argument."
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Class<?> eventType = parameterTypes[0];
|
|
|
|
|
|
|
|
if (!Event.class.isAssignableFrom(eventType))
|
|
|
|
{
|
|
|
|
throw new IllegalArgumentException("Method " + method + " has @ForgeSubscribe annotation, but takes a argument that is not a Event " + eventType);
|
|
|
|
}
|
|
|
|
|
|
|
|
register(eventType, target, method);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (NoSuchMethodException e)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void register(Class<?> eventType, Object target, Method method)
|
|
|
|
{
|
|
|
|
try
|
2012-09-12 00:49:21 +00:00
|
|
|
{
|
|
|
|
Constructor<?> ctr = eventType.getConstructor();
|
|
|
|
ctr.setAccessible(true);
|
|
|
|
Event event = (Event)ctr.newInstance();
|
2012-08-05 05:45:31 +00:00
|
|
|
ASMEventHandler listener = new ASMEventHandler(target, method);
|
|
|
|
event.getListenerList().register(busID, listener.getPriority(), listener);
|
2012-09-12 00:49:21 +00:00
|
|
|
|
2012-08-05 05:45:31 +00:00
|
|
|
ArrayList<IEventListener> others = listeners.get(target);
|
|
|
|
if (others == null)
|
|
|
|
{
|
|
|
|
others = new ArrayList<IEventListener>();
|
|
|
|
listeners.put(target, others);
|
|
|
|
}
|
|
|
|
others.add(listener);
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void unregister(Object object)
|
|
|
|
{
|
|
|
|
ArrayList<IEventListener> list = listeners.remove(object);
|
|
|
|
for (IEventListener listener : list)
|
|
|
|
{
|
|
|
|
ListenerList.unregiterAll(busID, listener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-07 08:24:06 +00:00
|
|
|
public boolean post(Event event)
|
2012-08-05 05:45:31 +00:00
|
|
|
{
|
|
|
|
IEventListener[] listeners = event.getListenerList().getListeners(busID);
|
|
|
|
for (IEventListener listener : listeners)
|
|
|
|
{
|
|
|
|
listener.invoke(event);
|
|
|
|
}
|
2012-08-07 08:24:06 +00:00
|
|
|
return (event.isCancelable() ? event.isCanceled() : false);
|
2012-08-05 05:45:31 +00:00
|
|
|
}
|
|
|
|
}
|