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); } }); } } }