Add ForgeEventCancellable

This commit is contained in:
shedaniel
2020-12-27 18:06:53 +08:00
parent 12680fde12
commit 575654f2bb
4 changed files with 97 additions and 1 deletions

View File

@@ -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 {
}

View File

@@ -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 <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
protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
for (Actor<T> 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 <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 final Function<List<T>, T> function;
private T invoker = null;

View File

@@ -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 <T> Event<Consumer<T>> attachToForge(Event<Consumer<T>> 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;
}
}

View File

@@ -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 <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;
}
}