diff --git a/neoforge/src/main/java/yesman/epicfight/api/event/CancelableEventHook.java b/neoforge/src/main/java/yesman/epicfight/api/event/CancelableEventHook.java index 8d286bf14..466876d01 100644 --- a/neoforge/src/main/java/yesman/epicfight/api/event/CancelableEventHook.java +++ b/neoforge/src/main/java/yesman/epicfight/api/event/CancelableEventHook.java @@ -1,9 +1,12 @@ package yesman.epicfight.api.event; +import com.google.common.collect.Lists; import yesman.epicfight.api.event.subscription.ContextAwareEventSubscription; import yesman.epicfight.api.event.subscription.DefaultEventSubscription; import yesman.epicfight.api.utils.side.LogicalSide; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Stream; /// EventHook definition for [CancelableEvent] @@ -19,25 +22,28 @@ protected CancelableEventHook(LogicalSide logicalSide) { public T post(T event) { EventContext eventContext = event.getEventContext(); - for (EventListener subscriber : this.subscribers.values()) { - eventContext.subscriptionStart(subscriber.identifier()); - - if (subscriber.subscriptionType() instanceof DefaultEventSubscription defaultSubscription) { - if (!event.isCanceled()) { - defaultSubscription.fire(event); - eventContext.onCalled(); - } - } else if (subscriber.subscriptionType() instanceof ContextAwareEventSubscription contextAwareSubscription) { - contextAwareSubscription.fire(event, eventContext); - eventContext.onCalled(); - } + for (var subscriber : subscribers.values()) { + subscriber.forEach(subs -> processSub(event, subs, eventContext)); } - eventContext.subscriptionEnd(); return event; } + private void processSub(T event, EventListener subscriber, EventContext eventContext) + { + eventContext.subscriptionStart(subscriber.identifier()); + if (subscriber.subscriptionType() instanceof DefaultEventSubscription defaultSubscription) { + if (!event.isCanceled()) { + defaultSubscription.fire(event); + eventContext.onCalled(); + } + } else if (subscriber.subscriptionType() instanceof ContextAwareEventSubscription contextAwareSubscription) { + contextAwareSubscription.fire(event, eventContext); + eventContext.onCalled(); + } + } + /// Post the event to subscribers including from [EntityEventListener], and execute tasks by their priority in descending order @Override public T postWithListener(T event, EntityEventListener eventListener) { @@ -47,21 +53,11 @@ public T postWithListener(T event, EntityEventListener eventListener) { EventContext eventContext = event.getEventContext(); - Stream.concat(this.subscribers.values().stream(), eventListener.getListenersFor(this)) - .sorted((o1, o2) -> Integer.compare(o2.priority(), o1.priority())) - .forEach(subscriber -> { - eventContext.subscriptionStart(subscriber.identifier()); - - if (subscriber.subscriptionType() instanceof DefaultEventSubscription defaultSubscription) { - if (!event.isCanceled()) { - defaultSubscription.fire(event); - eventContext.onCalled(); - } - } else if (subscriber.subscriptionType() instanceof ContextAwareEventSubscription contextAwareSubscription) { - contextAwareSubscription.fire(event, eventContext); - eventContext.onCalled(); - } - }); + List> buffer = Lists.newArrayList(); + this.subscribers.values().forEach(buffer::addAll); + Stream.concat(buffer.stream(), eventListener.getListenersFor(this)) + .sorted(EventHook::reverseOrder) + .forEach(subs -> processSub(event, subs, eventContext)); eventContext.subscriptionEnd(); @@ -87,7 +83,7 @@ public void registerContextAwareEvent(ContextAwareEventSubscription subscript /// Registers an event with full parameters public void registerContextAwareEvent(ContextAwareEventSubscription subscription, String name, int priority) { - this.subscribers.put(priority, new EventListener<> (name, priority, subscription)); + this.subscribers.computeIfAbsent(priority, sub -> new CopyOnWriteArrayList<>()).add(new EventListener<>(name, priority, subscription)); } /// Defines a cancelable event hook diff --git a/neoforge/src/main/java/yesman/epicfight/api/event/EventHook.java b/neoforge/src/main/java/yesman/epicfight/api/event/EventHook.java index 63598d7a6..b63491fe8 100644 --- a/neoforge/src/main/java/yesman/epicfight/api/event/EventHook.java +++ b/neoforge/src/main/java/yesman/epicfight/api/event/EventHook.java @@ -7,7 +7,9 @@ import java.util.Comparator; import java.util.List; -import java.util.TreeMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Stream; /// An event bus that is dedicated to one [Event] type @@ -20,7 +22,7 @@ /// and [EpicFightClientEventHooks] for client-side only events public class EventHook { /// Treemap to order subscribers in descending order - final TreeMap>> subscribers = new TreeMap<> ((i1, i2) -> Integer.compare(i2, i1)); + final ConcurrentMap>> subscribers = new ConcurrentSkipListMap<>(Comparator.reverseOrder()); /// Determines if the event is only called in logical side protected final LogicalSide logicalSide; @@ -31,10 +33,9 @@ protected EventHook(LogicalSide logicalSide) { /// Post the event to subscribers and execute tasks by their priority in descending order public T post(T event) { - - for (var subscriberList : this.subscribers.values()) { - for (var subscriber : subscriberList) { - if (subscriber.subscriptionType() instanceof DefaultEventSubscription passiveSubscription) { + for (var subscriber : subscribers.values()) { + for (var listener : subscriber) { + if (listener.subscriptionType() instanceof DefaultEventSubscription passiveSubscription) { passiveSubscription.fire(event); } } @@ -51,7 +52,7 @@ public T postWithListener(T event, EntityEventListener eventListener) { List> buffer = Lists.newArrayList(); this.subscribers.values().forEach(buffer::addAll); Stream.concat(buffer.stream(), eventListener.getListenersFor(this)) - .sorted(Comparator.comparingInt(EventListener::priority)) + .sorted(EventHook::reverseOrder) .forEach(subs -> { if (subs.subscriptionType() instanceof DefaultEventSubscription passiveSubscription) { passiveSubscription.fire(event); @@ -60,6 +61,11 @@ public T postWithListener(T event, EntityEventListener eventListener) { return event; } + public static int reverseOrder(EventListener A, EventListener B) + { + return Integer.compare(B.priority(), A.priority()); + } + /// Registers an event with default identifier and priority public void registerEvent(DefaultEventSubscription subscription) { this.registerEvent(subscription, getDefaultSubscriberName(), 0); @@ -79,7 +85,7 @@ public void registerEvent(DefaultEventSubscription subscription, String name) /// Registers an event with full parameters public void registerEvent(DefaultEventSubscription subscription, String name, int priority) { - this.subscribers.computeIfAbsent(priority, sub -> Lists.newArrayList()).add(new EventListener<>(name,priority,subscription)); + this.subscribers.computeIfAbsent(priority, sub -> new CopyOnWriteArrayList<>()).add(new EventListener<>(name,priority,subscription)); } public final LogicalSide logicalSide() {