Rework EventInterface

This commit is contained in:
TheMode 2021-08-16 07:58:58 +02:00
parent 02e8d53079
commit 8617d98c95
2 changed files with 47 additions and 20 deletions

View File

@ -2,34 +2,56 @@ package net.minestom.server.event;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Predicate;
public final class EventInterface<T> { public interface EventInterface<E extends Event> {
public static <T> @NotNull Builder<T> builder(@NotNull Class<T> type) { static <E extends Event, T> @NotNull FilteredBuilder<E, T> filtered(@NotNull EventFilter<E, T> filter, @NotNull Predicate<T> predicate) {
return new Builder<>(); return new FilteredBuilder<>(filter, predicate);
} }
final Map<Class<? extends Event>, BiConsumer<T, Event>> mapped; @NotNull Collection<Class<? extends Event>> eventTypes();
EventInterface(Map<Class<? extends Event>, BiConsumer<T, Event>> map) { void call(@NotNull E event);
this.mapped = map;
}
public static class Builder<T> { class FilteredBuilder<E extends Event, T> {
private final Map<Class<? extends Event>, BiConsumer<T, Event>> mapped = new HashMap<>(); private final EventFilter<E, T> filter;
private final Predicate<T> predicate;
private final Map<Class<? extends Event>, BiConsumer<Object, E>> mapped = new HashMap<>();
@SuppressWarnings("unchecked") FilteredBuilder(EventFilter<E, T> filter, Predicate<T> predicate) {
public <E extends Event> Builder<T> map(@NotNull Class<E> eventType, this.filter = filter;
@NotNull BiConsumer<@NotNull T, @NotNull E> consumer) { this.predicate = predicate;
this.mapped.put(eventType, (BiConsumer<T, Event>) consumer); }
public <M extends E> FilteredBuilder<E, T> map(@NotNull Class<M> eventType,
@NotNull BiConsumer<@NotNull T, @NotNull M> consumer) {
this.mapped.put(eventType, (BiConsumer<Object, E>) consumer);
return this; return this;
} }
public @NotNull EventInterface<T> build() { public @NotNull EventInterface<E> build() {
return new EventInterface<>(Map.copyOf(mapped)); final var copy = Map.copyOf(mapped);
final var eventTypes = copy.keySet();
return new EventInterface<>() {
@Override
public @NotNull Collection<Class<? extends Event>> eventTypes() {
return eventTypes;
}
@Override
public void call(@NotNull E event) {
final T handler = filter.getHandler(event);
if (!predicate.test(handler)) return;
final var consumer = copy.get(event.getClass());
if (consumer == null) return;
consumer.accept(handler, event);
}
};
} }
} }
} }

View File

@ -192,6 +192,7 @@ public class EventNode<T extends Event> {
private final Map<Class<? extends T>, ListenerEntry<T>> listenerMap = new ConcurrentHashMap<>(); private final Map<Class<? extends T>, ListenerEntry<T>> listenerMap = new ConcurrentHashMap<>();
private final Set<EventNode<T>> children = new CopyOnWriteArraySet<>(); private final Set<EventNode<T>> children = new CopyOnWriteArraySet<>();
private final Set<EventInterface<T>> interfaces = new CopyOnWriteArraySet<>();
private final Map<Object, EventNode<T>> mappedNode; private final Map<Object, EventNode<T>> mappedNode;
protected final String name; protected final String name;
@ -250,6 +251,13 @@ public class EventNode<T extends Event> {
// Cancelled by superclass // Cancelled by superclass
return; return;
} }
// Event interfaces
if (!interfaces.isEmpty()) {
this.interfaces.forEach(eventInterface -> {
if (!eventInterface.eventTypes().contains(eventClass)) return;
eventInterface.call(event);
});
}
// Mapped listeners // Mapped listeners
if (!mappedNode.isEmpty()) { if (!mappedNode.isEmpty()) {
// Check mapped listeners for each individual event handler // Check mapped listeners for each individual event handler
@ -547,11 +555,8 @@ public class EventNode<T extends Event> {
return mappedNode.remove(value) != null; return mappedNode.remove(value) != null;
} }
public <I> void addInter(@NotNull EventInterface<I> inter, @NotNull I value) { public void registerInterface(@NotNull EventInterface<? extends T> eventInterface) {
inter.mapped.forEach((eventType, consumer) -> { this.interfaces.add((EventInterface<T>) eventInterface);
// TODO cache so listeners can be removed from the EventInterface
addListener((EventListener<? extends T>) EventListener.builder(eventType).handler(event -> consumer.accept(value, event)).build());
});
} }
private void increaseChildListenerCount(Class<? extends T> eventClass, int count) { private void increaseChildListenerCount(Class<? extends T> eventClass, int count) {