package ameba.event;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author icode
*/
public class BasicEventBus<Event extends ameba.event.Event> implements EventBus<Event> {
private static final Logger logger = LoggerFactory.getLogger(EventBus.class);
private final Map<Class<? extends Event>, CopyOnWriteArrayList<Listener<? extends Event>>> listeners
= Maps.newConcurrentMap();
public <E extends Event> void subscribe(Class<E> event, final Listener<E> listener) {
listeners.computeIfAbsent(event, k -> Lists.newCopyOnWriteArrayList()).add(listener);
}
public <E extends Event> void unsubscribe(Class<E> event, final Listener<E> listener) {
CopyOnWriteArrayList<Listener<? extends Event>> ls = listeners.get(event);
if (ls != null)
ls.remove(listener);
}
public <E extends Event> void unsubscribe(Class<E> event) {
listeners.remove(event);
}
@SuppressWarnings("unchecked")
public <E extends Event> void publish(E event) {
CopyOnWriteArrayList ls = listeners.get(event.getClass());
if (ls != null) {
ls.forEach(listener -> {
try {
((Listener<E>) listener).onReceive(event);
} catch (Exception e) {
logger.error(event.getClass().getName() + " event handler has a error", e);
}
});
}
}
}