mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-21 23:51:36 +01:00
Add support for listener expiration count
This commit is contained in:
parent
bdfa164695
commit
305aa3e8d9
@ -1,20 +1,23 @@
|
|||||||
package net.minestom.server.event;
|
package net.minestom.server.event;
|
||||||
|
|
||||||
|
import net.minestom.server.utils.time.UpdateOption;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public class EventListener<T extends Event> {
|
public class EventListener<T extends Event> {
|
||||||
|
|
||||||
protected final Class<T> type;
|
protected final Class<T> type;
|
||||||
protected final Consumer<T> combined;
|
protected final Function<T, Result> executor;
|
||||||
|
|
||||||
private EventListener(@NotNull Class<T> type, @NotNull Consumer<T> combined) {
|
private EventListener(@NotNull Class<T> type, @NotNull Function<T, Result> executor) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.combined = combined;
|
this.executor = executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Event> EventListener.Builder<T> of(@NotNull Class<T> eventType) {
|
public static <T extends Event> EventListener.Builder<T> of(@NotNull Class<T> eventType) {
|
||||||
@ -26,6 +29,8 @@ public class EventListener<T extends Event> {
|
|||||||
private final Class<T> eventType;
|
private final Class<T> eventType;
|
||||||
|
|
||||||
private List<Predicate<T>> filters = new ArrayList<>();
|
private List<Predicate<T>> filters = new ArrayList<>();
|
||||||
|
private int expirationCount;
|
||||||
|
private UpdateOption expirationTime;
|
||||||
private Consumer<T> handler;
|
private Consumer<T> handler;
|
||||||
|
|
||||||
protected Builder(Class<T> eventType) {
|
protected Builder(Class<T> eventType) {
|
||||||
@ -37,25 +42,47 @@ public class EventListener<T extends Event> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EventListener.Builder<T> expirationCount(int expirationCount) {
|
||||||
|
this.expirationCount = expirationCount;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public EventListener.Builder<T> handler(Consumer<T> handler) {
|
public EventListener.Builder<T> handler(Consumer<T> handler) {
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EventListener<T> build() {
|
public EventListener<T> build() {
|
||||||
|
AtomicInteger expirationCount = new AtomicInteger(this.expirationCount);
|
||||||
|
final boolean hasExpirationCount = expirationCount.get() > 0;
|
||||||
|
|
||||||
|
final var filters = new ArrayList<>(this.filters);
|
||||||
|
final var handler = this.handler;
|
||||||
return new EventListener<>(eventType, event -> {
|
return new EventListener<>(eventType, event -> {
|
||||||
// Filtering
|
// Filtering
|
||||||
if (!filters.isEmpty()) {
|
if (!filters.isEmpty()) {
|
||||||
if (filters.stream().anyMatch(filter -> !filter.test(event))) {
|
if (filters.stream().anyMatch(filter -> !filter.test(event))) {
|
||||||
// Cancelled
|
// Cancelled
|
||||||
return;
|
return Result.INVALID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Handler
|
// Handler
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
handler.accept(event);
|
handler.accept(event);
|
||||||
}
|
}
|
||||||
|
// Expiration check
|
||||||
|
if (hasExpirationCount && expirationCount.decrementAndGet() == 0) {
|
||||||
|
return Result.EXPIRED;
|
||||||
|
}
|
||||||
|
return Result.SUCCESS;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum Result {
|
||||||
|
SUCCESS,
|
||||||
|
INVALID,
|
||||||
|
EXPIRED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,12 @@ public class EventNode<T extends Event> {
|
|||||||
}
|
}
|
||||||
final var listeners = listenerMap.get(event.getClass());
|
final var listeners = listenerMap.get(event.getClass());
|
||||||
if (listeners != null && !listeners.isEmpty()) {
|
if (listeners != null && !listeners.isEmpty()) {
|
||||||
listeners.forEach(eventListener ->
|
listeners.forEach(listener -> {
|
||||||
eventListener.combined.accept(event));
|
final EventListener.Result result = listener.executor.apply(event);
|
||||||
|
if (result == EventListener.Result.EXPIRED) {
|
||||||
|
listeners.remove(listener);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
this.children.forEach(eventNode -> eventNode.call(event));
|
this.children.forEach(eventNode -> eventNode.call(event));
|
||||||
}
|
}
|
||||||
|
@ -140,6 +140,7 @@ public class PlayerInit {
|
|||||||
var node = EventNode.create(PlayerEvent.class);
|
var node = EventNode.create(PlayerEvent.class);
|
||||||
node.addListener(EventListener.of(PlayerTickEvent.class)
|
node.addListener(EventListener.of(PlayerTickEvent.class)
|
||||||
.handler(playerTickEvent -> System.out.println("Player tick!"))
|
.handler(playerTickEvent -> System.out.println("Player tick!"))
|
||||||
|
.expirationCount(2)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
var empty = EventNode.create();
|
var empty = EventNode.create();
|
||||||
|
Loading…
Reference in New Issue
Block a user