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