1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-08-28 08:12:18 +00:00

Use Fabric's Item Lookup for registering media providers

We'll switch to capabilities on the (Neo)Forge side for 1.21, when the
capability system is less painful, and then fully deprecate in 1.21.4.
This commit is contained in:
Jonathan Coates 2025-02-16 19:49:47 +00:00
parent c03fce275e
commit 01fe949b3e
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
11 changed files with 86 additions and 10 deletions

View File

@ -11,7 +11,6 @@ import dan200.computercraft.api.filesystem.Mount;
import dan200.computercraft.api.filesystem.WritableMount; import dan200.computercraft.api.filesystem.WritableMount;
import dan200.computercraft.api.lua.GenericSource; import dan200.computercraft.api.lua.GenericSource;
import dan200.computercraft.api.lua.ILuaAPIFactory; import dan200.computercraft.api.lua.ILuaAPIFactory;
import dan200.computercraft.api.media.MediaProvider;
import dan200.computercraft.api.media.PrintoutContents; import dan200.computercraft.api.media.PrintoutContents;
import dan200.computercraft.api.network.PacketNetwork; import dan200.computercraft.api.network.PacketNetwork;
import dan200.computercraft.api.network.wired.WiredElement; import dan200.computercraft.api.network.wired.WiredElement;
@ -93,11 +92,6 @@ public abstract class AbstractComputerCraftAPI implements ComputerCraftAPIServic
return BundledRedstone.getDefaultOutput(world, pos, side); return BundledRedstone.getDefaultOutput(world, pos, side);
} }
@Override
public final void registerMediaProvider(MediaProvider provider) {
MediaProviders.register(provider);
}
@Override @Override
public final PacketNetwork getWirelessNetwork(MinecraftServer server) { public final PacketNetwork getWirelessNetwork(MinecraftServer server) {
return ServerContext.get(server).wirelessNetwork(); return ServerContext.get(server).wirelessNetwork();

View File

@ -4,9 +4,9 @@
package dan200.computercraft.shared.peripheral.diskdrive; package dan200.computercraft.shared.peripheral.diskdrive;
import dan200.computercraft.impl.MediaProviders;
import dan200.computercraft.shared.ModRegistry; import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.common.HorizontalContainerBlock; import dan200.computercraft.shared.common.HorizontalContainerBlock;
import dan200.computercraft.shared.platform.PlatformHelper;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
@ -50,7 +50,7 @@ public class DiskDriveBlock extends HorizontalContainerBlock {
var disk = player.getItemInHand(hand); var disk = player.getItemInHand(hand);
if (disk.isEmpty()) return InteractionResult.PASS; if (disk.isEmpty()) return InteractionResult.PASS;
if (!level.isClientSide && drive.getDiskStack().isEmpty() && MediaProviders.get(disk) != null) { if (!level.isClientSide && drive.getDiskStack().isEmpty() && PlatformHelper.get().getMedia(disk) != null) {
drive.setDiskStack(disk.split(1)); drive.setDiskStack(disk.split(1));
} }
return InteractionResult.sidedSuccess(level.isClientSide); return InteractionResult.sidedSuccess(level.isClientSide);

View File

@ -5,7 +5,7 @@
package dan200.computercraft.shared.peripheral.diskdrive; package dan200.computercraft.shared.peripheral.diskdrive;
import dan200.computercraft.api.media.IMedia; import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.impl.MediaProviders; import dan200.computercraft.shared.platform.PlatformHelper;
import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import org.jspecify.annotations.Nullable; import org.jspecify.annotations.Nullable;
@ -23,7 +23,7 @@ record MediaStack(ItemStack stack, @Nullable IMedia media) {
if (stack.isEmpty()) return EMPTY; if (stack.isEmpty()) return EMPTY;
var freshStack = stack.copy(); var freshStack = stack.copy();
return new MediaStack(freshStack, MediaProviders.get(freshStack)); return new MediaStack(freshStack, PlatformHelper.get().getMedia(freshStack));
} }
@Nullable @Nullable

View File

@ -7,6 +7,7 @@ package dan200.computercraft.shared.platform;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.ArgumentType;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.network.wired.WiredElement; import dan200.computercraft.api.network.wired.WiredElement;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.config.ConfigFile; import dan200.computercraft.shared.config.ConfigFile;
@ -424,4 +425,13 @@ public interface PlatformHelper extends dan200.computercraft.impl.PlatformHelper
default boolean canClickRunClientCommand() { default boolean canClickRunClientCommand() {
return true; return true;
} }
/**
* Find a {@link IMedia} instance for an item stack.
*
* @param stack The stack to look up the media for.
* @return The media instance, or {@code null} if not found.
*/
@Nullable
IMedia getMedia(ItemStack stack);
} }

