Browse Source

Add ForgeEventCancellable

shedaniel 4 years ago
parent
commit
575654f2bb

+ 30 - 0
common/src/main/java/me/shedaniel/architectury/ForgeEventCancellable.java

@@ -0,0 +1,30 @@
+/*
+ * This file is part of architectury.
+ * Copyright (C) 2020 shedaniel
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package me.shedaniel.architectury;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ForgeEventCancellable {
+}

+ 29 - 1
common/src/main/java/me/shedaniel/architectury/event/EventFactory.java

@@ -22,6 +22,7 @@ package me.shedaniel.architectury.event;
 import com.google.common.reflect.AbstractInvocationHandler;
 import com.google.common.reflect.AbstractInvocationHandler;
 import me.shedaniel.architectury.ExpectPlatform;
 import me.shedaniel.architectury.ExpectPlatform;
 import me.shedaniel.architectury.ForgeEvent;
 import me.shedaniel.architectury.ForgeEvent;
+import me.shedaniel.architectury.ForgeEventCancellable;
 import net.jodah.typetools.TypeResolver;
 import net.jodah.typetools.TypeResolver;
 import net.minecraft.world.InteractionResult;
 import net.minecraft.world.InteractionResult;
 import net.minecraft.world.InteractionResultHolder;
 import net.minecraft.world.InteractionResultHolder;
@@ -125,7 +126,7 @@ public final class EventFactory {
     
     
     @SuppressWarnings("UnstableApiUsage")
     @SuppressWarnings("UnstableApiUsage")
     public static <T> Event<Actor<T>> createActorLoop(Class<T> clazz) {
     public static <T> Event<Actor<T>> createActorLoop(Class<T> clazz) {
-        return of(listeners -> (Actor<T>) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{Actor.class}, new AbstractInvocationHandler() {
+        Event<Actor<T>> event = of(listeners -> (Actor<T>) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{Actor.class}, new AbstractInvocationHandler() {
             @Override
             @Override
             protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
             protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
                 for (Actor<T> listener : listeners) {
                 for (Actor<T> listener : listeners) {
@@ -137,6 +138,23 @@ public final class EventFactory {
                 return InteractionResult.PASS;
                 return InteractionResult.PASS;
             }
             }
         }));
         }));
+        Class<?> superClass = clazz;
+        do {
+            
+            if (superClass.isAnnotationPresent(ForgeEventCancellable.class)) {
+                return attachToForgeActorCancellable(event);
+            }
+            superClass = superClass.getSuperclass();
+        } while (superClass != null);
+        superClass = clazz;
+        do {
+            
+            if (superClass.isAnnotationPresent(ForgeEvent.class)) {
+                return attachToForgeActor(event);
+            }
+            superClass = superClass.getSuperclass();
+        } while (superClass != null);
+        return event;
     }
     }
     
     
     @ExpectPlatform
     @ExpectPlatform
@@ -144,6 +162,16 @@ public final class EventFactory {
         throw new AssertionError();
         throw new AssertionError();
     }
     }
     
     
+    @ExpectPlatform
+    public static <T> Event<Actor<T>> attachToForgeActor(Event<Actor<T>> event) {
+        throw new AssertionError();
+    }
+    
+    @ExpectPlatform
+    public static <T> Event<Actor<T>> attachToForgeActorCancellable(Event<Actor<T>> event) {
+        throw new AssertionError();
+    }
+    
     private static class EventImpl<T> implements Event<T> {
     private static class EventImpl<T> implements Event<T> {
         private final Function<List<T>, T> function;
         private final Function<List<T>, T> function;
         private T invoker = null;
         private T invoker = null;

+ 9 - 0
fabric/src/main/java/me/shedaniel/architectury/event/fabric/EventFactoryImpl.java

@@ -19,6 +19,7 @@
 
 
 package me.shedaniel.architectury.event.fabric;
 package me.shedaniel.architectury.event.fabric;
 
 
+import me.shedaniel.architectury.event.Actor;
 import me.shedaniel.architectury.event.Event;
 import me.shedaniel.architectury.event.Event;
 
 
 import java.util.function.Consumer;
 import java.util.function.Consumer;
@@ -27,4 +28,12 @@ public class EventFactoryImpl {
     public static <T> Event<Consumer<T>> attachToForge(Event<Consumer<T>> event) {
     public static <T> Event<Consumer<T>> attachToForge(Event<Consumer<T>> event) {
         return event;
         return event;
     }
     }
+    
+    public static <T> Event<Actor<T>> attachToForgeActor(Event<Actor<T>> event) {
+        return event;
+    }
+    
+    public static <T> Event<Actor<T>> attachToForgeActorCancellable(Event<Actor<T>> event) {
+        return event;
+    }
 }
 }

+ 29 - 0
forge/src/main/java/me/shedaniel/architectury/event/forge/EventFactoryImpl.java

@@ -19,7 +19,9 @@
 
 
 package me.shedaniel.architectury.event.forge;
 package me.shedaniel.architectury.event.forge;
 
 
+import me.shedaniel.architectury.event.Actor;
 import me.shedaniel.architectury.event.Event;
 import me.shedaniel.architectury.event.Event;
+import net.minecraft.world.InteractionResult;
 import net.minecraftforge.common.MinecraftForge;
 import net.minecraftforge.common.MinecraftForge;
 
 
 import java.util.function.Consumer;
 import java.util.function.Consumer;
@@ -34,4 +36,31 @@ public class EventFactoryImpl {
         });
         });
         return event;
         return event;
     }
     }
+    
+    public static <T> Event<Actor<T>> attachToForgeActor(Event<Actor<T>> event) {
+        event.register(eventObj -> {
+            if (!(eventObj instanceof net.minecraftforge.eventbus.api.Event)) {
+                throw new ClassCastException(eventObj.getClass() + " is not an instance of forge Event!");
+            }
+            MinecraftForge.EVENT_BUS.post((net.minecraftforge.eventbus.api.Event) eventObj);
+            return InteractionResult.PASS;
+        });
+        return event;
+    }
+    
+    public static <T> Event<Actor<T>> attachToForgeActorCancellable(Event<Actor<T>> event) {
+        event.register(eventObj -> {
+            if (!(eventObj instanceof net.minecraftforge.eventbus.api.Event)) {
+                throw new ClassCastException(eventObj.getClass() + " is not an instance of forge Event!");
+            }
+            if (!((net.minecraftforge.eventbus.api.Event) eventObj).isCancelable()) {
+                throw new ClassCastException(eventObj.getClass() + " is not cancellable Event!");
+            }
+            if (MinecraftForge.EVENT_BUS.post((net.minecraftforge.eventbus.api.Event) eventObj)) {
+                return InteractionResult.FAIL;
+            }
+            return InteractionResult.PASS;
+        });
+        return event;
+    }
 }
 }