From fa57788fef686119582e049d175ca0fedb1a636c Mon Sep 17 00:00:00 2001 From: Technici4n <13494793+Technici4n@users.noreply.github.com> Date: Sat, 20 Apr 2024 19:11:05 +0200 Subject: [PATCH] Move `EventBusSubscriber` to top-level and cleanup Bindings suppliers (#118) * Move EventBusSubscriber to top-level and cleanup Bindings suppliers * Inline I18nParser into IBindingsProvider * Rename FORGE bus to GAME bus * Add EBS snippet in javadoc --- .../main/java/net/neoforged/fml/Bindings.java | 31 ++++---- .../java/net/neoforged/fml/I18NParser.java | 12 --- .../net/neoforged/fml/IBindingsProvider.java | 11 ++- .../neoforged/fml/ModLoadingException.java | 4 +- .../net/neoforged/fml/ModLoadingWarning.java | 2 +- .../fml/common/EventBusSubscriber.java | 79 +++++++++++++++++++ .../java/net/neoforged/fml/common/Mod.java | 66 ---------------- .../neoforged/fml/config/IConfigEvent.java | 2 +- .../javafmlmod/AutomaticEventSubscriber.java | 11 +-- 9 files changed, 113 insertions(+), 105 deletions(-) delete mode 100644 loader/src/main/java/net/neoforged/fml/I18NParser.java create mode 100644 loader/src/main/java/net/neoforged/fml/common/EventBusSubscriber.java diff --git a/loader/src/main/java/net/neoforged/fml/Bindings.java b/loader/src/main/java/net/neoforged/fml/Bindings.java index 18e66a480..25290e631 100644 --- a/loader/src/main/java/net/neoforged/fml/Bindings.java +++ b/loader/src/main/java/net/neoforged/fml/Bindings.java @@ -5,35 +5,38 @@ package net.neoforged.fml; -import cpw.mods.modlauncher.util.ServiceLoaderUtils; import java.util.ServiceLoader; -import java.util.function.Supplier; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.config.IConfigEvent; import net.neoforged.fml.loading.FMLLoader; +import org.jetbrains.annotations.ApiStatus; +@ApiStatus.Internal public class Bindings { - private static final Bindings INSTANCE = new Bindings(); + private static final IBindingsProvider provider; - private final IBindingsProvider provider; - - private Bindings() { - final var providers = ServiceLoaderUtils.streamServiceLoader(() -> ServiceLoader.load(FMLLoader.getGameLayer(), IBindingsProvider.class), sce -> {}).toList(); + static { + var providers = ServiceLoader.load(FMLLoader.getGameLayer(), IBindingsProvider.class) + .stream().toList(); if (providers.size() != 1) { throw new IllegalStateException("Could not find bindings provider"); } - this.provider = providers.get(0); + provider = providers.get(0).get(); + } + + public static IEventBus getGameBus() { + return provider.getGameBus(); } - public static Supplier getForgeBus() { - return INSTANCE.provider.getForgeBusSupplier(); + public static String parseMessage(String i18nMessage, Object... args) { + return provider.parseMessage(i18nMessage, args); } - public static Supplier getMessageParser() { - return INSTANCE.provider.getMessageParser(); + public static String stripControlCodes(String toStrip) { + return provider.stripControlCodes(toStrip); } - public static Supplier getConfigConfiguration() { - return INSTANCE.provider.getConfigConfiguration(); + public static IConfigEvent.ConfigConfig getConfigConfiguration() { + return provider.getConfigConfiguration(); } } diff --git a/loader/src/main/java/net/neoforged/fml/I18NParser.java b/loader/src/main/java/net/neoforged/fml/I18NParser.java deleted file mode 100644 index ca1c3a02a..000000000 --- a/loader/src/main/java/net/neoforged/fml/I18NParser.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.fml; - -public interface I18NParser { - String parseMessage(String i18nMessage, Object... args); - - String stripControlCodes(String toStrip); -} diff --git a/loader/src/main/java/net/neoforged/fml/IBindingsProvider.java b/loader/src/main/java/net/neoforged/fml/IBindingsProvider.java index ff48ff490..977a6b87a 100644 --- a/loader/src/main/java/net/neoforged/fml/IBindingsProvider.java +++ b/loader/src/main/java/net/neoforged/fml/IBindingsProvider.java @@ -5,14 +5,17 @@ package net.neoforged.fml; -import java.util.function.Supplier; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.config.IConfigEvent; +import org.jetbrains.annotations.ApiStatus; +@ApiStatus.Internal public interface IBindingsProvider { - Supplier getForgeBusSupplier(); + IEventBus getGameBus(); - Supplier getMessageParser(); + String parseMessage(String i18nMessage, Object... args); - Supplier getConfigConfiguration(); + String stripControlCodes(String toStrip); + + IConfigEvent.ConfigConfig getConfigConfiguration(); } diff --git a/loader/src/main/java/net/neoforged/fml/ModLoadingException.java b/loader/src/main/java/net/neoforged/fml/ModLoadingException.java index 2c7e688e3..6029a5a3b 100644 --- a/loader/src/main/java/net/neoforged/fml/ModLoadingException.java +++ b/loader/src/main/java/net/neoforged/fml/ModLoadingException.java @@ -53,7 +53,7 @@ public Object[] getContext() { public String formatToString() { // TODO: cleanup null here - this requires moving all indices in the translations - return Bindings.getMessageParser().get().parseMessage(i18nMessage, Streams.concat(Stream.of(modInfo, null, getCause()), context.stream()).toArray()); + return Bindings.parseMessage(i18nMessage, Streams.concat(Stream.of(modInfo, null, getCause()), context.stream()).toArray()); } @Override @@ -66,6 +66,6 @@ public IModInfo getModInfo() { } public String getCleanMessage() { - return Bindings.getMessageParser().get().stripControlCodes(formatToString()); + return Bindings.stripControlCodes(formatToString()); } } diff --git a/loader/src/main/java/net/neoforged/fml/ModLoadingWarning.java b/loader/src/main/java/net/neoforged/fml/ModLoadingWarning.java index 5e006a2a2..7982cea90 100644 --- a/loader/src/main/java/net/neoforged/fml/ModLoadingWarning.java +++ b/loader/src/main/java/net/neoforged/fml/ModLoadingWarning.java @@ -36,7 +36,7 @@ public ModLoadingWarning(final IModInfo modInfo, final String i18nMessage, Objec public String formatToString() { // TODO: cleanup null here - this requires moving all indices in the translations - return Bindings.getMessageParser().get().parseMessage(i18nMessage, Streams.concat(Stream.of(modInfo, null), context.stream()).toArray()); + return Bindings.parseMessage(i18nMessage, Streams.concat(Stream.of(modInfo, null), context.stream()).toArray()); } static Stream fromEarlyException(final EarlyLoadingException e) { diff --git a/loader/src/main/java/net/neoforged/fml/common/EventBusSubscriber.java b/loader/src/main/java/net/neoforged/fml/common/EventBusSubscriber.java new file mode 100644 index 000000000..49499969c --- /dev/null +++ b/loader/src/main/java/net/neoforged/fml/common/EventBusSubscriber.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.fml.common; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.ModContainer; + +// @formatter:off - spotless doesn't like @ +/** + * Annotate a class which will be subscribed to an Event Bus at mod construction time. Defaults to subscribing the current modid to the {@code NeoForge#EVENT_BUS} on both sides. + * + *

Annotated classes will be scanned for static methods that have the {@link SubscribeEvent} annotation. + * For example: + * + * {@snippet : + * @EventBusSubscriber + * public class MyEventHandler { + * @SubscribeEvent + * private static void onSomeEvent(SomeEvent event) { + * // SomeEvent handler here + * } + * + * @SubscribeEvent + * private static void onAnotherEvent(AnotherEvent event) { + * // AnotherEvent handler here + * } + * } + * } + * + * @see Bus + */ +// @formatter:on +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface EventBusSubscriber { + /** + * Specify targets to load this event subscriber on. Can be used to avoid loading Client specific events on a dedicated server, for example. + * + * @return an array of Dist to load this event subscriber on + */ + Dist[] value() default { Dist.CLIENT, Dist.DEDICATED_SERVER }; + + /** + * Optional value, only necessary if this annotation is not on the same class that has a @Mod annotation. Needed to prevent early classloading of classes not owned by your mod. + * + * @return a modid + */ + String modid() default ""; + + /** + * Specify an alternative bus to listen to + * + * @return the bus you wish to listen to + */ + Bus bus() default Bus.GAME; + + enum Bus { + /** + * The main NeoForge Event Bus, used after the game has started up. + * + *

See {@code NeoForge#EVENT_BUS}

+ */ + GAME, + /** + * The mod-specific Event bus, used during startup. + * + * @see ModContainer#getEventBus() + */ + MOD, + } +} diff --git a/loader/src/main/java/net/neoforged/fml/common/Mod.java b/loader/src/main/java/net/neoforged/fml/common/Mod.java index 4e1988331..b1aa6b6fe 100644 --- a/loader/src/main/java/net/neoforged/fml/common/Mod.java +++ b/loader/src/main/java/net/neoforged/fml/common/Mod.java @@ -9,12 +9,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.util.function.Supplier; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.bus.api.IEventBus; -import net.neoforged.fml.Bindings; -import net.neoforged.fml.ModContainer; -import net.neoforged.fml.javafmlmod.FMLJavaModLoadingContext; /** * This defines a Mod to FML. @@ -33,64 +27,4 @@ * By default, you will have a resource domain that matches the modid. All these uses require that constraints are imposed on the format of the modid. */ String value(); - - /** - * Annotate a class which will be subscribed to an Event Bus at mod construction time. - * Defaults to subscribing the current modid to the {@code NeoForge#EVENT_BUS} - * on both sides. - * - * @see Bus - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.TYPE) - @interface EventBusSubscriber { - /** - * Specify targets to load this event subscriber on. Can be used to avoid loading Client specific events - * on a dedicated server, for example. - * - * @return an array of Dist to load this event subscriber on - */ - Dist[] value() default { Dist.CLIENT, Dist.DEDICATED_SERVER }; - - /** - * Optional value, only necessary if this annotation is not on the same class that has a @Mod annotation. - * Needed to prevent early classloading of classes not owned by your mod. - * - * @return a modid - */ - String modid() default ""; - - /** - * Specify an alternative bus to listen to - * - * @return the bus you wish to listen to - */ - Bus bus() default Bus.FORGE; - - enum Bus { - /** - * The main Forge Event Bus. - * - *

See {@code NeoForge#EVENT_BUS}

- */ - FORGE(Bindings.getForgeBus()), - /** - * The mod specific Event bus. - * - * @see ModContainer#getEventBus() - */ - MOD(() -> FMLJavaModLoadingContext.get().getModEventBus()); - - private final Supplier busSupplier; - - Bus(final Supplier eventBusSupplier) { - this.busSupplier = eventBusSupplier; - } - - @Deprecated(forRemoval = true) - public Supplier bus() { - return busSupplier; - } - } - } } diff --git a/loader/src/main/java/net/neoforged/fml/config/IConfigEvent.java b/loader/src/main/java/net/neoforged/fml/config/IConfigEvent.java index 4d68271f5..c5c6ef41f 100644 --- a/loader/src/main/java/net/neoforged/fml/config/IConfigEvent.java +++ b/loader/src/main/java/net/neoforged/fml/config/IConfigEvent.java @@ -14,7 +14,7 @@ public interface IConfigEvent { record ConfigConfig(Function loading, Function reloading, @Nullable Function unloading) {} - ConfigConfig CONFIGCONFIG = Bindings.getConfigConfiguration().get(); + ConfigConfig CONFIGCONFIG = Bindings.getConfigConfiguration(); static IConfigEvent reloading(ModConfig modConfig) { return CONFIGCONFIG.reloading().apply(modConfig); diff --git a/loader/src/main/java/net/neoforged/fml/javafmlmod/AutomaticEventSubscriber.java b/loader/src/main/java/net/neoforged/fml/javafmlmod/AutomaticEventSubscriber.java index e7948051e..f584d10af 100644 --- a/loader/src/main/java/net/neoforged/fml/javafmlmod/AutomaticEventSubscriber.java +++ b/loader/src/main/java/net/neoforged/fml/javafmlmod/AutomaticEventSubscriber.java @@ -17,6 +17,7 @@ import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.Bindings; import net.neoforged.fml.ModContainer; +import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.Mod; import net.neoforged.fml.loading.FMLEnvironment; import net.neoforged.fml.loading.moddiscovery.ModAnnotation; @@ -26,13 +27,13 @@ import org.objectweb.asm.Type; /** - * Automatic eventbus subscriber - reads {@link Mod.EventBusSubscriber} - * annotations and passes the class instances to the {@link Mod.EventBusSubscriber.Bus} + * Automatic eventbus subscriber - reads {@link EventBusSubscriber} + * annotations and passes the class instances to the {@link EventBusSubscriber.Bus} * defined by the annotation. Defaults to {@code NeoForge#EVENT_BUS} */ public class AutomaticEventSubscriber { private static final Logger LOGGER = LogManager.getLogger(); - private static final Type AUTO_SUBSCRIBER = Type.getType(Mod.EventBusSubscriber.class); + private static final Type AUTO_SUBSCRIBER = Type.getType(EventBusSubscriber.class); private static final Type MOD_TYPE = Type.getType(Mod.class); public static void inject(final ModContainer mod, final ModFileScanData scanData, final ClassLoader loader) { @@ -47,11 +48,11 @@ public static void inject(final ModContainer mod, final ModFileScanData scanData final EnumSet sides = sidesValue.stream().map(eh -> Dist.valueOf(eh.getValue())).collect(Collectors.toCollection(() -> EnumSet.noneOf(Dist.class))); final String modId = (String) ad.annotationData().getOrDefault("modid", modids.getOrDefault(ad.clazz().getClassName(), mod.getModId())); final ModAnnotation.EnumHolder busTargetHolder = (ModAnnotation.EnumHolder) ad.annotationData().getOrDefault("bus", new ModAnnotation.EnumHolder(null, "FORGE")); - final Mod.EventBusSubscriber.Bus busTarget = Mod.EventBusSubscriber.Bus.valueOf(busTargetHolder.getValue()); + final EventBusSubscriber.Bus busTarget = EventBusSubscriber.Bus.valueOf(busTargetHolder.getValue()); if (Objects.equals(mod.getModId(), modId) && sides.contains(FMLEnvironment.dist)) { try { IEventBus bus = switch (busTarget) { - case FORGE -> Bindings.getForgeBus().get(); + case GAME -> Bindings.getGameBus(); case MOD -> mod.getEventBus(); };