From 575654f2bb1396f76b5181a5f02c9d3c5932aceb Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 27 Dec 2020 18:06:53 +0800 Subject: [PATCH] Add ForgeEventCancellable --- .../architectury/ForgeEventCancellable.java | 30 +++++++++++++++++++ .../architectury/event/EventFactory.java | 30 ++++++++++++++++++- .../event/fabric/EventFactoryImpl.java | 9 ++++++ .../event/forge/EventFactoryImpl.java | 29 ++++++++++++++++++ 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 common/src/main/java/me/shedaniel/architectury/ForgeEventCancellable.java diff --git a/common/src/main/java/me/shedaniel/architectury/ForgeEventCancellable.java b/common/src/main/java/me/shedaniel/architectury/ForgeEventCancellable.java new file mode 100644 index 00000000..315c5ca1 --- /dev/null +++ b/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 { +} diff --git a/common/src/main/java/me/shedaniel/architectury/event/EventFactory.java b/common/src/main/java/me/shedaniel/architectury/event/EventFactory.java index 5bce2ff9..1c1f6619 100644 --- a/common/src/main/java/me/shedaniel/architectury/event/EventFactory.java +++ b/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 me.shedaniel.architectury.ExpectPlatform; import me.shedaniel.architectury.ForgeEvent; +import me.shedaniel.architectury.ForgeEventCancellable; import net.jodah.typetools.TypeResolver; import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResultHolder; @@ -125,7 +126,7 @@ public final class EventFactory { @SuppressWarnings("UnstableApiUsage") public static Event> createActorLoop(Class clazz) { - return of(listeners -> (Actor) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{Actor.class}, new AbstractInvocationHandler() { + Event> event = of(listeners -> (Actor) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{Actor.class}, new AbstractInvocationHandler() { @Override protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable { for (Actor listener : listeners) { @@ -137,6 +138,23 @@ public final class EventFactory { 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 @@ -144,6 +162,16 @@ public final class EventFactory { throw new AssertionError(); } + @ExpectPlatform + public static Event> attachToForgeActor(Event> event) { + throw new AssertionError(); + } + + @ExpectPlatform + public static Event> attachToForgeActorCancellable(Event> event) { + throw new AssertionError(); + } + private static class EventImpl implements Event { private final Function, T> function; private T invoker = null; diff --git a/fabric/src/main/java/me/shedaniel/architectury/event/fabric/EventFactoryImpl.java b/fabric/src/main/java/me/shedaniel/architectury/event/fabric/EventFactoryImpl.java index c97073dc..766ea177 100644 --- a/fabric/src/main/java/me/shedaniel/architectury/event/fabric/EventFactoryImpl.java +++ b/fabric/src/main/java/me/shedaniel/architectury/event/fabric/EventFactoryImpl.java @@ -19,6 +19,7 @@ package me.shedaniel.architectury.event.fabric; +import me.shedaniel.architectury.event.Actor; import me.shedaniel.architectury.event.Event; import java.util.function.Consumer; @@ -27,4 +28,12 @@ public class EventFactoryImpl { public static Event> attachToForge(Event> event) { return event; } + + public static Event> attachToForgeActor(Event> event) { + return event; + } + + public static Event> attachToForgeActorCancellable(Event> event) { + return event; + } } diff --git a/forge/src/main/java/me/shedaniel/architectury/event/forge/EventFactoryImpl.java b/forge/src/main/java/me/shedaniel/architectury/event/forge/EventFactoryImpl.java index bd2e691f..f02c8907 100644 --- a/forge/src/main/java/me/shedaniel/architectury/event/forge/EventFactoryImpl.java +++ b/forge/src/main/java/me/shedaniel/architectury/event/forge/EventFactoryImpl.java @@ -19,7 +19,9 @@ package me.shedaniel.architectury.event.forge; +import me.shedaniel.architectury.event.Actor; import me.shedaniel.architectury.event.Event; +import net.minecraft.world.InteractionResult; import net.minecraftforge.common.MinecraftForge; import java.util.function.Consumer; @@ -34,4 +36,31 @@ public class EventFactoryImpl { }); return event; } + + public static Event> attachToForgeActor(Event> 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 Event> attachToForgeActorCancellable(Event> 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; + } } \ No newline at end of file