001 package net.minecraftforge.event; 002 003 import java.lang.reflect.Constructor; 004 import java.lang.reflect.Method; 005 import java.util.ArrayList; 006 import java.util.Set; 007 import java.util.concurrent.ConcurrentHashMap; 008 009 010 011 import com.google.common.reflect.TypeToken; 012 013 public class EventBus 014 { 015 private static int maxID = 0; 016 017 private ConcurrentHashMap<Object, ArrayList<IEventListener>> listeners = new ConcurrentHashMap<Object, ArrayList<IEventListener>>(); 018 private final int busID = maxID++; 019 020 public EventBus() 021 { 022 ListenerList.resize(busID + 1); 023 } 024 025 public void register(Object target) 026 { 027 Set<? extends Class<?>> supers = TypeToken.of(target.getClass()).getTypes().rawTypes(); 028 for (Method method : target.getClass().getMethods()) 029 { 030 for (Class<?> cls : supers) 031 { 032 try 033 { 034 Method real = cls.getDeclaredMethod(method.getName(), method.getParameterTypes()); 035 if (real.isAnnotationPresent(ForgeSubscribe.class)) 036 { 037 Class<?>[] parameterTypes = method.getParameterTypes(); 038 if (parameterTypes.length != 1) 039 { 040 throw new IllegalArgumentException( 041 "Method " + method + " has @ForgeSubscribe annotation, but requires " + parameterTypes.length + 042 " arguments. Event handler methods must require a single argument." 043 ); 044 } 045 046 Class<?> eventType = parameterTypes[0]; 047 048 if (!Event.class.isAssignableFrom(eventType)) 049 { 050 throw new IllegalArgumentException("Method " + method + " has @ForgeSubscribe annotation, but takes a argument that is not a Event " + eventType); 051 } 052 053 register(eventType, target, method); 054 break; 055 } 056 } 057 catch (NoSuchMethodException e) 058 { 059 ; 060 } 061 } 062 } 063 } 064 065 private void register(Class<?> eventType, Object target, Method method) 066 { 067 try 068 { 069 Constructor<?> ctr = eventType.getConstructor(); 070 ctr.setAccessible(true); 071 Event event = (Event)ctr.newInstance(); 072 ASMEventHandler listener = new ASMEventHandler(target, method); 073 event.getListenerList().register(busID, listener.getPriority(), listener); 074 075 ArrayList<IEventListener> others = listeners.get(target); 076 if (others == null) 077 { 078 others = new ArrayList<IEventListener>(); 079 listeners.put(target, others); 080 } 081 others.add(listener); 082 } 083 catch (Exception e) 084 { 085 e.printStackTrace(); 086 } 087 } 088 089 public void unregister(Object object) 090 { 091 ArrayList<IEventListener> list = listeners.remove(object); 092 for (IEventListener listener : list) 093 { 094 ListenerList.unregiterAll(busID, listener); 095 } 096 } 097 098 public boolean post(Event event) 099 { 100 IEventListener[] listeners = event.getListenerList().getListeners(busID); 101 for (IEventListener listener : listeners) 102 { 103 listener.invoke(event); 104 } 105 return (event.isCancelable() ? event.isCanceled() : false); 106 } 107 }