Minestom/src/main/java/net/minestom/server/event/EventListener.java

122 lines
3.9 KiB
Java
Raw Normal View History

2021-05-11 04:52:57 +02:00
package net.minestom.server.event;
2021-06-08 14:15:30 +02:00
import org.jetbrains.annotations.Contract;
2021-05-11 04:52:57 +02:00
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
2021-05-11 04:52:57 +02:00
import java.util.function.Consumer;
import java.util.function.Predicate;
2021-06-02 21:14:48 +02:00
public interface EventListener<T extends Event> {
2021-05-11 04:52:57 +02:00
2021-06-02 21:14:48 +02:00
@NotNull Class<T> getEventType();
2021-05-11 04:52:57 +02:00
2021-06-02 21:14:48 +02:00
@NotNull Result run(@NotNull T event);
2021-05-11 04:52:57 +02:00
2021-06-08 14:15:30 +02:00
@Contract(pure = true)
static <T extends Event> EventListener.@NotNull Builder<T> builder(@NotNull Class<T> eventType) {
2021-06-02 08:17:03 +02:00
return new EventListener.Builder<>(eventType);
}
2021-06-08 14:15:30 +02:00
@Contract(pure = true)
static <T extends Event> @NotNull EventListener<T> of(@NotNull Class<T> eventType, @NotNull Consumer<@NotNull T> listener) {
2021-06-02 21:14:48 +02:00
return new EventListener<>() {
@Override
public @NotNull Class<T> getEventType() {
return eventType;
}
@Override
public @NotNull Result run(@NotNull T event) {
listener.accept(event);
return Result.SUCCESS;
}
};
2021-06-02 20:56:47 +02:00
}
2021-06-02 21:14:48 +02:00
class Builder<T extends Event> {
2021-05-11 04:52:57 +02:00
private final Class<T> eventType;
2021-06-02 20:23:50 +02:00
private final List<Predicate<T>> filters = new ArrayList<>();
2021-06-08 14:07:27 +02:00
private int expireCount;
private Predicate<T> expireWhen;
2021-05-11 04:52:57 +02:00
private Consumer<T> handler;
protected Builder(Class<T> eventType) {
this.eventType = eventType;
}
2021-06-08 14:15:30 +02:00
@Contract(value = "_ -> this")
public @NotNull EventListener.Builder<T> filter(Predicate<T> filter) {
2021-05-11 04:52:57 +02:00
this.filters.add(filter);
return this;
}
2021-06-08 14:15:30 +02:00
@Contract(value = "_ -> this")
public @NotNull EventListener.Builder<T> expireCount(int expireCount) {
2021-06-08 14:07:27 +02:00
this.expireCount = expireCount;
return this;
}
2021-06-08 14:15:30 +02:00
@Contract(value = "_ -> this")
public @NotNull EventListener.Builder<T> expireWhen(Predicate<T> expireWhen) {
2021-06-08 14:07:27 +02:00
this.expireWhen = expireWhen;
2021-06-02 20:23:50 +02:00
return this;
}
2021-06-08 14:15:30 +02:00
@Contract(value = "_ -> this")
public @NotNull EventListener.Builder<T> handler(Consumer<T> handler) {
2021-05-11 04:52:57 +02:00
this.handler = handler;
return this;
}
2021-06-08 14:15:30 +02:00
@Contract(value = "-> new", pure = true)
2021-06-02 21:14:48 +02:00
public @NotNull EventListener<T> build() {
2021-06-08 14:07:27 +02:00
AtomicInteger expirationCount = new AtomicInteger(this.expireCount);
final boolean hasExpirationCount = expirationCount.get() > 0;
2021-06-08 14:15:30 +02:00
final Predicate<T> expireWhen = this.expireWhen;
final var filters = new ArrayList<>(this.filters);
final var handler = this.handler;
2021-06-02 21:14:48 +02:00
return new EventListener<>() {
@Override
public @NotNull Class<T> getEventType() {
return eventType;
2021-05-11 04:52:57 +02:00
}
2021-06-02 21:14:48 +02:00
@Override
public @NotNull Result run(@NotNull T event) {
2021-06-08 14:07:27 +02:00
// Expiration predicate
if (expireWhen != null && expireWhen.test(event)) {
return Result.EXPIRED;
}
2021-06-02 21:14:48 +02:00
// Filtering
if (!filters.isEmpty()) {
if (filters.stream().anyMatch(filter -> !filter.test(event))) {
// Cancelled
return Result.INVALID;
}
}
// Handler
if (handler != null) {
handler.accept(event);
}
2021-06-08 14:07:27 +02:00
// Expiration count
2021-06-02 21:14:48 +02:00
if (hasExpirationCount && expirationCount.decrementAndGet() == 0) {
return Result.EXPIRED;
}
return Result.SUCCESS;
}
2021-06-02 21:14:48 +02:00
};
2021-05-11 04:52:57 +02:00
}
}
enum Result {
SUCCESS,
INVALID,
EXPIRED
}
2021-05-11 04:52:57 +02:00
}