浏览代码

Switch to MethodHandlers to avoid wrapping exceptions with InvocationTargetException due to reflection

shedaniel 3 年之前
父节点
当前提交
9a5de11b59

+ 14 - 8
common/src/main/java/me/shedaniel/architectury/event/EventFactory.java

@@ -29,6 +29,7 @@ import net.minecraft.world.InteractionResultHolder;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 
+import java.lang.invoke.MethodHandles;
 import java.lang.reflect.Array;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
@@ -65,13 +66,18 @@ public final class EventFactory {
         return createLoop((Class<T>) typeGetter.getClass().getComponentType());
     }
     
+    private static <T, R> R invokeMethod(T listener, Method method, Object[] args) throws Throwable {
+        return (R) MethodHandles.lookup().unreflect(method)
+                .bindTo(listener).invokeWithArguments(args);
+    }
+    
     @SuppressWarnings("UnstableApiUsage")
     public static <T> Event<T> createLoop(Class<T> clazz) {
         return of(listeners -> (T) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{clazz}, new AbstractInvocationHandler() {
             @Override
             protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
                 for (T listener : listeners) {
-                    method.invoke(listener, args);
+                    invokeMethod(listener, method, args);
                 }
                 return null;
             }
@@ -94,7 +100,7 @@ public final class EventFactory {
             @Override
             protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
                 for (T listener : listeners) {
-                    InteractionResult result = (InteractionResult) Objects.requireNonNull(method.invoke(listener, args));
+                    InteractionResult result = Objects.requireNonNull(invokeMethod(listener, method, args));
                     if (result != InteractionResult.PASS) {
                         return result;
                     }
@@ -116,7 +122,7 @@ public final class EventFactory {
             @Override
             protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
                 for (T listener : listeners) {
-                    EventResult result = (EventResult) Objects.requireNonNull(method.invoke(listener, args));
+                    EventResult result = Objects.requireNonNull(invokeMethod(listener, method, args));
                     if (result.interruptsFurtherEvaluation()) {
                         return result;
                     }
@@ -142,7 +148,7 @@ public final class EventFactory {
             @Override
             protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
                 for (T listener : listeners) {
-                    InteractionResultHolder result = (InteractionResultHolder) Objects.requireNonNull(method.invoke(listener, args));
+                    InteractionResultHolder result = Objects.requireNonNull(invokeMethod(listener, method, args));
                     if (result.getResult() != InteractionResult.PASS) {
                         return result;
                     }
@@ -164,7 +170,7 @@ public final class EventFactory {
             @Override
             protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
                 for (T listener : listeners) {
-                    CompoundEventResult result = (CompoundEventResult) Objects.requireNonNull(method.invoke(listener, args));
+                    CompoundEventResult result = Objects.requireNonNull(invokeMethod(listener, method, args));
                     if (result.interruptsFurtherEvaluation()) {
                         return result;
                     }
@@ -186,7 +192,7 @@ public final class EventFactory {
             @Override
             protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
                 for (Consumer<T> listener : listeners) {
-                    method.invoke(listener, args);
+                    invokeMethod(listener, method, args);
                 }
                 return null;
             }
@@ -217,7 +223,7 @@ public final class EventFactory {
             @Override
             protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
                 for (Actor<T> listener : listeners) {
-                    InteractionResult result = (InteractionResult) method.invoke(listener, args);
+                    InteractionResult result = invokeMethod(listener, method, args);
                     if (result != InteractionResult.PASS) {
                         return result;
                     }
@@ -256,7 +262,7 @@ public final class EventFactory {
             @Override
             protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
                 for (EventActor<T> listener : listeners) {
-                    EventResult result = (EventResult) method.invoke(listener, args);
+                    EventResult result = invokeMethod(listener, method, args);
                     if (result.interruptsFurtherEvaluation()) {
                         return result;
                     }

+ 5 - 1
fabric/build.gradle

@@ -21,12 +21,16 @@ architectury {
     fabric()
 }
 
+repositories {
+    maven { url "https://maven.terraformersmc.com/releases/" }
+}
+
 dependencies {
     minecraft "com.mojang:minecraft:${rootProject.architectury.minecraft}"
     mappings minecraft.officialMojangMappings()
     modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
     modImplementation "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
-    modCompileOnly "io.github.prospector:modmenu:${rootProject.mod_menu_version}"
+    modCompileOnly "com.terraformersmc:modmenu:${rootProject.mod_menu_version}"
     implementation "net.jodah:typetools:0.6.2"
     shadowCommon "net.jodah:typetools:0.6.2"
 

+ 1 - 1
gradle.properties

@@ -11,6 +11,6 @@ maven_group=me.shedaniel
 
 fabric_loader_version=0.11.1
 fabric_api_version=0.34.2+1.16
-mod_menu_version=1.14.6+
+mod_menu_version=1.16.11+
 
 forge_version=36.0.42

+ 0 - 1
testmod-fabric/build.gradle

@@ -13,7 +13,6 @@ dependencies {
     mappings loom.officialMojangMappings()
     modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
     modImplementation "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
-    modCompileOnly "io.github.prospector:modmenu:${rootProject.mod_menu_version}"
 
     implementation project(path: ":fabric", configuration: "dev")
     implementation(project(path: ":common")) {