package net.minecraftforge.event; import java.lang.reflect.Constructor; 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> listeners = new ConcurrentHashMap>(); private final int busID = maxID++; public EventBus() { ListenerList.resize(busID + 1); } public void register(Object target) { Set> 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 { Constructor ctr = eventType.getConstructor(); ctr.setAccessible(true); Event event = (Event)ctr.newInstance(); ASMEventHandler listener = new ASMEventHandler(target, method); event.getListenerList().register(busID, listener.getPriority(), listener); ArrayList others = listeners.get(target); if (others == null) { others = new ArrayList(); listeners.put(target, others); } others.add(listener); } catch (Exception e) { e.printStackTrace(); } } public void unregister(Object object) { ArrayList list = listeners.remove(object); for (IEventListener listener : list) { ListenerList.unregiterAll(busID, listener); } } public boolean post(Event event) { IEventListener[] listeners = event.getListenerList().getListeners(busID); for (IEventListener listener : listeners) { listener.invoke(event); } return (event.isCancelable() ? event.isCanceled() : false); } }