Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
*
*/
package rinde.sim.event;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Sets.newHashSet;
import static java.util.Arrays.asList;
import java.util.HashSet;
import java.util.Set;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
/**
* Basic event dispatcher for easily dispatching {@link Event}s to
* {@link Listener}s. It provides methods for dispatching events and removing
* and adding of listeners.
* @author Rinde van Lon
*/
public class EventDispatcher implements EventAPI {
/**
* A map of event types to registered {@link Listener}s.
*/
protected final Multimap, Listener> listeners;
/**
* The set of event types that this event dispatcher supports.
*/
protected final Set> supportedTypes;
/**
* The 'public' api of this dispatcher. Public in this context means API
* that is intended for users of the dispatcher, that is, classes
* that want to be notified of events.
*/
protected final PublicEventAPI publicAPI;
/**
* Creates a new {@link EventDispatcher} instance which is capable of
* dispatching any {@link Event} with a type attribute that is
* one of eventTypes.
* @param supportedEventTypes The types of events this EventDispatcher
* supports.
*/
public EventDispatcher(Set> supportedEventTypes) {
checkArgument(supportedEventTypes != null, "event types can not be null");
listeners = LinkedHashMultimap.create();
supportedTypes = newHashSet(supportedEventTypes);
publicAPI = new PublicEventAPI(this);
}
/**
* Creates a new {@link EventDispatcher} instance which is capable of
* dispatching any {@link Event} with a type attribute that is
* one of eventTypes.
* @param supportedEventTypes The types of events this EventDispatcher
* supports.
*/
public EventDispatcher(Enum>... supportedEventTypes) {
this(new HashSet>(asList(supportedEventTypes)));
}
/**
* Dispatch an event. Notifies all listeners that are listening for this
* type of event.
* @param e The event to be dispatched, only events with a supported type
* can be dispatched.
*/
public void dispatchEvent(Event e) {
if (e == null) {
throw new IllegalArgumentException("event can not be null");
}
checkArgument(supportedTypes.contains(e.getEventType()), "Cannot dispatch an event of type %s since it was not registered at this dispatcher.", e
.getEventType());
for (final Listener l : listeners.get(e.getEventType())) {
l.handleEvent(e);
}
}
/**
* {@inheritDoc}
*/
@Override
public void addListener(Listener listener, Enum>... eventTypes) {
checkArgument(eventTypes != null, "event types can not be null");
addListener(listener, newHashSet(eventTypes), eventTypes.length == 0);
}
/**
* {@inheritDoc}
*/
@Override
public void addListener(Listener listener, Set> eventTypes) {
addListener(listener, eventTypes, false);
}
/**
* Adds the specified listener. From now on, the specified listener will be
* notified of events with one of the eventTypes. If
* eventTypes is empty, the listener will be notified of no
* events. If all is true the value for
* eventTypes is ignored and the listener is registered for
* all events. Otherwise, if all is false
* the listener is only registered for the event types in
* eventTypes.
* @param listener The listener to register.
* @param eventTypes The event types to listen to.
* @param all Indicates whether eventTypes is used or if the
* listener is registered to all event types.
*/
protected void addListener(Listener listener, Set> eventTypes,
boolean all) {
checkArgument(listener != null, "listener can not be null");
if (eventTypes == null) {
throw new IllegalArgumentException("event types can not be null");
}
final Set> theTypes = all ? supportedTypes : eventTypes;
for (final Enum> eventType : theTypes) {
checkArgument(eventType != null, "event type can not be null");
checkArgument(supportedTypes.contains(eventType), "A listener for type %s is not allowed.", eventType);
listeners.put(eventType, listener);
}
}
/**
* {@inheritDoc}
*/
@Override
public void removeListener(Listener listener, Enum>... eventTypes) {
removeListener(listener, newHashSet(eventTypes));
}
/**
* {@inheritDoc}
*/
@Override
public void removeListener(Listener listener, Set> eventTypes) {
checkArgument(listener != null, "listener can not be null");
if (eventTypes == null) {
throw new IllegalArgumentException("event types can not be null");
}
if (eventTypes.isEmpty()) {
// remove all
// store keys in intermediate set to avoid concurrent modifications
final Set> keys = new HashSet>(listeners.keySet());
for (final Enum> eventType : keys) {
if (listeners.containsEntry(eventType, listener)) {
removeListener(listener, eventType);
}
}
} else {
for (final Enum> eventType : eventTypes) {
checkArgument(eventType != null, "event type can not be null");
checkArgument(containsListener(listener, eventType), "The listener %s for the type %s cannot be removed because it does not exist.", listener, eventType);
listeners.remove(eventType, listener);
}
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean containsListener(Listener listener, Enum> eventType) {
return listeners.containsEntry(eventType, listener);
}
/**
* This method returns the public {@link EventAPI} instance associated to
* this {@link EventDispatcher}. This instance can be made publicly
* available to classes outside the scope of the events. Through this
* instance listeners can be added and removed to this
* {@link EventDispatcher}.
* @return A wrapper for {@link EventDispatcher}, only shows the methods
* which should be allowed to be called outside of the dispatcher's
* parent.
*/
public EventAPI getPublicEventAPI() {
return publicAPI;
}
class PublicEventAPI implements EventAPI {
private final EventDispatcher ref;
public PublicEventAPI(EventDispatcher ed) {
ref = ed;
}
@Override
public void addListener(Listener l, Enum>... eventTypes) {
ref.addListener(l, eventTypes);
}
@Override
public void addListener(Listener listener, Set> eventTypes) {
ref.addListener(listener, eventTypes);
}
@Override
public void removeListener(Listener l, Enum>... eventTypes) {
ref.removeListener(l, eventTypes);
}
@Override
public void removeListener(Listener listener, Set> eventTypes) {
ref.removeListener(listener, eventTypes);
}
@Override
public boolean containsListener(Listener l, Enum> eventType) {
return ref.containsListener(l, eventType);
}
}
}