From c6cc96a5f957ace5526a236a1365d85bcaeb62dd Mon Sep 17 00:00:00 2001 From: TheMode Date: Sat, 21 Aug 2021 04:15:47 +0200 Subject: [PATCH] Less change propagation/volatile read --- .../minestom/server/event/EventNodeImpl.java | 67 ++++++++----------- 1 file changed, 28 insertions(+), 39 deletions(-) diff --git a/src/main/java/net/minestom/server/event/EventNodeImpl.java b/src/main/java/net/minestom/server/event/EventNodeImpl.java index 56ed122f0..a4f77d76d 100644 --- a/src/main/java/net/minestom/server/event/EventNodeImpl.java +++ b/src/main/java/net/minestom/server/event/EventNodeImpl.java @@ -40,12 +40,10 @@ class EventNodeImpl implements EventNode { @Override public void call(@NotNull E event, @NotNull ListenerHandle handle) { - var castedHandle = (Handle) handle; + final Handle castedHandle = (Handle) handle; Check.argCondition(castedHandle.node != this, "Invalid handle owner"); - List> listeners = castedHandle.listeners; - if (!castedHandle.updated) { - castedHandle.update(); - } + if (!castedHandle.updated) castedHandle.update(); + final List> listeners = castedHandle.listeners; if (listeners.isEmpty()) return; for (Consumer listener : listeners) { listener.accept(event); @@ -61,12 +59,9 @@ class EventNodeImpl implements EventNode { @Override public boolean hasListener(@NotNull ListenerHandle handle) { - var castedHandle = (Handle) handle; - List> listeners = castedHandle.listeners; - if (!castedHandle.updated) { - castedHandle.update(); - } - return !listeners.isEmpty(); + final Handle castedHandle = (Handle) handle; + if (!castedHandle.updated) castedHandle.update(); + return !castedHandle.listeners.isEmpty(); } @Override @@ -129,10 +124,9 @@ class EventNodeImpl implements EventNode { final var childImpl = (EventNodeImpl) child; Check.stateCondition(childImpl.parent != null, "Node already has a parent"); Check.stateCondition(Objects.equals(parent, child), "Cannot have a child as parent"); - final boolean result = this.children.add((EventNodeImpl) childImpl); - if (!result) return this; + if (!children.add((EventNodeImpl) childImpl)) return this; // Couldn't add the child (already present?) childImpl.parent = this; - childImpl.propagateEvents(); // Propagate after setting the parent + childImpl.propagateEvents(this); // Propagate after setting the parent } return this; } @@ -140,10 +134,10 @@ class EventNodeImpl implements EventNode { @Override public @NotNull EventNode removeChild(@NotNull EventNode child) { synchronized (GLOBAL_CHILD_LOCK) { - final boolean result = this.children.remove(child); - if (!result) return this; final var childImpl = (EventNodeImpl) child; - childImpl.propagateEvents(); // Propagate before removing the parent + final boolean result = this.children.remove(childImpl); + if (!result) return this; // Child not found + childImpl.propagateEvents(parent); // Propagate before removing the parent childImpl.parent = null; } return this; @@ -153,9 +147,9 @@ class EventNodeImpl implements EventNode { public @NotNull EventNode addListener(@NotNull EventListener listener) { synchronized (GLOBAL_CHILD_LOCK) { final var eventType = listener.eventType(); - var entry = getEntry(eventType); + ListenerEntry entry = getEntry(eventType); entry.listeners.add((EventListener) listener); - propagateEvent(eventType); + propagateEvent(parent, eventType); } return this; } @@ -164,11 +158,10 @@ class EventNodeImpl implements EventNode { public @NotNull EventNode removeListener(@NotNull EventListener listener) { synchronized (GLOBAL_CHILD_LOCK) { final var eventType = listener.eventType(); - var entry = listenerMap.get(eventType); - if (entry == null) return this; + ListenerEntry entry = listenerMap.get(eventType); + if (entry == null) return this; // There is no listener with such type var listeners = entry.listeners; - final boolean removed = listeners.remove(listener); - if (removed) propagateEvent(eventType); + if (listeners.remove(listener)) propagateEvent(parent, eventType); } return this; } @@ -180,12 +173,9 @@ class EventNodeImpl implements EventNode { Check.stateCondition(nodeImpl.parent != null, "Node already has a parent"); Check.stateCondition(Objects.equals(parent, nodeImpl), "Cannot map to self"); var previous = this.mappedNodeCache.put(value, (EventNodeImpl) nodeImpl); - if (previous != null) { - previous.propagateEvents(); // Propagate before removing the parent - previous.parent = null; - } + if (previous != null) previous.parent = null; nodeImpl.parent = this; - nodeImpl.propagateEvents(); // Propagate after setting the parent + nodeImpl.propagateEvents(this); // Propagate after setting the parent } } @@ -193,9 +183,9 @@ class EventNodeImpl implements EventNode { public boolean unmap(@NotNull Object value) { synchronized (GLOBAL_CHILD_LOCK) { final var mappedNode = this.mappedNodeCache.remove(value); - if (mappedNode == null) return false; + if (mappedNode == null) return false; // Mapped node not found final var childImpl = (EventNodeImpl) mappedNode; - childImpl.propagateEvents(); // Propagate before removing the parent + childImpl.propagateEvents(parent); // Propagate before removing the parent childImpl.parent = null; return true; } @@ -207,7 +197,7 @@ class EventNodeImpl implements EventNode { for (var eventType : binding.eventTypes()) { ListenerEntry entry = getEntry((Class) eventType); final boolean added = entry.bindingConsumers.add((Consumer) binding.consumer(eventType)); - if (added) propagateEvent((Class) eventType); + if (added) propagateEvent(parent, (Class) eventType); } } } @@ -219,7 +209,7 @@ class EventNodeImpl implements EventNode { ListenerEntry entry = listenerMap.get(eventType); if (entry == null) return; final boolean removed = entry.bindingConsumers.remove(binding.consumer(eventType)); - if (removed) propagateEvent((Class) eventType); + if (removed) propagateEvent(parent, (Class) eventType); } } } @@ -250,18 +240,17 @@ class EventNodeImpl implements EventNode { return parent; } - private void propagateEvents() { - this.listenerMap.keySet().forEach(this::propagateEvent); + private void propagateEvents(EventNodeImpl parent) { + this.listenerMap.keySet().forEach(aClass -> propagateEvent(parent, aClass)); } - private void propagateEvent(Class eventClass) { + private void propagateEvent(EventNodeImpl parent, Class eventClass) { + if (parent == null) return; forTargetEvents(eventClass, type -> { - final var parent = this.parent; - if (parent == null) return; - Handle parentHandle = parent.handleMap.get(type); + Handle parentHandle = (Handle) parent.handleMap.get(type); if (parentHandle == null) return; parentHandle.updated = false; - parent.propagateEvent((Class) type); + parent.propagateEvent(parent.parent, type); }); }