package com.github.shansun.sparrow.event.impl;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.github.shansun.sparrow.event.Event;
import com.github.shansun.sparrow.event.EventListener;
import com.github.shansun.sparrow.event.EventPublisher;
import com.google.common.collect.MapMaker;
/**
* @author: lanbo <br>
* @version: 1.0 <br>
* @date: 2012-6-6
*/
public final class SyncEventPublisher implements EventPublisher {
private final Listeners listeners = new Listeners();
private static SyncEventPublisher instance = new SyncEventPublisher();
private SyncEventPublisher() {
// Singleton
}
public static SyncEventPublisher getInstance() {
return instance;
}
@Override
public void publish(final Event event) {
checkNotNull(event);
Iterator<EventListener> iterator = listeners.get(event.getClass());
while (iterator.hasNext()) {
iterator.next().onEvent(event);
}
}
@Override
public void register(final EventListener listener) {
checkNotNull(listener);
listeners.register(listener);
}
@Override
public void unregister(final EventListener listener) {
checkNotNull(listener);
listeners.remove(listener);
}
public void unregisterAll() {
listeners.clear();
}
static final class Listeners {
private final Map<Class<?>, List<EventListener>> invokers = new MapMaker().makeMap();
private void register(final EventListener listener) {
@SuppressWarnings("rawtypes")
Class[] eventClasses = listener.getHandledEventClasses();
checkNotNull(eventClasses, "监听者必须指定感兴趣的事件类型!");
for (Class<? extends Event> event : eventClasses) {
List<EventListener> list = invokers.get(eventClasses);
if (list == null) {
list = new ArrayList<EventListener>();
}
list.add(listener);
invokers.put(event, list);
}
}
void remove(final EventListener listener) {
for (Entry<Class<?>, List<EventListener>> entry : invokers.entrySet()) {
entry.getValue().remove(listener);
}
}
void clear() {
invokers.clear();
}
public Iterator<EventListener> get(final Class<? extends Event> eventClass) {
return invokers.get(eventClass).iterator();
}
}
}