mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-04 23:47:59 +01:00
Less change propagation/volatile read
This commit is contained in:
parent
cfbd655027
commit
c6cc96a5f9
@ -40,12 +40,10 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <E extends T> void call(@NotNull E event, @NotNull ListenerHandle<E> handle) {
|
public <E extends T> void call(@NotNull E event, @NotNull ListenerHandle<E> handle) {
|
||||||
var castedHandle = (Handle<T>) handle;
|
final Handle<T> castedHandle = (Handle<T>) handle;
|
||||||
Check.argCondition(castedHandle.node != this, "Invalid handle owner");
|
Check.argCondition(castedHandle.node != this, "Invalid handle owner");
|
||||||
List<Consumer<T>> listeners = castedHandle.listeners;
|
if (!castedHandle.updated) castedHandle.update();
|
||||||
if (!castedHandle.updated) {
|
final List<Consumer<T>> listeners = castedHandle.listeners;
|
||||||
castedHandle.update();
|
|
||||||
}
|
|
||||||
if (listeners.isEmpty()) return;
|
if (listeners.isEmpty()) return;
|
||||||
for (Consumer<T> listener : listeners) {
|
for (Consumer<T> listener : listeners) {
|
||||||
listener.accept(event);
|
listener.accept(event);
|
||||||
@ -61,12 +59,9 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <E extends T> boolean hasListener(@NotNull ListenerHandle<E> handle) {
|
public <E extends T> boolean hasListener(@NotNull ListenerHandle<E> handle) {
|
||||||
var castedHandle = (Handle<T>) handle;
|
final Handle<T> castedHandle = (Handle<T>) handle;
|
||||||
List<Consumer<T>> listeners = castedHandle.listeners;
|
if (!castedHandle.updated) castedHandle.update();
|
||||||
if (!castedHandle.updated) {
|
return !castedHandle.listeners.isEmpty();
|
||||||
castedHandle.update();
|
|
||||||
}
|
|
||||||
return !listeners.isEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -129,10 +124,9 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
|||||||
final var childImpl = (EventNodeImpl<? extends T>) child;
|
final var childImpl = (EventNodeImpl<? extends T>) child;
|
||||||
Check.stateCondition(childImpl.parent != null, "Node already has a parent");
|
Check.stateCondition(childImpl.parent != null, "Node already has a parent");
|
||||||
Check.stateCondition(Objects.equals(parent, child), "Cannot have a child as parent");
|
Check.stateCondition(Objects.equals(parent, child), "Cannot have a child as parent");
|
||||||
final boolean result = this.children.add((EventNodeImpl<T>) childImpl);
|
if (!children.add((EventNodeImpl<T>) childImpl)) return this; // Couldn't add the child (already present?)
|
||||||
if (!result) return this;
|
|
||||||
childImpl.parent = this;
|
childImpl.parent = this;
|
||||||
childImpl.propagateEvents(); // Propagate after setting the parent
|
childImpl.propagateEvents(this); // Propagate after setting the parent
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -140,10 +134,10 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
|||||||
@Override
|
@Override
|
||||||
public @NotNull EventNode<T> removeChild(@NotNull EventNode<? extends T> child) {
|
public @NotNull EventNode<T> removeChild(@NotNull EventNode<? extends T> child) {
|
||||||
synchronized (GLOBAL_CHILD_LOCK) {
|
synchronized (GLOBAL_CHILD_LOCK) {
|
||||||
final boolean result = this.children.remove(child);
|
|
||||||
if (!result) return this;
|
|
||||||
final var childImpl = (EventNodeImpl<? extends T>) child;
|
final var childImpl = (EventNodeImpl<? extends T>) 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;
|
childImpl.parent = null;
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@ -153,9 +147,9 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
|||||||
public @NotNull EventNode<T> addListener(@NotNull EventListener<? extends T> listener) {
|
public @NotNull EventNode<T> addListener(@NotNull EventListener<? extends T> listener) {
|
||||||
synchronized (GLOBAL_CHILD_LOCK) {
|
synchronized (GLOBAL_CHILD_LOCK) {
|
||||||
final var eventType = listener.eventType();
|
final var eventType = listener.eventType();
|
||||||
var entry = getEntry(eventType);
|
ListenerEntry<T> entry = getEntry(eventType);
|
||||||
entry.listeners.add((EventListener<T>) listener);
|
entry.listeners.add((EventListener<T>) listener);
|
||||||
propagateEvent(eventType);
|
propagateEvent(parent, eventType);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -164,11 +158,10 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
|||||||
public @NotNull EventNode<T> removeListener(@NotNull EventListener<? extends T> listener) {
|
public @NotNull EventNode<T> removeListener(@NotNull EventListener<? extends T> listener) {
|
||||||
synchronized (GLOBAL_CHILD_LOCK) {
|
synchronized (GLOBAL_CHILD_LOCK) {
|
||||||
final var eventType = listener.eventType();
|
final var eventType = listener.eventType();
|
||||||
var entry = listenerMap.get(eventType);
|
ListenerEntry<T> entry = listenerMap.get(eventType);
|
||||||
if (entry == null) return this;
|
if (entry == null) return this; // There is no listener with such type
|
||||||
var listeners = entry.listeners;
|
var listeners = entry.listeners;
|
||||||
final boolean removed = listeners.remove(listener);
|
if (listeners.remove(listener)) propagateEvent(parent, eventType);
|
||||||
if (removed) propagateEvent(eventType);
|
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -180,12 +173,9 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
|||||||
Check.stateCondition(nodeImpl.parent != null, "Node already has a parent");
|
Check.stateCondition(nodeImpl.parent != null, "Node already has a parent");
|
||||||
Check.stateCondition(Objects.equals(parent, nodeImpl), "Cannot map to self");
|
Check.stateCondition(Objects.equals(parent, nodeImpl), "Cannot map to self");
|
||||||
var previous = this.mappedNodeCache.put(value, (EventNodeImpl<T>) nodeImpl);
|
var previous = this.mappedNodeCache.put(value, (EventNodeImpl<T>) nodeImpl);
|
||||||
if (previous != null) {
|
if (previous != null) previous.parent = null;
|
||||||
previous.propagateEvents(); // Propagate before removing the parent
|
|
||||||
previous.parent = null;
|
|
||||||
}
|
|
||||||
nodeImpl.parent = this;
|
nodeImpl.parent = this;
|
||||||
nodeImpl.propagateEvents(); // Propagate after setting the parent
|
nodeImpl.propagateEvents(this); // Propagate after setting the parent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,9 +183,9 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
|||||||
public boolean unmap(@NotNull Object value) {
|
public boolean unmap(@NotNull Object value) {
|
||||||
synchronized (GLOBAL_CHILD_LOCK) {
|
synchronized (GLOBAL_CHILD_LOCK) {
|
||||||
final var mappedNode = this.mappedNodeCache.remove(value);
|
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<? extends T>) mappedNode;
|
final var childImpl = (EventNodeImpl<? extends T>) mappedNode;
|
||||||
childImpl.propagateEvents(); // Propagate before removing the parent
|
childImpl.propagateEvents(parent); // Propagate before removing the parent
|
||||||
childImpl.parent = null;
|
childImpl.parent = null;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -207,7 +197,7 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
|||||||
for (var eventType : binding.eventTypes()) {
|
for (var eventType : binding.eventTypes()) {
|
||||||
ListenerEntry<T> entry = getEntry((Class<? extends T>) eventType);
|
ListenerEntry<T> entry = getEntry((Class<? extends T>) eventType);
|
||||||
final boolean added = entry.bindingConsumers.add((Consumer<T>) binding.consumer(eventType));
|
final boolean added = entry.bindingConsumers.add((Consumer<T>) binding.consumer(eventType));
|
||||||
if (added) propagateEvent((Class<? extends T>) eventType);
|
if (added) propagateEvent(parent, (Class<? extends T>) eventType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,7 +209,7 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
|||||||
ListenerEntry<T> entry = listenerMap.get(eventType);
|
ListenerEntry<T> entry = listenerMap.get(eventType);
|
||||||
if (entry == null) return;
|
if (entry == null) return;
|
||||||
final boolean removed = entry.bindingConsumers.remove(binding.consumer(eventType));
|
final boolean removed = entry.bindingConsumers.remove(binding.consumer(eventType));
|
||||||
if (removed) propagateEvent((Class<? extends T>) eventType);
|
if (removed) propagateEvent(parent, (Class<? extends T>) eventType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,18 +240,17 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
|||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void propagateEvents() {
|
private void propagateEvents(EventNodeImpl<? super T> parent) {
|
||||||
this.listenerMap.keySet().forEach(this::propagateEvent);
|
this.listenerMap.keySet().forEach(aClass -> propagateEvent(parent, aClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void propagateEvent(Class<? extends T> eventClass) {
|
private void propagateEvent(EventNodeImpl parent, Class<? extends T> eventClass) {
|
||||||
|
if (parent == null) return;
|
||||||
forTargetEvents(eventClass, type -> {
|
forTargetEvents(eventClass, type -> {
|
||||||
final var parent = this.parent;
|
Handle<? super T> parentHandle = (Handle<? super T>) parent.handleMap.get(type);
|
||||||
if (parent == null) return;
|
|
||||||
Handle<? super T> parentHandle = parent.handleMap.get(type);
|
|
||||||
if (parentHandle == null) return;
|
if (parentHandle == null) return;
|
||||||
parentHandle.updated = false;
|
parentHandle.updated = false;
|
||||||
parent.propagateEvent((Class<? extends T>) type);
|
parent.propagateEvent(parent.parent, type);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user