diff --git a/eventbus-test-jar/src/main/java/net/minecraftforge/eventbus/testjar/benchmarks/ModLauncherBenchmarks.java b/eventbus-test-jar/src/main/java/net/minecraftforge/eventbus/testjar/benchmarks/ModLauncherBenchmarks.java index 73442506..bd8fc55e 100644 --- a/eventbus-test-jar/src/main/java/net/minecraftforge/eventbus/testjar/benchmarks/ModLauncherBenchmarks.java +++ b/eventbus-test-jar/src/main/java/net/minecraftforge/eventbus/testjar/benchmarks/ModLauncherBenchmarks.java @@ -6,6 +6,7 @@ package net.minecraftforge.eventbus.testjar.benchmarks; import net.minecraftforge.eventbus.api.BusBuilder; +import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.testjar.events.CancelableEvent; import net.minecraftforge.eventbus.testjar.events.EventWithData; @@ -28,7 +29,7 @@ private ModLauncherBenchmarks() {} public static final class Post { private Post() {} - private static final IEventBus EVENT_BUS = BusBuilder.builder().useModLauncher().build(); + private static final IEventBus EVENT_BUS = BusBuilder.builder().useModLauncher().setPhasesToTrack(EventPriority.MONITOR).build(); public static void setup(int multiplier, Supplier> registrar) { for (int i = 0; i < multiplier; i++) diff --git a/eventbus-test-jar/src/main/java/net/minecraftforge/eventbus/testjar/benchmarks/NoLoaderBenchmarks.java b/eventbus-test-jar/src/main/java/net/minecraftforge/eventbus/testjar/benchmarks/NoLoaderBenchmarks.java index de2185aa..f456a14f 100644 --- a/eventbus-test-jar/src/main/java/net/minecraftforge/eventbus/testjar/benchmarks/NoLoaderBenchmarks.java +++ b/eventbus-test-jar/src/main/java/net/minecraftforge/eventbus/testjar/benchmarks/NoLoaderBenchmarks.java @@ -6,6 +6,7 @@ package net.minecraftforge.eventbus.testjar.benchmarks; import net.minecraftforge.eventbus.api.BusBuilder; +import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.testjar.events.CancelableEvent; import net.minecraftforge.eventbus.testjar.events.EventWithData; @@ -28,7 +29,7 @@ private NoLoaderBenchmarks() {} public static final class Post { private Post() {} - private static final IEventBus EVENT_BUS = BusBuilder.builder().build(); + private static final IEventBus EVENT_BUS = BusBuilder.builder().setPhasesToTrack(EventPriority.MONITOR).build(); public static void setup(int multiplier, Supplier> registrar) { for (int i = 0; i < multiplier; i++) diff --git a/src/main/java/net/minecraftforge/eventbus/BusBuilderImpl.java b/src/main/java/net/minecraftforge/eventbus/BusBuilderImpl.java index 4356e521..4b25eebf 100644 --- a/src/main/java/net/minecraftforge/eventbus/BusBuilderImpl.java +++ b/src/main/java/net/minecraftforge/eventbus/BusBuilderImpl.java @@ -4,17 +4,21 @@ */ package net.minecraftforge.eventbus; -import net.minecraftforge.eventbus.api.BusBuilder; -import net.minecraftforge.eventbus.api.Event; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.eventbus.api.IEventExceptionHandler; +import net.minecraftforge.eventbus.api.*; + +import java.util.EnumSet; /** * BusBuilder Implementation, public for BusBuilder.builder() only, don't use this directly. */ public final class BusBuilderImpl implements BusBuilder { + static final EnumSet ALL_PHASES = EnumSet.allOf(EventPriority.class); + static final EnumSet NO_PHASES = EnumSet.noneOf(EventPriority.class); + private static final EnumSet MONITOR_ONLY = EnumSet.of(EventPriority.MONITOR); + IEventExceptionHandler exceptionHandler; boolean trackPhases = true; + EnumSet phasesToTrack = ALL_PHASES; boolean startShutdown = false; boolean checkTypesOnDispatch = false; Class markerType = Event.class; @@ -23,9 +27,29 @@ public final class BusBuilderImpl implements BusBuilder { @Override public BusBuilder setTrackPhases(boolean trackPhases) { this.trackPhases = trackPhases; + this.phasesToTrack = trackPhases ? ALL_PHASES : NO_PHASES; return this; } + @Override + public BusBuilder setPhasesToTrack(EnumSet phases) { + if (phases.isEmpty()) { + this.trackPhases = false; + this.phasesToTrack = NO_PHASES; + } else { + this.trackPhases = true; + this.phasesToTrack = phases; + } + return this; + } + + @Override + public BusBuilder setPhasesToTrack(EventPriority phase) { + return phase == EventPriority.MONITOR + ? setPhasesToTrack(BusBuilderImpl.MONITOR_ONLY) + : setPhasesToTrack(EnumSet.of(phase)); + } + @Override public BusBuilder setExceptionHandler(IEventExceptionHandler handler) { this.exceptionHandler = handler; diff --git a/src/main/java/net/minecraftforge/eventbus/EventBus.java b/src/main/java/net/minecraftforge/eventbus/EventBus.java index 46ccbf88..1fc4f314 100644 --- a/src/main/java/net/minecraftforge/eventbus/EventBus.java +++ b/src/main/java/net/minecraftforge/eventbus/EventBus.java @@ -25,7 +25,9 @@ public class EventBus implements IEventExceptionHandler, IEventBus { private static final Logger LOGGER = LogManager.getLogger(); private static final boolean checkTypesOnDispatchProperty = Boolean.parseBoolean(System.getProperty("eventbus.checkTypesOnDispatch", "false")); private static final AtomicInteger maxID = new AtomicInteger(0); + private final boolean trackPhases; + final EnumSet phasesToTrack; private final ConcurrentHashMap> listeners = new ConcurrentHashMap<>(); private final int busID = maxID.getAndIncrement(); @@ -41,16 +43,18 @@ private EventBus() { ListenerList.resize(busID + 1); exceptionHandler = this; this.trackPhases = true; + this.phasesToTrack = BusBuilderImpl.ALL_PHASES; this.baseType = Event.class; this.checkTypesOnDispatch = checkTypesOnDispatchProperty; this.factory = new ClassLoaderFactory(); } - private EventBus(final IEventExceptionHandler handler, boolean trackPhase, boolean startShutdown, Class baseType, boolean checkTypesOnDispatch, IEventListenerFactory factory) { + private EventBus(final IEventExceptionHandler handler, boolean trackPhase, EnumSet phasesToTrack, boolean startShutdown, Class baseType, boolean checkTypesOnDispatch, IEventListenerFactory factory) { ListenerList.resize(busID + 1); if (handler == null) exceptionHandler = this; else exceptionHandler = handler; this.trackPhases = trackPhase; + this.phasesToTrack = trackPhase ? phasesToTrack : BusBuilderImpl.NO_PHASES; this.shutdown = startShutdown; this.baseType = baseType; this.checkTypesOnDispatch = checkTypesOnDispatch || checkTypesOnDispatchProperty; @@ -58,7 +62,7 @@ private EventBus(final IEventExceptionHandler handler, boolean trackPhase, boole } public EventBus(final BusBuilderImpl busBuilder) { - this(busBuilder.exceptionHandler, busBuilder.trackPhases, busBuilder.startShutdown, + this(busBuilder.exceptionHandler, busBuilder.trackPhases, busBuilder.phasesToTrack, busBuilder.startShutdown, busBuilder.markerType, busBuilder.checkTypesOnDispatch, busBuilder.modLauncher ? new ModLauncherFactory() : new ClassLoaderFactory()); } @@ -268,7 +272,7 @@ private void register(Class eventType, Object target, Method method) { private void addToListeners(final Object target, final Class eventType, final IEventListener listener, final EventPriority priority) { ListenerList listenerList = EventListenerHelper.getListenerList(eventType); - listenerList.register(busID, priority, listener); + listenerList.register(busID, this, priority, listener); List others = listeners.computeIfAbsent(target, k -> Collections.synchronizedList(new ArrayList<>())); others.add(listener); } diff --git a/src/main/java/net/minecraftforge/eventbus/ListenerList.java b/src/main/java/net/minecraftforge/eventbus/ListenerList.java index 02ba68f9..a87b7667 100644 --- a/src/main/java/net/minecraftforge/eventbus/ListenerList.java +++ b/src/main/java/net/minecraftforge/eventbus/ListenerList.java @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.EnumSet; import java.util.List; import java.util.concurrent.Semaphore; @@ -85,6 +86,12 @@ public void register(int id, EventPriority priority, IEventListener listener) { lists[id].register(priority, listener); } + public void register(int id, EventBus eventBus, EventPriority priority, IEventListener listener) { + var list = lists[id]; + list.phasesToTrack = eventBus.phasesToTrack; + list.register(priority, listener); + } + public void unregister(int id, IEventListener listener) { lists[id].unregister(listener); } @@ -115,6 +122,7 @@ private static class ListenerListInst { private ListenerListInst parent; private List children; private final Semaphore writeLock = new Semaphore(1, true); + private EnumSet phasesToTrack = BusBuilderImpl.ALL_PHASES; private ListenerListInst() {} @@ -216,7 +224,8 @@ private IEventListener[] buildCache() { for (EventPriority value : EVENT_PRIORITY_VALUES) { List listeners = getListeners(value); if (listeners.isEmpty()) continue; - ret.add(value); // Add the priority to notify the event of its current phase. + if (phasesToTrack.contains(value)) + ret.add(value); // Add the priority to notify the event of its current phase. ret.addAll(listeners); } diff --git a/src/main/java/net/minecraftforge/eventbus/api/BusBuilder.java b/src/main/java/net/minecraftforge/eventbus/api/BusBuilder.java index 1b8a7c37..ab81ca3d 100644 --- a/src/main/java/net/minecraftforge/eventbus/api/BusBuilder.java +++ b/src/main/java/net/minecraftforge/eventbus/api/BusBuilder.java @@ -6,6 +6,8 @@ import net.minecraftforge.eventbus.BusBuilderImpl; +import java.util.EnumSet; + /** * Build a bus */ @@ -16,6 +18,15 @@ public static BusBuilder builder() { /* true by default */ BusBuilder setTrackPhases(boolean trackPhases); + default BusBuilder setPhasesToTrack(EnumSet phases) { + throw new UnsupportedOperationException(); + } + default BusBuilder setPhasesToTrack(EventPriority... phases) { + return setPhasesToTrack(EnumSet.of(phases[0], phases)); + } + default BusBuilder setPhasesToTrack(EventPriority phase) { + return setPhasesToTrack(EnumSet.of(phase)); + } BusBuilder setExceptionHandler(IEventExceptionHandler handler); BusBuilder startShutdown(); BusBuilder checkTypesOnDispatch();