package net.minestom.server.event; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Predicate; @ApiStatus.Experimental public interface EventBinding { static @NotNull FilteredBuilder filtered(@NotNull EventFilter filter, @NotNull Predicate predicate) { return new FilteredBuilder<>(filter, predicate); } @NotNull Collection> eventTypes(); @NotNull Consumer<@NotNull E> consumer(@NotNull Class eventType); class FilteredBuilder { private final EventFilter filter; private final Predicate predicate; private final Map, BiConsumer> mapped = new HashMap<>(); FilteredBuilder(EventFilter filter, Predicate predicate) { this.filter = filter; this.predicate = predicate; } public FilteredBuilder map(@NotNull Class eventType, @NotNull BiConsumer<@NotNull T, @NotNull M> consumer) { //noinspection unchecked this.mapped.put(eventType, (BiConsumer) consumer); return this; } public @NotNull EventBinding build() { final var copy = Map.copyOf(mapped); final var eventTypes = copy.keySet(); Map, Consumer> consumers = new HashMap<>(eventTypes.size()); for (var eventType : eventTypes) { final var consumer = copy.get(eventType); consumers.put(eventType, event -> { final T handler = filter.getHandler(event); if (!predicate.test(handler)) return; consumer.accept(handler, event); }); } return new EventBinding<>() { @Override public @NotNull Collection> eventTypes() { return eventTypes; } @Override public @NotNull Consumer consumer(@NotNull Class eventType) { return consumers.get(eventType); } }; } } }