1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-08-24 22:42: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.lua.GenericSource;
import dan200.computercraft.api.lua.ILuaAPIFactory;
import dan200.computercraft.api.media.MediaProvider;
import dan200.computercraft.api.media.PrintoutContents;
import dan200.computercraft.api.network.PacketNetwork;
import dan200.computercraft.api.network.wired.WiredElement;
@ -93,11 +92,6 @@ public abstract class AbstractComputerCraftAPI implements ComputerCraftAPIServic
return BundledRedstone.getDefaultOutput(world, pos, side);
}
@Override
public final void registerMediaProvider(MediaProvider provider) {
MediaProviders.register(provider);
}
@Override
public final PacketNetwork getWirelessNetwork(MinecraftServer server) {
return ServerContext.get(server).wirelessNetwork();

View File

@ -4,9 +4,9 @@
package dan200.computercraft.shared.peripheral.diskdrive;
import dan200.computercraft.impl.MediaProviders;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.common.HorizontalContainerBlock;
import dan200.computercraft.shared.platform.PlatformHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand;
@ -50,7 +50,7 @@ public class DiskDriveBlock extends HorizontalContainerBlock {
var disk = player.getItemInHand(hand);
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));
}
return InteractionResult.sidedSuccess(level.isClientSide);

View File

@ -5,7 +5,7 @@
package dan200.computercraft.shared.peripheral.diskdrive;
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.world.item.ItemStack;
import org.jspecify.annotations.Nullable;
@ -23,7 +23,7 @@ record MediaStack(ItemStack stack, @Nullable IMedia media) {
if (stack.isEmpty()) return EMPTY;
var freshStack = stack.copy();
return new MediaStack(freshStack, MediaProviders.get(freshStack));
return new MediaStack(freshStack, PlatformHelper.get().getMedia(freshStack));
}
@Nullable

View File

@ -7,6 +7,7 @@ package dan200.computercraft.shared.platform;
import com.google.gson.JsonObject;
import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.arguments.ArgumentType;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.network.wired.WiredElement;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.config.ConfigFile;
@ -424,4 +425,13 @@ public interface PlatformHelper extends dan200.computercraft.impl.PlatformHelper
default boolean canClickRunClientCommand() {
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.mojang.authlib.GameProfile;
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.peripheral.IPeripheral;
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");
}
@Override
public @Nullable IMedia getMedia(ItemStack stack) {
return null;
}
@Override
public ContainerTransfer.Slotted wrapContainer(Container 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");
}
@Override
public void registerMediaProvider(MediaProvider provider) {
throw new UnsupportedOperationException("Cannot register media providers inside tests");
}
@Override
public String getInstalledVersion() {
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 dan200.computercraft.api.ComputerCraftAPI;
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.shared.details.FluidDetails;
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
@ -41,4 +43,9 @@ public final class ComputerCraftAPIImpl extends AbstractComputerCraftAPI impleme
public DetailRegistry<StorageView<FluidVariant>> getFluidDetailRegistry() {
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.brigadier.arguments.ArgumentType;
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.node.wired.WiredElementLookup;
import dan200.computercraft.api.peripheral.IPeripheral;
@ -317,6 +319,12 @@ public class PlatformHelperImpl implements PlatformHelper {
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>(
ResourceLocation name, Registry<T> registry
) implements RegistryWrappers.RegistryWrapper<T> {

View File

@ -7,6 +7,7 @@ package dan200.computercraft.impl;
import com.google.auto.service.AutoService;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.detail.DetailRegistry;
import dan200.computercraft.api.media.MediaProvider;
import dan200.computercraft.api.network.wired.WiredElement;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.impl.detail.DetailRegistryImpl;
@ -56,4 +57,9 @@ public final class ComputerCraftAPIImpl extends AbstractComputerCraftAPI impleme
public DetailRegistry<FluidStack> getFluidStackDetailRegistry() {
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.brigadier.arguments.ArgumentType;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.network.wired.WiredElement;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.impl.MediaProviders;
import dan200.computercraft.impl.Peripherals;
import dan200.computercraft.shared.Capabilities;
import dan200.computercraft.shared.config.ConfigFile;
@ -348,6 +350,11 @@ public class PlatformHelperImpl implements PlatformHelper {
return false;
}
@Override
public @Nullable IMedia getMedia(ItemStack stack) {
return MediaProviders.get(stack);
}
private record RegistryWrapperImpl<T>(
ResourceLocation name, ForgeRegistry<T> registry
) implements RegistryWrappers.RegistryWrapper<T> {