Simplify EventHandler implementation

This commit is contained in:
themode 2020-10-06 04:06:59 +02:00
parent 37d3c9c6bc
commit a757f4b97b
5 changed files with 50 additions and 62 deletions

View File

@ -13,7 +13,7 @@ public abstract class JsonMessage {
// true if the compiled string is up-to-date, false otherwise
private boolean updated;
// the compiled json string of this colored text (can be outdated)
// the compiled json string of the message (can be outdated)
private String compiledJson;
/**

View File

@ -137,7 +137,7 @@ public class RichMessage extends JsonMessage {
}
/**
* Process the components to add click/hover event
* Process the components to add click/hover events
*
* @param component the rich component to process
* @return a list of processed components

View File

@ -33,11 +33,9 @@ import net.minestom.server.utils.validate.Check;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.stream.Stream;
public abstract class Entity implements Viewable, EventHandler, DataContainer {
@ -98,7 +96,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
private long lastSynchronizationTime;
// Events
private final Map<Class<? extends Event>, List<EventCallback>> eventCallbacks = new ConcurrentHashMap<>();
private final Map<Class<? extends Event>, Collection<EventCallback>> eventCallbacks = new ConcurrentHashMap<>();
// Metadata
protected boolean onFire;
@ -542,30 +540,8 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
}
@Override
public <E extends Event> void addEventCallback(Class<E> eventClass, EventCallback<E> eventCallback) {
Check.notNull(eventClass, "Event class cannot be null");
Check.notNull(eventCallback, "Event callback cannot be null");
List<EventCallback> callbacks = getEventCallbacks(eventClass);
callbacks.add(eventCallback);
}
@Override
public <E extends Event> void removeEventCallback(Class<E> eventClass, EventCallback<E> eventCallback) {
Check.notNull(eventClass, "Event class cannot be null");
Check.notNull(eventCallback, "Event callback cannot be null");
List<EventCallback> callbacks = getEventCallbacks(eventClass);
callbacks.remove(eventCallback);
}
@Override
public <E extends Event> List<EventCallback> getEventCallbacks(Class<E> eventClass) {
Check.notNull(eventClass, "Event class cannot be null");
return eventCallbacks.computeIfAbsent(eventClass, clazz -> new CopyOnWriteArrayList<>());
}
@Override
public Stream<EventCallback> getEventCallbacks() {
return eventCallbacks.values().stream().flatMap(Collection::stream);
public Map<Class<? extends Event>, Collection<EventCallback>> getEventCallbacksMap() {
return eventCallbacks;
}
@Override

View File

@ -3,12 +3,25 @@ package net.minestom.server.event.handler;
import net.minestom.server.event.CancellableEvent;
import net.minestom.server.event.Event;
import net.minestom.server.event.EventCallback;
import net.minestom.server.utils.validate.Check;
import java.util.List;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Stream;
/**
* Represents an element which can have {@link Event} listeners assigned to it
*/
public interface EventHandler {
/**
* Get a {@link Map} containing all the listeners assigned to a specific {@link Event} type
*
* @return a {@link Map} with all the listeners
*/
Map<Class<? extends Event>, Collection<EventCallback>> getEventCallbacksMap();
/**
* Add a new event callback for the specified type {@code eventClass}
*
@ -16,7 +29,12 @@ public interface EventHandler {
* @param eventCallback the event callback
* @param <E> the event type
*/
<E extends Event> void addEventCallback(Class<E> eventClass, EventCallback<E> eventCallback);
default <E extends Event> void addEventCallback(Class<E> eventClass, EventCallback<E> eventCallback) {
Check.notNull(eventClass, "Event class cannot be null");
Check.notNull(eventCallback, "Event callback cannot be null");
Collection<EventCallback> callbacks = getEventCallbacks(eventClass);
callbacks.add(eventCallback);
}
/**
* Remove an event callback
@ -25,7 +43,12 @@ public interface EventHandler {
* @param eventCallback the event callback
* @param <E> the event type
*/
<E extends Event> void removeEventCallback(Class<E> eventClass, EventCallback<E> eventCallback);
default <E extends Event> void removeEventCallback(Class<E> eventClass, EventCallback<E> eventCallback) {
Check.notNull(eventClass, "Event class cannot be null");
Check.notNull(eventCallback, "Event callback cannot be null");
Collection<EventCallback> callbacks = getEventCallbacks(eventClass);
callbacks.remove(eventCallback);
}
/**
* Get the event callbacks of a specific event type
@ -34,37 +57,45 @@ public interface EventHandler {
* @param <E> the event type
* @return all event callbacks for the specified type {@code eventClass}
*/
<E extends Event> List<EventCallback> getEventCallbacks(Class<E> eventClass);
default <E extends Event> Collection<EventCallback> getEventCallbacks(Class<E> eventClass) {
Check.notNull(eventClass, "Event class cannot be null");
return getEventCallbacksMap().computeIfAbsent(eventClass, clazz -> new CopyOnWriteArrayList<>());
}
/**
* Get a {@link Stream} containing all the added callbacks, no matter to which event they are linked
* Get a {@link Stream} containing all the {@link EventCallback}, no matter to which {@link Event} they are linked
*
* @return a {@link Stream} containing all the added callbacks
*/
Stream<EventCallback> getEventCallbacks();
default Stream<EventCallback> getEventCallbacks() {
return getEventCallbacksMap().values().stream().flatMap(Collection::stream);
}
/**
* Call the specified event type using the Event object parameter
* Call the specified {@link Event}
*
* @param eventClass the event class
* @param event the event object
* @param <E> the event type
*/
default <E extends Event> void callEvent(Class<E> eventClass, E event) {
final List<EventCallback> eventCallbacks = getEventCallbacks(eventClass);
// TODO global event
final Collection<EventCallback> eventCallbacks = getEventCallbacks(eventClass);
for (EventCallback<E> eventCallback : eventCallbacks) {
eventCallback.run(event);
}
}
/**
* Same as {@link #callEvent(Class, Event)} but add a Runnable which is called if the event is not cancelled
* Call a {@link CancellableEvent} and execute {@code runnable} if the event is not cancelled
* <p>
* Does call {@link #callEvent(Class, Event)} internally
*
* @param eventClass the event class
* @param event the event object
* @param runnable the callback called when the event is not cancelled
* @param <E> the event type
* @see #callEvent(Class, Event)
*/
default <E extends CancellableEvent> void callCancellableEvent(Class<E> eventClass, E event, Runnable runnable) {
callEvent(eventClass, event);

View File

@ -33,10 +33,8 @@ import net.minestom.server.world.DimensionType;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Consumer;
import java.util.stream.Stream;
/**
* Instances are what are called "worlds" in Minecraft
@ -64,7 +62,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
private UpdateOption timeUpdate = new UpdateOption(1, TimeUnit.TICK);
private long lastTimeUpdate;
private final Map<Class<? extends Event>, List<EventCallback>> eventCallbacks = new ConcurrentHashMap<>();
private final Map<Class<? extends Event>, Collection<EventCallback>> eventCallbacks = new ConcurrentHashMap<>();
// Entities present in this instance
protected final Set<Entity> entities = new CopyOnWriteArraySet<>();
@ -655,7 +653,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
public Data getBlockData(int x, int y, int z) {
final Chunk chunk = getChunkAt(x, z);
Check.notNull(chunk, "The chunk at " + x + ":" + z + " is not loaded");
final int index = ChunkUtils.getBlockIndex(x,y,z);
final int index = ChunkUtils.getBlockIndex(x, y, z);
return chunk.getBlockData(index);
}
@ -775,25 +773,8 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
}
@Override
public <E extends Event> void addEventCallback(Class<E> eventClass, EventCallback<E> eventCallback) {
List<EventCallback> callbacks = getEventCallbacks(eventClass);
callbacks.add(eventCallback);
}
@Override
public <E extends Event> void removeEventCallback(Class<E> eventClass, EventCallback<E> eventCallback) {
List<EventCallback> callbacks = getEventCallbacks(eventClass);
callbacks.remove(eventCallback);
}
@Override
public <E extends Event> List<EventCallback> getEventCallbacks(Class<E> eventClass) {
return eventCallbacks.computeIfAbsent(eventClass, clazz -> new CopyOnWriteArrayList<>());
}
@Override
public Stream<EventCallback> getEventCallbacks() {
return eventCallbacks.values().stream().flatMap(Collection::stream);
public Map<Class<? extends Event>, Collection<EventCallback>> getEventCallbacksMap() {
return eventCallbacks;
}
// UNSAFE METHODS (need most of time to be synchronized)