mirror of
https://github.com/EngineHub/WorldEdit.git
synced 2024-12-15 04:41:37 +08:00
Use MethodHandle for faster event bus (#1865)
* Use MethodHandle for faster event bus * Implement hashCode/equals * Apply review comments * Bind to the object directly
This commit is contained in:
parent
8ee45137aa
commit
4277cb5239
@ -22,6 +22,8 @@
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
@ -59,7 +61,14 @@ public Multimap<Class<?>, EventHandler> findAllSubscribers(Object listener) {
|
||||
);
|
||||
}
|
||||
Class<?> eventType = parameterTypes[0];
|
||||
EventHandler handler = new MethodEventHandler(annotation.priority(), listener, method);
|
||||
MethodHandle handle;
|
||||
try {
|
||||
handle = MethodHandles.publicLookup().unreflect(method);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalArgumentException("Method " + method + " failed to unreflect.", e);
|
||||
}
|
||||
|
||||
EventHandler handler = new MethodHandleEventHandler(annotation.priority(), listener, handle, method.getName());
|
||||
methodsInListener.put(eventType, handler);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
package com.sk89q.worldedit.util.eventbus;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@ -72,11 +73,8 @@ public boolean equals(Object o) {
|
||||
if (!method.equals(that.method)) {
|
||||
return false;
|
||||
}
|
||||
if (object != null ? !object.equals(that.object) : that.object != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return Objects.equals(object, that.object);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.eventbus;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.Objects;
|
||||
|
||||
public class MethodHandleEventHandler extends EventHandler {
|
||||
|
||||
private final MethodHandle methodHandle;
|
||||
private final String methodName;
|
||||
private final Object object;
|
||||
|
||||
/**
|
||||
* Create a new event handler that uses MethodHandles to dispatch.
|
||||
*
|
||||
* @param priority the priority
|
||||
* @param object The object to invoke it on
|
||||
* @param methodHandle The handle to invoke
|
||||
* @param methodName The name of the method (for equality checks)
|
||||
*/
|
||||
protected MethodHandleEventHandler(Priority priority, Object object, MethodHandle methodHandle, String methodName) {
|
||||
super(priority);
|
||||
|
||||
this.object = object;
|
||||
this.methodHandle = methodHandle.bindTo(object).asType(MethodType.methodType(void.class, Object.class));
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(Object event) throws Exception {
|
||||
try {
|
||||
this.methodHandle.invokeExact(event);
|
||||
} catch (Exception | Error e) {
|
||||
throw e;
|
||||
} catch (Throwable t) {
|
||||
// If it's not an Exception or Error, throw it wrapped.
|
||||
throw new Exception(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(methodName, object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MethodHandleEventHandler that = (MethodHandleEventHandler) o;
|
||||
|
||||
if (!methodName.equals(that.methodName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Objects.equals(object, that.object);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user