Initial revamped event listening API

This commit is contained in:
TheMode 2021-05-04 00:46:18 +02:00
parent 748e3d7b39
commit e45c60c225
2 changed files with 94 additions and 0 deletions

View File

@ -1,6 +1,14 @@
package net.minestom.server.event;
import net.minestom.server.event.handler.EventHandler;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* Object which can be listened to by an {@link EventHandler}.
@ -8,4 +16,79 @@ import net.minestom.server.event.handler.EventHandler;
* Called using {@link EventHandler#callEvent(Class, Event)}.
*/
public class Event {
public static <T extends EntityEvent> Listener.Builder<T> entity(Class<T> eventType) {
return new Listener.Builder<>(eventType);
}
public static <T extends PlayerEvent> Listener.Builder<T> player(Class<T> eventType) {
return new Listener.Builder<>(eventType);
}
public static class Listener<T extends Event> {
private final Class<T> eventType;
private final Set<EventHandler> attach = new CopyOnWriteArraySet<>();
private final Consumer<T> combined;
private Listener(Class<T> eventType, @NotNull Consumer<T> combined) {
this.eventType = eventType;
this.combined = combined;
}
public void attachTo(@NotNull EventHandler handler) {
final boolean success = this.attach.add(handler);
if (success) {
handler.addEventCallback(eventType, combined::accept);
}
}
public void detachFrom(@NotNull EventHandler handler) {
final boolean success = this.attach.remove(handler);
if (success) {
handler.removeEventCallback(eventType, combined::accept);
}
}
public static class Builder<T extends Event> {
private final Class<T> eventType;
private List<Function<T, Boolean>> filters = new ArrayList<>();
private Consumer<T> handler;
private Builder(Class<T> eventType) {
this.eventType = eventType;
}
public Builder<T> filter(Function<T, Boolean> filter) {
this.filters.add(filter);
return this;
}
public Builder<T> handler(Consumer<T> handler) {
this.handler = handler;
return this;
}
public Listener<T> build() {
return new Listener<>(eventType, event -> {
// Filtering
if (!filters.isEmpty()) {
if (filters.stream().anyMatch(tBooleanFunction -> !tBooleanFunction.apply(event))) {
// Cancelled
return;
}
}
// Handler
if (handler != null) {
handler.accept(event);
}
});
}
}
}
}

View File

@ -11,6 +11,7 @@ import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.ItemEntity;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.damage.DamageType;
import net.minestom.server.event.Event;
import net.minestom.server.event.GlobalEventHandler;
import net.minestom.server.event.entity.EntityAttackEvent;
import net.minestom.server.event.item.ItemDropEvent;
@ -136,6 +137,16 @@ public class PlayerInit {
GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();
connectionManager.addPlayerInitialization(player -> {
var listener = Event.player(PlayerChatEvent.class)
.filter(playerChatEvent -> player.isCreative())
.handler(playerChatEvent -> Audiences.players().sendMessage(Component.text("Listener is working!")))
.build();
listener.attachTo(player);
});
globalEventHandler.addEventCallback(EntityAttackEvent.class, event -> {
final Entity source = event.getEntity();
final Entity entity = event.getTarget();