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;
|
2021-06-02 12:12:14 +02:00
|
|
|
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;
|
2021-06-02 12:12:14 +02:00
|
|
|
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);
|
2021-06-02 12:12:14 +02:00
|
|
|
final boolean hasExpirationCount = expirationCount.get() > 0;
|
|
|
|
|
2021-06-08 14:15:30 +02:00
|
|
|
final Predicate<T> expireWhen = this.expireWhen;
|
|
|
|
|
2021-06-02 12:12:14 +02:00
|
|
|
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 12:12:14 +02:00
|
|
|
}
|
2021-06-02 21:14:48 +02:00
|
|
|
};
|
2021-05-11 04:52:57 +02:00
|
|
|
}
|
|
|
|
}
|
2021-06-02 12:12:14 +02:00
|
|
|
|
|
|
|
enum Result {
|
|
|
|
SUCCESS,
|
|
|
|
INVALID,
|
|
|
|
EXPIRED
|
|
|
|
}
|
2021-05-11 04:52:57 +02:00
|
|
|
}
|