From f0abb83f6e49c2f63ea26792e0063df7674f5712 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sat, 3 Jun 2023 19:01:07 +0100 Subject: [PATCH] Eagerly create upgrade registries for Fabric Instead of creating the upgrade serialiser registries in mod initialisation, we now do it when the API is created. This ensures the registries are available for other mods, irrespective of mod load order. This feels a little sad (we're doing side effects in the static initialiser), but is /fine/ - it's pretty much what other mods do. --- .../api/pocket/PocketUpgradeDataProvider.java | 2 +- .../api/pocket/PocketUpgradeSerialiser.java | 13 ++++++++++++ .../api/turtle/TurtleUpgradeDataProvider.java | 2 +- .../api/turtle/TurtleUpgradeSerialiser.java | 13 ++++++++++++ .../impl/ComputerCraftAPIService.java | 8 ++++++++ .../impl/AbstractComputerCraftAPI.java | 20 ++++++++++++++++++- .../computercraft/impl/PocketUpgrades.java | 2 +- .../computercraft/impl/TurtleUpgrades.java | 2 +- .../computercraft/shared/ModRegistry.java | 4 ++-- .../network/client/UpgradesLoadedMessage.java | 8 ++++---- .../impl/network/wired/NetworkTest.java | 3 +-- .../impl/ComputerCraftAPIImpl.java | 9 +++++++++ .../computercraft/shared/ComputerCraft.java | 5 ----- .../dan200/computercraft/ComputerCraft.java | 6 +++--- 14 files changed, 76 insertions(+), 21 deletions(-) diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeDataProvider.java b/projects/common-api/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeDataProvider.java index 574b4afc6..80250c1da 100644 --- a/projects/common-api/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeDataProvider.java +++ b/projects/common-api/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeDataProvider.java @@ -21,6 +21,6 @@ import java.util.function.Consumer; */ public abstract class PocketUpgradeDataProvider extends UpgradeDataProvider> { public PocketUpgradeDataProvider(PackOutput output) { - super(output, "Pocket Computer Upgrades", "computercraft/pocket_upgrades", PocketUpgradeSerialiser.REGISTRY_ID); + super(output, "Pocket Computer Upgrades", "computercraft/pocket_upgrades", PocketUpgradeSerialiser.registryId()); } } diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeSerialiser.java b/projects/common-api/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeSerialiser.java index 3e4442fa2..41117da91 100644 --- a/projects/common-api/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeSerialiser.java +++ b/projects/common-api/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeSerialiser.java @@ -7,6 +7,7 @@ package dan200.computercraft.api.pocket; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.upgrades.UpgradeBase; import dan200.computercraft.api.upgrades.UpgradeSerialiser; +import dan200.computercraft.impl.ComputerCraftAPIService; import dan200.computercraft.impl.upgrades.SerialiserWithCraftingItem; import dan200.computercraft.impl.upgrades.SimpleSerialiser; import net.minecraft.core.Registry; @@ -31,9 +32,21 @@ import java.util.function.Function; public interface PocketUpgradeSerialiser extends UpgradeSerialiser { /** * The ID for the associated registry. + * + * @deprecated Use {@link #registryId()} instead. */ + @Deprecated(forRemoval = true) ResourceKey>> REGISTRY_ID = ResourceKey.createRegistryKey(new ResourceLocation(ComputerCraftAPI.MOD_ID, "pocket_upgrade_serialiser")); + /** + * The ID for the associated registry. + * + * @return The registry key. + */ + static ResourceKey>> registryId() { + return ComputerCraftAPIService.get().pocketUpgradeRegistryId(); + } + /** * Create an upgrade serialiser for a simple upgrade. This is similar to a {@link SimpleCraftingRecipeSerializer}, * but for upgrades. diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeDataProvider.java b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeDataProvider.java index 55a4d572b..7aef277d6 100644 --- a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeDataProvider.java +++ b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeDataProvider.java @@ -33,7 +33,7 @@ public abstract class TurtleUpgradeDataProvider extends UpgradeDataProvider extends UpgradeSerialiser { /** * The ID for the associated registry. + * + * @deprecated Use {@link #registryId()} instead. */ + @Deprecated(forRemoval = true) ResourceKey>> REGISTRY_ID = ResourceKey.createRegistryKey(new ResourceLocation(ComputerCraftAPI.MOD_ID, "turtle_upgrade_serialiser")); + /** + * The ID for the associated registry. + * + * @return The registry key. + */ + static ResourceKey>> registryId() { + return ComputerCraftAPIService.get().turtleUpgradeRegistryId(); + } + /** * Create an upgrade serialiser for a simple upgrade. This is similar to a {@link SimpleCraftingRecipeSerializer}, * but for upgrades. diff --git a/projects/common-api/src/main/java/dan200/computercraft/impl/ComputerCraftAPIService.java b/projects/common-api/src/main/java/dan200/computercraft/impl/ComputerCraftAPIService.java index a1da780e6..b45a8596a 100644 --- a/projects/common-api/src/main/java/dan200/computercraft/impl/ComputerCraftAPIService.java +++ b/projects/common-api/src/main/java/dan200/computercraft/impl/ComputerCraftAPIService.java @@ -15,10 +15,14 @@ import dan200.computercraft.api.media.MediaProvider; import dan200.computercraft.api.network.PacketNetwork; import dan200.computercraft.api.network.wired.WiredElement; import dan200.computercraft.api.network.wired.WiredNode; +import dan200.computercraft.api.pocket.PocketUpgradeSerialiser; import dan200.computercraft.api.redstone.BundledRedstoneProvider; import dan200.computercraft.api.turtle.TurtleRefuelHandler; +import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; @@ -63,6 +67,10 @@ public interface ComputerCraftAPIService { void registerRefuelHandler(TurtleRefuelHandler handler); + ResourceKey>> turtleUpgradeRegistryId(); + + ResourceKey>> pocketUpgradeRegistryId(); + DetailRegistry getItemStackDetailRegistry(); DetailRegistry getBlockInWorldDetailRegistry(); diff --git a/projects/common/src/main/java/dan200/computercraft/impl/AbstractComputerCraftAPI.java b/projects/common/src/main/java/dan200/computercraft/impl/AbstractComputerCraftAPI.java index 32384cee0..45e4ed707 100644 --- a/projects/common/src/main/java/dan200/computercraft/impl/AbstractComputerCraftAPI.java +++ b/projects/common/src/main/java/dan200/computercraft/impl/AbstractComputerCraftAPI.java @@ -4,6 +4,7 @@ package dan200.computercraft.impl; +import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.detail.BlockReference; import dan200.computercraft.api.detail.DetailRegistry; import dan200.computercraft.api.filesystem.Mount; @@ -14,8 +15,10 @@ import dan200.computercraft.api.media.MediaProvider; import dan200.computercraft.api.network.PacketNetwork; import dan200.computercraft.api.network.wired.WiredElement; import dan200.computercraft.api.network.wired.WiredNode; +import dan200.computercraft.api.pocket.PocketUpgradeSerialiser; import dan200.computercraft.api.redstone.BundledRedstoneProvider; import dan200.computercraft.api.turtle.TurtleRefuelHandler; +import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser; import dan200.computercraft.core.apis.ApiFactories; import dan200.computercraft.core.asm.GenericMethod; import dan200.computercraft.core.filesystem.WritableFileMount; @@ -27,6 +30,8 @@ import dan200.computercraft.shared.details.BlockDetails; import dan200.computercraft.shared.details.ItemDetails; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.world.item.ItemStack; @@ -41,6 +46,9 @@ public abstract class AbstractComputerCraftAPI implements ComputerCraftAPIServic private final DetailRegistry itemStackDetails = new DetailRegistryImpl<>(ItemDetails::fillBasic); private final DetailRegistry blockDetails = new DetailRegistryImpl<>(BlockDetails::fillBasic); + protected static final ResourceKey>> turtleUpgradeRegistryId = ResourceKey.createRegistryKey(new ResourceLocation(ComputerCraftAPI.MOD_ID, "turtle_upgrade_serialiser")); + protected static final ResourceKey>> pocketUpgradeRegistryId = ResourceKey.createRegistryKey(new ResourceLocation(ComputerCraftAPI.MOD_ID, "pocket_upgrade_serialiser")); + public static @Nullable InputStream getResourceFile(MinecraftServer server, String domain, String subPath) { var manager = server.getResourceManager(); var resource = manager.getResource(new ResourceLocation(domain, subPath)).orElse(null); @@ -105,10 +113,20 @@ public abstract class AbstractComputerCraftAPI implements ComputerCraftAPIServic } @Override - public void registerRefuelHandler(TurtleRefuelHandler handler) { + public final void registerRefuelHandler(TurtleRefuelHandler handler) { TurtleRefuelHandlers.register(handler); } + @Override + public final ResourceKey>> turtleUpgradeRegistryId() { + return turtleUpgradeRegistryId; + } + + @Override + public final ResourceKey>> pocketUpgradeRegistryId() { + return pocketUpgradeRegistryId; + } + @Override public final DetailRegistry getItemStackDetailRegistry() { return itemStackDetails; diff --git a/projects/common/src/main/java/dan200/computercraft/impl/PocketUpgrades.java b/projects/common/src/main/java/dan200/computercraft/impl/PocketUpgrades.java index ac702d058..feaf30182 100644 --- a/projects/common/src/main/java/dan200/computercraft/impl/PocketUpgrades.java +++ b/projects/common/src/main/java/dan200/computercraft/impl/PocketUpgrades.java @@ -12,7 +12,7 @@ import java.util.stream.Stream; public final class PocketUpgrades { private static final UpgradeManager, IPocketUpgrade> registry = new UpgradeManager<>( - "pocket computer upgrade", "computercraft/pocket_upgrades", PocketUpgradeSerialiser.REGISTRY_ID + "pocket computer upgrade", "computercraft/pocket_upgrades", PocketUpgradeSerialiser.registryId() ); private PocketUpgrades() { diff --git a/projects/common/src/main/java/dan200/computercraft/impl/TurtleUpgrades.java b/projects/common/src/main/java/dan200/computercraft/impl/TurtleUpgrades.java index b377d89b6..78c91f623 100644 --- a/projects/common/src/main/java/dan200/computercraft/impl/TurtleUpgrades.java +++ b/projects/common/src/main/java/dan200/computercraft/impl/TurtleUpgrades.java @@ -12,7 +12,7 @@ import java.util.stream.Stream; public final class TurtleUpgrades { private static final UpgradeManager, ITurtleUpgrade> registry = new UpgradeManager<>( - "turtle upgrade", "computercraft/turtle_upgrades", TurtleUpgradeSerialiser.REGISTRY_ID + "turtle upgrade", "computercraft/turtle_upgrades", TurtleUpgradeSerialiser.registryId() ); private TurtleUpgrades() { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java b/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java index 339769f9a..13ea6d0a6 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java @@ -255,7 +255,7 @@ public final class ModRegistry { } public static class TurtleSerialisers { - static final RegistrationHelper> REGISTRY = PlatformHelper.get().createRegistrationHelper(TurtleUpgradeSerialiser.REGISTRY_ID); + static final RegistrationHelper> REGISTRY = PlatformHelper.get().createRegistrationHelper(TurtleUpgradeSerialiser.registryId()); public static final RegistryEntry> SPEAKER = REGISTRY.register("speaker", () -> TurtleUpgradeSerialiser.simpleWithCustomItem(TurtleSpeaker::new)); @@ -270,7 +270,7 @@ public final class ModRegistry { } public static class PocketUpgradeSerialisers { - static final RegistrationHelper> REGISTRY = PlatformHelper.get().createRegistrationHelper(PocketUpgradeSerialiser.REGISTRY_ID); + static final RegistrationHelper> REGISTRY = PlatformHelper.get().createRegistrationHelper(PocketUpgradeSerialiser.registryId()); public static final RegistryEntry> SPEAKER = REGISTRY.register("speaker", () -> PocketUpgradeSerialiser.simpleWithCustomItem(PocketSpeaker::new)); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/network/client/UpgradesLoadedMessage.java b/projects/common/src/main/java/dan200/computercraft/shared/network/client/UpgradesLoadedMessage.java index 54446514b..61371e256 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/network/client/UpgradesLoadedMessage.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/network/client/UpgradesLoadedMessage.java @@ -37,8 +37,8 @@ public class UpgradesLoadedMessage implements NetworkMessage, T extends UpgradeBase> Map> fromBytes( @@ -66,8 +66,8 @@ public class UpgradesLoadedMessage implements NetworkMessage, T extends UpgradeBase> void toBytes( diff --git a/projects/common/src/test/java/dan200/computercraft/impl/network/wired/NetworkTest.java b/projects/common/src/test/java/dan200/computercraft/impl/network/wired/NetworkTest.java index 822ceb5ec..1a7d01907 100644 --- a/projects/common/src/test/java/dan200/computercraft/impl/network/wired/NetworkTest.java +++ b/projects/common/src/test/java/dan200/computercraft/impl/network/wired/NetworkTest.java @@ -6,7 +6,6 @@ package dan200.computercraft.impl.network.wired; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.network.wired.WiredElement; import dan200.computercraft.api.network.wired.WiredNetwork; import dan200.computercraft.api.network.wired.WiredNetworkChange; @@ -308,7 +307,7 @@ public class NetworkTest { this.world = world; this.position = position; this.id = id; - this.node = ComputerCraftAPI.createWiredNodeForElement(this); + this.node = new WiredNodeImpl(this); this.addPeripheral(id); } diff --git a/projects/fabric/src/main/java/dan200/computercraft/impl/ComputerCraftAPIImpl.java b/projects/fabric/src/main/java/dan200/computercraft/impl/ComputerCraftAPIImpl.java index 65e62f0c8..14073805b 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/impl/ComputerCraftAPIImpl.java +++ b/projects/fabric/src/main/java/dan200/computercraft/impl/ComputerCraftAPIImpl.java @@ -9,6 +9,7 @@ import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.detail.DetailRegistry; import dan200.computercraft.impl.detail.DetailRegistryImpl; import dan200.computercraft.shared.details.FluidDetails; +import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; import net.fabricmc.fabric.api.transfer.v1.storage.StorageView; import net.fabricmc.loader.api.FabricLoader; @@ -19,6 +20,14 @@ import javax.annotation.Nullable; public final class ComputerCraftAPIImpl extends AbstractComputerCraftAPI implements ComputerCraftAPIFabricService { private final DetailRegistry> fluidDetails = new DetailRegistryImpl<>(FluidDetails::fillBasic); + static { + // This We create the registries here (rather than in the mod initialiser) to guarantee that they're available + // when people come to register upgrade serialisers. + // This is a little nasty (side effects in static constructors and all that!), but seems to be the easiest way. + FabricRegistryBuilder.createSimple(turtleUpgradeRegistryId).buildAndRegister(); + FabricRegistryBuilder.createSimple(pocketUpgradeRegistryId).buildAndRegister(); + } + private @Nullable String version; @Override diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java b/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java index 28d25a2ea..d4587a7a1 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java +++ b/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java @@ -8,8 +8,6 @@ import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.detail.FabricDetailRegistries; import dan200.computercraft.api.node.wired.WiredElementLookup; import dan200.computercraft.api.peripheral.PeripheralLookup; -import dan200.computercraft.api.pocket.PocketUpgradeSerialiser; -import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser; import dan200.computercraft.shared.command.CommandComputerCraft; import dan200.computercraft.shared.config.Config; import dan200.computercraft.shared.config.ConfigSpec; @@ -28,7 +26,6 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents; import net.fabricmc.fabric.api.event.player.UseBlockCallback; -import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; import net.fabricmc.fabric.api.loot.v2.LootTableEvents; import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; @@ -50,8 +47,6 @@ public class ComputerCraft { public static void init() { NetworkHandler.init(); - FabricRegistryBuilder.createSimple(TurtleUpgradeSerialiser.REGISTRY_ID).buildAndRegister(); - FabricRegistryBuilder.createSimple(PocketUpgradeSerialiser.REGISTRY_ID).buildAndRegister(); ModRegistry.register(); ModRegistry.registerMainThread(); ModRegistry.registerCreativeTab(FabricItemGroup.builder(new ResourceLocation(ComputerCraftAPI.MOD_ID, "tab"))).build(); diff --git a/projects/forge/src/main/java/dan200/computercraft/ComputerCraft.java b/projects/forge/src/main/java/dan200/computercraft/ComputerCraft.java index 8b3f27f60..fded03ddb 100644 --- a/projects/forge/src/main/java/dan200/computercraft/ComputerCraft.java +++ b/projects/forge/src/main/java/dan200/computercraft/ComputerCraft.java @@ -13,11 +13,11 @@ import dan200.computercraft.api.pocket.PocketUpgradeSerialiser; import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser; import dan200.computercraft.shared.ModRegistry; import dan200.computercraft.shared.config.ConfigSpec; -import dan200.computercraft.shared.platform.ForgeConfigFile; import dan200.computercraft.shared.details.FluidData; import dan200.computercraft.shared.peripheral.generic.methods.EnergyMethods; import dan200.computercraft.shared.peripheral.generic.methods.FluidMethods; import dan200.computercraft.shared.peripheral.generic.methods.InventoryMethods; +import dan200.computercraft.shared.platform.ForgeConfigFile; import dan200.computercraft.shared.platform.NetworkHandler; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.common.capabilities.ForgeCapabilities; @@ -47,11 +47,11 @@ public final class ComputerCraft { @SubscribeEvent public static void registerRegistries(NewRegistryEvent event) { event.create(new RegistryBuilder>() - .setName(TurtleUpgradeSerialiser.REGISTRY_ID.location()) + .setName(TurtleUpgradeSerialiser.registryId().location()) .disableSaving().disableSync()); event.create(new RegistryBuilder>() - .setName(PocketUpgradeSerialiser.REGISTRY_ID.location()) + .setName(PocketUpgradeSerialiser.registryId().location()) .disableSaving().disableSync()); }