Make EventNode an interface

This commit is contained in:
TheMode 2021-06-02 19:17:08 +02:00
parent a835a479ae
commit 0d6dde3ff5
4 changed files with 87 additions and 64 deletions

View File

@ -3,90 +3,43 @@ package net.minestom.server.event;
import net.minestom.server.event.handler.EventHandler;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
public class EventNode<T extends Event> {
public interface EventNode<T extends Event> {
private final String name = "debug";
private final Map<Class<? extends T>, List<EventListener<T>>> listenerMap = new ConcurrentHashMap<>();
private final List<EventNode<T>> children = new CopyOnWriteArrayList<>();
protected final Class<T> type;
protected EventNode(Class<T> type) {
this.type = type;
static <E extends Event> EventNode<E> create(@NotNull Class<E> type) {
return new EventNodeImpl<>(type);
}
public static <E extends Event> EventNode<E> create(@NotNull Class<E> type) {
return new EventNode<>(type);
}
public static EventNode<Event> create() {
static EventNode<Event> create() {
return create(Event.class);
}
public static <E extends Event> EventNode<E> conditional(@NotNull Class<E> type,
@NotNull Predicate<E> predicate) {
static <E extends Event> EventNode<E> conditional(@NotNull Class<E> type,
@NotNull Predicate<E> predicate) {
return new EventNodeConditional<>(type, predicate);
}
public static <E extends Event, H extends EventHandler> EventNode<E> map(@NotNull Class<E> eventType,
@NotNull Class<H> handlerType,
@NotNull Function<E, H> handlerGetter) {
static <E extends Event, H extends EventHandler> EventNode<E> map(@NotNull Class<E> eventType,
@NotNull Class<H> handlerType,
@NotNull Function<E, H> handlerGetter) {
return new EventNodeMap<>(eventType, handlerGetter);
}
protected boolean condition(@NotNull T event) {
return true;
}
void call(@NotNull T event);
public void call(@NotNull T event) {
if (!type.isAssignableFrom(event.getClass())) {
// Invalid event type
return;
}
if (!condition(event)) {
// Cancelled by superclass
return;
}
final var listeners = listenerMap.get(event.getClass());
if (listeners != null && !listeners.isEmpty()) {
listeners.forEach(listener -> {
final EventListener.Result result = listener.executor.apply(event);
if (result == EventListener.Result.EXPIRED) {
listeners.remove(listener);
}
});
}
this.children.forEach(eventNode -> eventNode.call(event));
}
void addChild(@NotNull EventNode<? extends T> child);
public void addChild(@NotNull EventNode<? extends T> child) {
this.children.add((EventNode<T>) child);
}
void addListener(@NotNull EventListener<? extends T> listener);
public void addListener(@NotNull EventListener<? extends T> listener) {
this.listenerMap.computeIfAbsent(listener.type, aClass -> new CopyOnWriteArrayList<>())
.add((EventListener<T>) listener);
}
public <E extends T> void addListener(@NotNull Class<E> eventClass, @NotNull Consumer<@NotNull E> listener) {
default <E extends T> void addListener(@NotNull Class<E> eventClass, @NotNull Consumer<@NotNull E> listener) {
addListener(EventListener.of(eventClass).handler(listener).build());
}
public @NotNull String getName() {
return name;
}
@NotNull String getName();
public @NotNull List<@NotNull EventNode<T>> getChildren() {
return Collections.unmodifiableList(children);
}
@NotNull List<@NotNull EventNode<T>> getChildren();
}

View File

@ -4,7 +4,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.function.Predicate;
public class EventNodeConditional<T extends Event> extends EventNode<T> {
public class EventNodeConditional<T extends Event> extends EventNodeImpl<T> {
private volatile Predicate<T> predicate;

View File

@ -0,0 +1,70 @@
package net.minestom.server.event;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
class EventNodeImpl<T extends Event> implements EventNode<T> {
private final String name = "debug";
private final Map<Class<? extends T>, List<EventListener<T>>> listenerMap = new ConcurrentHashMap<>();
private final List<EventNode<T>> children = new CopyOnWriteArrayList<>();
protected final Class<T> type;
protected EventNodeImpl(Class<T> type) {
this.type = type;
}
protected boolean condition(@NotNull T event) {
return true;
}
@Override
public void call(@NotNull T event) {
if (!type.isAssignableFrom(event.getClass())) {
// Invalid event type
return;
}
if (!condition(event)) {
// Cancelled by superclass
return;
}
final var listeners = listenerMap.get(event.getClass());
if (listeners != null && !listeners.isEmpty()) {
listeners.forEach(listener -> {
final EventListener.Result result = listener.executor.apply(event);
if (result == EventListener.Result.EXPIRED) {
listeners.remove(listener);
}
});
}
this.children.forEach(eventNode -> eventNode.call(event));
}
@Override
public void addChild(@NotNull EventNode<? extends T> child) {
this.children.add((EventNode<T>) child);
}
@Override
public void addListener(@NotNull EventListener<? extends T> listener) {
this.listenerMap.computeIfAbsent(listener.type, aClass -> new CopyOnWriteArrayList<>())
.add((EventListener<T>) listener);
}
@Override
public @NotNull String getName() {
return name;
}
@Override
public @NotNull List<@NotNull EventNode<T>> getChildren() {
return Collections.unmodifiableList(children);
}
}

View File

@ -7,7 +7,7 @@ import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Function;
public class EventNodeMap<T extends Event, H extends EventHandler> extends EventNode<T> {
public class EventNodeMap<T extends Event, H extends EventHandler> extends EventNodeImpl<T> {
private final Function<T, H> handlerGetter;