From c03fce275e757d97d18630b58e16b2fd46b0f1aa Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sun, 16 Feb 2025 18:33:41 +0000 Subject: [PATCH] Add some abstractions for registering capabilities This is pretty useless right now (not even going to try to use it for Forge), but should be a bit more useful for 1.21. --- .../computercraft/shared/ModRegistry.java | 44 +++++++++++++++++++ .../computercraft/shared/ComputerCraft.java | 42 +++++++----------- 2 files changed, 59 insertions(+), 27 deletions(-) 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 7106355bf..6fb2c8b66 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java @@ -10,6 +10,8 @@ import dan200.computercraft.api.component.ComputerComponents; import dan200.computercraft.api.detail.DetailProvider; import dan200.computercraft.api.detail.VanillaDetailRegistries; import dan200.computercraft.api.media.IMedia; +import dan200.computercraft.api.network.wired.WiredElement; +import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.pocket.PocketUpgradeSerialiser; import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser; import dan200.computercraft.api.upgrades.UpgradeData; @@ -52,6 +54,7 @@ import dan200.computercraft.shared.media.recipes.DiskRecipe; import dan200.computercraft.shared.media.recipes.PrintoutRecipe; import dan200.computercraft.shared.network.container.ComputerContainerData; import dan200.computercraft.shared.network.container.ContainerData; +import dan200.computercraft.shared.peripheral.commandblock.CommandBlockPeripheral; import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveBlock; import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveBlockEntity; import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveMenu; @@ -94,6 +97,7 @@ import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.synchronization.ArgumentTypeInfo; import net.minecraft.commands.synchronization.SingletonArgumentInfo; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.core.cauldron.CauldronInteraction; import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; @@ -112,6 +116,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.NoteBlockInstrument; import net.minecraft.world.level.material.MapColor; import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType; +import org.jspecify.annotations.Nullable; import java.util.Objects; import java.util.function.BiFunction; @@ -497,6 +502,45 @@ public final class ModRegistry { CauldronInteraction.WATER.put(Items.TURTLE_ADVANCED.get(), TurtleItem.CAULDRON_INTERACTION); } + /** + * Register our peripherals. + * + * @param peripherals The object to register our peripheral capability/lookups with. + */ + public static void registerPeripherals(BlockComponent peripherals) { + peripherals.registerForBlockEntity(ModRegistry.BlockEntities.COMPUTER_NORMAL.get(), (b, d) -> b.peripheral()); + peripherals.registerForBlockEntity(ModRegistry.BlockEntities.COMPUTER_ADVANCED.get(), (b, d) -> b.peripheral()); + peripherals.registerForBlockEntity(ModRegistry.BlockEntities.TURTLE_NORMAL.get(), (b, d) -> b.peripheral()); + peripherals.registerForBlockEntity(ModRegistry.BlockEntities.TURTLE_ADVANCED.get(), (b, d) -> b.peripheral()); + peripherals.registerForBlockEntity(ModRegistry.BlockEntities.SPEAKER.get(), (b, d) -> b.peripheral()); + peripherals.registerForBlockEntity(ModRegistry.BlockEntities.PRINTER.get(), (b, d) -> b.peripheral()); + peripherals.registerForBlockEntity(ModRegistry.BlockEntities.DISK_DRIVE.get(), (b, d) -> b.peripheral()); + peripherals.registerForBlockEntity(ModRegistry.BlockEntities.MONITOR_NORMAL.get(), (b, d) -> b.peripheral()); + peripherals.registerForBlockEntity(ModRegistry.BlockEntities.MONITOR_ADVANCED.get(), (b, d) -> b.peripheral()); + peripherals.registerForBlockEntity(ModRegistry.BlockEntities.WIRELESS_MODEM_NORMAL.get(), WirelessModemBlockEntity::getPeripheral); + peripherals.registerForBlockEntity(ModRegistry.BlockEntities.WIRELESS_MODEM_ADVANCED.get(), WirelessModemBlockEntity::getPeripheral); + peripherals.registerForBlockEntity(ModRegistry.BlockEntities.WIRED_MODEM_FULL.get(), WiredModemFullBlockEntity::getPeripheral); + peripherals.registerForBlockEntity(ModRegistry.BlockEntities.CABLE.get(), CableBlockEntity::getPeripheral); + peripherals.registerForBlockEntity(ModRegistry.BlockEntities.REDSTONE_RELAY.get(), (b, d) -> b.peripheral()); + + peripherals.registerForBlockEntity(BlockEntityType.COMMAND_BLOCK, (b, d) -> Config.enableCommandBlock ? new CommandBlockPeripheral(b) : null); + } + + public static void registerWiredElements(BlockComponent wiredElements) { + wiredElements.registerForBlockEntity(ModRegistry.BlockEntities.WIRED_MODEM_FULL.get(), (b, d) -> b.getElement()); + wiredElements.registerForBlockEntity(ModRegistry.BlockEntities.CABLE.get(), CableBlockEntity::getWiredElement); + } + + /** + * An abstraction for registering capabilities/block lookups for blocks and block entities. + * + * @param The type of the component. + * @param The context parameter to the component. + */ + public interface BlockComponent { + void registerForBlockEntity(BlockEntityType blockEntityType, BiFunction provider); + } + private static void addTurtle(CreativeModeTab.Output out, TurtleItem turtle) { out.accept(turtle.create(-1, null, -1, null, null, 0, null)); TurtleUpgrades.getVanillaUpgrades() 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 0980ac3ab..b76b77246 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java +++ b/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java @@ -10,18 +10,13 @@ import dan200.computercraft.api.node.wired.WiredElementLookup; import dan200.computercraft.api.peripheral.PeripheralLookup; import dan200.computercraft.impl.Peripherals; import dan200.computercraft.shared.command.CommandComputerCraft; -import dan200.computercraft.shared.config.Config; import dan200.computercraft.shared.config.ConfigSpec; import dan200.computercraft.shared.details.FluidDetails; import dan200.computercraft.shared.integration.CreateIntegration; import dan200.computercraft.shared.network.NetworkMessages; import dan200.computercraft.shared.network.client.UpgradesLoadedMessage; import dan200.computercraft.shared.network.server.ServerNetworking; -import dan200.computercraft.shared.peripheral.commandblock.CommandBlockPeripheral; import dan200.computercraft.shared.peripheral.generic.methods.InventoryMethods; -import dan200.computercraft.shared.peripheral.modem.wired.CableBlockEntity; -import dan200.computercraft.shared.peripheral.modem.wired.WiredModemFullBlockEntity; -import dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemBlockEntity; import dan200.computercraft.shared.platform.FabricConfigFile; import dan200.computercraft.shared.platform.FabricMessageType; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; @@ -31,6 +26,7 @@ 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.itemgroup.v1.ItemGroupEvents; +import net.fabricmc.fabric.api.lookup.v1.block.BlockApiLookup; import net.fabricmc.fabric.api.loot.v2.LootTableEvents; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; @@ -42,11 +38,14 @@ import net.minecraft.server.packs.PackType; import net.minecraft.server.packs.resources.PreparableReloadListener; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.util.profiling.ProfilerFiller; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.storage.LevelResource; +import org.jspecify.annotations.Nullable; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import java.util.function.BiFunction; public class ComputerCraft { private static final LevelResource SERVERCONFIG = new LevelResource("serverconfig"); @@ -61,28 +60,8 @@ public class ComputerCraft { ModRegistry.register(); ModRegistry.registerMainThread(); - // Register peripherals - PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.COMPUTER_NORMAL.get()); - PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.COMPUTER_ADVANCED.get()); - PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.TURTLE_NORMAL.get()); - PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.TURTLE_ADVANCED.get()); - PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.SPEAKER.get()); - PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.PRINTER.get()); - PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.DISK_DRIVE.get()); - PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.MONITOR_NORMAL.get()); - PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.MONITOR_ADVANCED.get()); - PeripheralLookup.get().registerForBlockEntity( - (b, d) -> Config.enableCommandBlock ? new CommandBlockPeripheral(b) : null, - BlockEntityType.COMMAND_BLOCK - ); - PeripheralLookup.get().registerForBlockEntity(WirelessModemBlockEntity::getPeripheral, ModRegistry.BlockEntities.WIRELESS_MODEM_NORMAL.get()); - PeripheralLookup.get().registerForBlockEntity(WirelessModemBlockEntity::getPeripheral, ModRegistry.BlockEntities.WIRELESS_MODEM_ADVANCED.get()); - PeripheralLookup.get().registerForBlockEntity(WiredModemFullBlockEntity::getPeripheral, ModRegistry.BlockEntities.WIRED_MODEM_FULL.get()); - PeripheralLookup.get().registerForBlockEntity(CableBlockEntity::getPeripheral, ModRegistry.BlockEntities.CABLE.get()); - PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.REDSTONE_RELAY.get()); - - WiredElementLookup.get().registerForBlockEntity((b, d) -> b.getElement(), ModRegistry.BlockEntities.WIRED_MODEM_FULL.get()); - WiredElementLookup.get().registerForBlockEntity(CableBlockEntity::getWiredElement, ModRegistry.BlockEntities.CABLE.get()); + ModRegistry.registerPeripherals(new BlockComponentImpl<>(PeripheralLookup.get())); + ModRegistry.registerWiredElements(new BlockComponentImpl<>(WiredElementLookup.get())); // Register commands CommandRegistrationCallback.EVENT.register((dispatcher, context, environment) -> CommandComputerCraft.register(dispatcher)); @@ -139,4 +118,13 @@ public class ComputerCraft { return listener.reload(preparationBarrier, resourceManager, preparationsProfiler, reloadProfiler, backgroundExecutor, gameExecutor); } } + + private record BlockComponentImpl( + BlockApiLookup lookup + ) implements ModRegistry.BlockComponent { + @Override + public void registerForBlockEntity(BlockEntityType blockEntityType, BiFunction provider) { + lookup.registerForBlockEntity(provider, blockEntityType); + } + } }