View File

@ -8,6 +8,8 @@ import com.google.auto.service.AutoService;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.ArgumentType;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.media.MediaProvider;
import dan200.computercraft.api.network.wired.WiredElement; import dan200.computercraft.api.network.wired.WiredElement;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.impl.AbstractComputerCraftAPI; import dan200.computercraft.impl.AbstractComputerCraftAPI;
@ -227,6 +229,11 @@ public class TestPlatformHelper extends AbstractComputerCraftAPI implements Plat
throw new UnsupportedOperationException("Cannot interact with the world inside tests"); throw new UnsupportedOperationException("Cannot interact with the world inside tests");
} }
@Override
public @Nullable IMedia getMedia(ItemStack stack) {
return null;
}
@Override @Override
public ContainerTransfer.Slotted wrapContainer(Container container) { public ContainerTransfer.Slotted wrapContainer(Container container) {
throw new UnsupportedOperationException("Cannot wrap container"); throw new UnsupportedOperationException("Cannot wrap container");
@ -248,6 +255,11 @@ public class TestPlatformHelper extends AbstractComputerCraftAPI implements Plat
throw new UnsupportedOperationException("Cannot interact with the world inside tests"); throw new UnsupportedOperationException("Cannot interact with the world inside tests");
} }
@Override
public void registerMediaProvider(MediaProvider provider) {
throw new UnsupportedOperationException("Cannot register media providers inside tests");
}
@Override @Override
public String getInstalledVersion() { public String getInstalledVersion() {
return "1.0"; return "1.0";

View File

@ -0,0 +1,32 @@
// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package dan200.computercraft.api.media;
import dan200.computercraft.api.ComputerCraftAPI;
import net.fabricmc.fabric.api.lookup.v1.item.ItemApiLookup;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import org.jspecify.annotations.Nullable;
/**
* {@linkplain ItemApiLookup Item API lookup} for {@link IMedia}.
* <p>
* The returned {@link IMedia} instance should be a singleton, and not reference the passed {@link ItemStack}.
* <p>
* Registering a {@link MediaProvider} via {@link ComputerCraftAPI#registerMediaProvider(MediaProvider)} is equivalent
* to registering a {@linkplain ItemApiLookup#registerFallback(ItemApiLookup.ItemApiProvider) fallback provider}.
*/
public final class MediaLookup {
public static final ResourceLocation ID = new ResourceLocation(ComputerCraftAPI.MOD_ID, "media");
private static final ItemApiLookup<IMedia, @Nullable Void> lookup = ItemApiLookup.get(ID, IMedia.class, Void.class);
private MediaLookup() {
}
public static ItemApiLookup<IMedia, @Nullable Void> get() {
return lookup;
}
}

View File

@ -7,6 +7,8 @@ package dan200.computercraft.impl;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.detail.DetailRegistry; import dan200.computercraft.api.detail.DetailRegistry;
import dan200.computercraft.api.media.MediaLookup;
import dan200.computercraft.api.media.MediaProvider;
import dan200.computercraft.impl.detail.DetailRegistryImpl; import dan200.computercraft.impl.detail.DetailRegistryImpl;
import dan200.computercraft.shared.details.FluidDetails; import dan200.computercraft.shared.details.FluidDetails;
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
@ -41,4 +43,9 @@ public final class ComputerCraftAPIImpl extends AbstractComputerCraftAPI impleme
public DetailRegistry<StorageView<FluidVariant>> getFluidDetailRegistry() { public DetailRegistry<StorageView<FluidVariant>> getFluidDetailRegistry() {
return fluidDetails; return fluidDetails;
} }
@Override
public void registerMediaProvider(MediaProvider provider) {
MediaLookup.get().registerFallback((stack, ctx) -> provider.getMedia(stack));
}
} }

