mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-04 23:47:59 +01:00
Add support for node predicate, fast exit when the node type is incompatible
This commit is contained in:
parent
43fc7ad624
commit
044849b5ac
@ -14,11 +14,10 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
class EventNodeImpl<T extends Event> implements EventNode<T> {
|
class EventNodeImpl<T extends Event> implements EventNode<T> {
|
||||||
private static final Object GLOBAL_CHILD_LOCK = new Object();
|
private static final Object GLOBAL_CHILD_LOCK = new Object();
|
||||||
private final Object lock = new Object();
|
|
||||||
|
|
||||||
private final Map<Class<? extends T>, Handle<T>> handleMap = new ConcurrentHashMap<>();
|
private final Map<Class<? extends T>, Handle<T>> handleMap = new ConcurrentHashMap<>();
|
||||||
private final Map<Class<? extends T>, ListenerEntry<T>> listenerMap = new ConcurrentHashMap<>();
|
private final Map<Class<? extends T>, ListenerEntry<T>> listenerMap = new ConcurrentHashMap<>();
|
||||||
private final Set<EventNode<T>> children = new CopyOnWriteArraySet<>();
|
private final Set<EventNodeImpl<T>> children = new CopyOnWriteArraySet<>();
|
||||||
private final Map<Object, ListenerEntry<T>> mappedNodeCache = new WeakHashMap<>();
|
private final Map<Object, ListenerEntry<T>> mappedNodeCache = new WeakHashMap<>();
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
@ -45,7 +44,7 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
|||||||
if (!castedHandle.updated) {
|
if (!castedHandle.updated) {
|
||||||
listeners.clear();
|
listeners.clear();
|
||||||
synchronized (GLOBAL_CHILD_LOCK) {
|
synchronized (GLOBAL_CHILD_LOCK) {
|
||||||
handle(castedHandle);
|
handle(castedHandle.eventType, castedHandle.listeners);
|
||||||
}
|
}
|
||||||
castedHandle.updated = true;
|
castedHandle.updated = true;
|
||||||
}
|
}
|
||||||
@ -61,22 +60,33 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
|||||||
aClass -> new Handle<>(this, (Class<T>) aClass));
|
aClass -> new Handle<>(this, (Class<T>) aClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handle(Handle<T> handle) {
|
private void handle(Class<T> handleType, List<Consumer<T>> listeners) {
|
||||||
ListenerEntry<T> entry = listenerMap.get(handle.eventType);
|
ListenerEntry<T> entry = listenerMap.get(handleType);
|
||||||
if (entry != null) {
|
if (entry != null) {
|
||||||
// Add normal listeners
|
// Add normal listeners
|
||||||
for (var listener : entry.listeners) {
|
for (var listener : entry.listeners) {
|
||||||
handle.listeners.add(listener::run);
|
if (predicate != null) {
|
||||||
|
// Ensure that the event is valid before running
|
||||||
|
listeners.add(event -> {
|
||||||
|
final var value = filter.getHandler(event);
|
||||||
|
if (!predicate.test(event, value)) return;
|
||||||
|
listener.run(event);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// No predicate, run directly
|
||||||
|
listeners.add(listener::run);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Add bindings
|
// Add bindings
|
||||||
handle.listeners.addAll(entry.bindingConsumers);
|
listeners.addAll(entry.bindingConsumers);
|
||||||
// TODO mapped node
|
// TODO mapped node
|
||||||
}
|
}
|
||||||
// Add children
|
// Add children
|
||||||
if (children.isEmpty()) return;
|
if (children.isEmpty()) return;
|
||||||
this.children.stream()
|
this.children.stream()
|
||||||
.sorted(Comparator.comparing(EventNode::getPriority))
|
.sorted(Comparator.comparing(EventNode::getPriority))
|
||||||
.forEach(child -> ((EventNodeImpl) child).handle(handle));
|
.filter(child -> child.eventType.isAssignableFrom(handleType)) // Invalid event type
|
||||||
|
.forEach(child -> child.handle(handleType, listeners));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user