Skip to content

Commit

Permalink
Simplify listener class checks in posting hot-path (#62)
Browse files Browse the repository at this point in the history
Remove the need for Objects#equals in the posting hot-path
Remove null check in ASMEventHandler#invoke
The handler is created by the factory, which for ASM and ClassFactory goes through IEventListenerFactory#getUniqueName, which would throw an NPE during handler creation, therefore handler can never be null.
Cleanup ASMEventHandler, make filter final
  • Loading branch information
PaintNinja authored Dec 25, 2024
1 parent 42eba1c commit 913fb17
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 12 deletions.
19 changes: 8 additions & 11 deletions src/main/java/net/minecraftforge/eventbus/ASMEventHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,40 @@
import static org.objectweb.asm.Type.getMethodDescriptor;

public class ASMEventHandler implements IEventListener {
private final IEventListenerFactory factory;
private final IEventListener handler;
private final SubscribeEvent subInfo;
private final String readable;
private Type filter = null;
private final Type filter;

public ASMEventHandler(IEventListenerFactory factory, Object target, Method method, boolean isGeneric) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException {
this.factory = factory;
handler = this.factory.create(method, target);
handler = factory.create(method, target);

subInfo = method.getAnnotation(SubscribeEvent.class);
readable = "ASM: " + target + " " + method.getName() + getMethodDescriptor(method);
Type filter = null;
if (isGeneric) {
Type type = method.getGenericParameterTypes()[0];
if (type instanceof ParameterizedType) {
filter = ((ParameterizedType)type).getActualTypeArguments()[0];
if (filter instanceof ParameterizedType) // Unlikely that nested generics will ever be relevant for event filtering, so discard them
filter = ((ParameterizedType)filter).getRawType();
else if (filter instanceof WildcardType) {
else if (filter instanceof WildcardType wfilter) {
// If there's a wildcard filter of Object.class, then remove the filter.
final WildcardType wfilter = (WildcardType) filter;
if (wfilter.getUpperBounds().length == 1 && wfilter.getUpperBounds()[0] == Object.class && wfilter.getLowerBounds().length == 0) {
filter = null;
}
}
}
}
this.filter = filter;
}

@SuppressWarnings("rawtypes")
@Override
public void invoke(Event event) {
if (handler != null) {
if (!event.isCanceled() || subInfo.receiveCanceled()) {
if (filter == null || filter == ((IGenericEvent)event).getGenericType())
handler.invoke(event);
}
if (!event.isCanceled() || subInfo.receiveCanceled()) {
if (filter == null || filter == ((IGenericEvent)event).getGenericType())
handler.invoke(event);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/minecraftforge/eventbus/EventBus.java
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ public boolean post(Event event, IEventBusInvokeDispatcher wrapper) {
int index = 0;
try {
for (; index < listeners.length; index++) {
if (!trackPhases && Objects.equals(listeners[index].getClass(), EventPriority.class)) continue;
if (!trackPhases && listeners[index].getClass() == EventPriority.class) continue;
wrapper.invoke(listeners[index], event);
}
} catch (Throwable throwable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ private void buildCache() {
}

public void register(EventPriority priority, IEventListener listener) {
if (listener == null) return;
writeLock.acquireUninterruptibly();
priorities.get(priority.ordinal()).add(listener);
writeLock.release();
Expand Down

0 comments on commit 913fb17

Please sign in to comment.