View File

@ -10,6 +10,8 @@ import com.google.gson.JsonObject;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.ArgumentType;
import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.media.MediaLookup;
import dan200.computercraft.api.network.wired.WiredElement; import dan200.computercraft.api.network.wired.WiredElement;
import dan200.computercraft.api.node.wired.WiredElementLookup; import dan200.computercraft.api.node.wired.WiredElementLookup;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
@ -317,6 +319,12 @@ public class PlatformHelperImpl implements PlatformHelper {
return new UseOnResult.Continue(true, true); return new UseOnResult.Continue(true, true);
} }
@Override
@SuppressWarnings("NullAway") // NullAway doesn't like the null here.
public @Nullable IMedia getMedia(ItemStack stack) {
return MediaLookup.get().find(stack, null);
}
private record RegistryWrapperImpl<T>( private record RegistryWrapperImpl<T>(
ResourceLocation name, Registry<T> registry ResourceLocation name, Registry<T> registry
) implements RegistryWrappers.RegistryWrapper<T> { ) implements RegistryWrappers.RegistryWrapper<T> {

View File

@ -7,6 +7,7 @@ package dan200.computercraft.impl;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.detail.DetailRegistry; import dan200.computercraft.api.detail.DetailRegistry;
import dan200.computercraft.api.media.MediaProvider;
import dan200.computercraft.api.network.wired.WiredElement; import dan200.computercraft.api.network.wired.WiredElement;
import dan200.computercraft.api.peripheral.IPeripheralProvider; import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.impl.detail.DetailRegistryImpl; import dan200.computercraft.impl.detail.DetailRegistryImpl;
@ -56,4 +57,9 @@ public final class ComputerCraftAPIImpl extends AbstractComputerCraftAPI impleme
public DetailRegistry<FluidStack> getFluidStackDetailRegistry() { public DetailRegistry<FluidStack> getFluidStackDetailRegistry() {
return fluidStackDetails; return fluidStackDetails;
} }
@Override
public void registerMediaProvider(MediaProvider provider) {
MediaProviders.register(provider);
}
} }

View File

@ -10,8 +10,10 @@ import com.google.gson.JsonObject;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.ArgumentType;
import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.network.wired.WiredElement; import dan200.computercraft.api.network.wired.WiredElement;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.impl.MediaProviders;
import dan200.computercraft.impl.Peripherals; import dan200.computercraft.impl.Peripherals;
import dan200.computercraft.shared.Capabilities; import dan200.computercraft.shared.Capabilities;
import dan200.computercraft.shared.config.ConfigFile; import dan200.computercraft.shared.config.ConfigFile;
@ -348,6 +350,11 @@ public class PlatformHelperImpl implements PlatformHelper {
return false; return false;
} }
@Override
public @Nullable IMedia getMedia(ItemStack stack) {
return MediaProviders.get(stack);
}
private record RegistryWrapperImpl<T>( private record RegistryWrapperImpl<T>(
ResourceLocation name, ForgeRegistry<T> registry ResourceLocation name, ForgeRegistry<T> registry
) implements RegistryWrappers.RegistryWrapper<T> { ) implements RegistryWrappers.RegistryWrapper<T> {