Implement usage of EventPriority in EventBus

This commit is contained in:
Dabo Ross 2013-09-05 01:55:44 -07:00 committed by md_5
parent d3c1acce83
commit 0f06b2c4e0

View File

@ -15,7 +15,7 @@ import java.util.logging.Logger;
public class EventBus public class EventBus
{ {
private final Map<Class<?>, Map<Object, Method[]>> eventToHandler = new HashMap<>(); private final Map<Class<?>, Map<EventPriority, Map<Object, Method[]>>> eventToHandler = new HashMap<>();
private final ReadWriteLock lock = new ReentrantReadWriteLock(); private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Logger logger; private final Logger logger;
@ -34,25 +34,29 @@ public class EventBus
lock.readLock().lock(); lock.readLock().lock();
try try
{ {
Map<Object, Method[]> handlers = eventToHandler.get( event.getClass() ); Map<EventPriority, Map<Object, Method[]>> handlersByPriority = eventToHandler.get( event.getClass() );
if ( handlers != null ) for ( EventPriority value : EventPriority.values() )
{ {
for ( Map.Entry<Object, Method[]> handler : handlers.entrySet() ) Map<Object, Method[]> handlers = handlersByPriority.get( value );
if ( handlers != null )
{ {
for ( Method method : handler.getValue() ) for ( Map.Entry<Object, Method[]> handler : handlers.entrySet() )
{ {
try for ( Method method : handler.getValue() )
{ {
method.invoke( handler.getKey(), event ); try
} catch ( IllegalAccessException ex ) {
{ method.invoke( handler.getKey(), event );
throw new Error( "Method became inaccessible: " + event, ex ); } catch ( IllegalAccessException ex )
} catch ( IllegalArgumentException ex ) {
{ throw new Error( "Method became inaccessible: " + event, ex );
throw new Error( "Method rejected target/argument: " + event, ex ); } catch ( IllegalArgumentException ex )
} catch ( InvocationTargetException ex ) {
{ throw new Error( "Method rejected target/argument: " + event, ex );
logger.log( Level.WARNING, MessageFormat.format( "Error dispatching event {0} to listener {1}", event, handler.getKey() ), ex.getCause() ); } catch ( InvocationTargetException ex )
{
logger.log( Level.WARNING, MessageFormat.format( "Error dispatching event {0} to listener {1}", event, handler.getKey() ), ex.getCause() );
}
} }
} }
} }
@ -63,9 +67,9 @@ public class EventBus
} }
} }
private Map<Class<?>, Set<Method>> findHandlers(Object listener) private Map<Class<?>, Map<EventPriority, Set<Method>>> findHandlers(Object listener)
{ {
Map<Class<?>, Set<Method>> handler = new HashMap<>(); Map<Class<?>, Map<EventPriority, Set<Method>>> handler = new HashMap<>();
for ( Method m : listener.getClass().getDeclaredMethods() ) for ( Method m : listener.getClass().getDeclaredMethods() )
{ {
EventHandler annotation = m.getAnnotation( EventHandler.class ); EventHandler annotation = m.getAnnotation( EventHandler.class );
@ -80,14 +84,19 @@ public class EventBus
} ); } );
continue; continue;
} }
Map<EventPriority, Set<Method>> prioritiesMap = handler.get( params[0] );
Set<Method> existing = handler.get( params[0] ); if ( prioritiesMap == null )
if ( existing == null )
{ {
existing = new HashSet<>(); prioritiesMap = new HashMap<>();
handler.put( params[0], existing ); handler.put( params[0], prioritiesMap );
} }
existing.add( m ); Set<Method> priority = prioritiesMap.get( annotation.priority() );
if ( priority == null )
{
priority = new HashSet<>();
prioritiesMap.put( annotation.priority(), priority );
}
priority.add( m );
} }
} }
return handler; return handler;
@ -95,20 +104,29 @@ public class EventBus
public void register(Object listener) public void register(Object listener)
{ {
Map<Class<?>, Set<Method>> handler = findHandlers( listener ); Map<Class<?>, Map<EventPriority, Set<Method>>> handler = findHandlers( listener );
lock.writeLock().lock(); lock.writeLock().lock();
try try
{ {
for ( Map.Entry<Class<?>, Set<Method>> e : handler.entrySet() ) for ( Map.Entry<Class<?>, Map<EventPriority, Set<Method>>> e : handler.entrySet() )
{ {
Map<Object, Method[]> a = eventToHandler.get( e.getKey() ); Map<EventPriority, Map<Object, Method[]>> prioritiesMap = eventToHandler.get( e.getKey() );
if ( a == null ) if ( prioritiesMap == null )
{ {
a = new HashMap<>(); prioritiesMap = new HashMap<>();
eventToHandler.put( e.getKey(), a ); eventToHandler.put( e.getKey(), prioritiesMap );
}
for ( Map.Entry<EventPriority, Set<Method>> entry : e.getValue().entrySet() )
{
Map<Object, Method[]> currentPriorityMap = prioritiesMap.get( entry.getKey() );
if ( currentPriorityMap == null )
{
currentPriorityMap = new HashMap<>();
prioritiesMap.put( entry.getKey(), currentPriorityMap );
}
Method[] baked = new Method[ entry.getValue().size() ];
currentPriorityMap.put( listener, entry.getValue().toArray( baked ) );
} }
Method[] baked = new Method[ e.getValue().size() ];
a.put( listener, e.getValue().toArray( baked ) );
} }
} finally } finally
{ {
@ -118,17 +136,28 @@ public class EventBus
public void unregister(Object listener) public void unregister(Object listener)
{ {
Map<Class<?>, Set<Method>> handler = findHandlers( listener ); Map<Class<?>, Map<EventPriority, Set<Method>>> handler = findHandlers( listener );
lock.writeLock().lock(); lock.writeLock().lock();
try try
{ {
for ( Map.Entry<Class<?>, Set<Method>> e : handler.entrySet() ) for ( Map.Entry<Class<?>, Map<EventPriority, Set<Method>>> e : handler.entrySet() )
{ {
Map<Object, Method[]> a = eventToHandler.get( e.getKey() ); Map<EventPriority, Map<Object, Method[]>> prioritiesMap = eventToHandler.get( e.getKey() );
if ( a != null ) if ( prioritiesMap != null )
{ {
a.remove( listener ); for ( EventPriority priority : e.getValue().keySet() )
if ( a.isEmpty() ) {
Map<Object, Method[]> currentPriority = prioritiesMap.get( priority );
if ( currentPriority != null )
{
currentPriority.remove( listener );
if ( currentPriority.isEmpty() )
{
prioritiesMap.remove( priority );
}
}
}
if ( prioritiesMap.isEmpty() )
{ {
eventToHandler.remove( e.getKey() ); eventToHandler.remove( e.getKey() );
} }