mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-12-03 21:08:06 +00:00
Unify the generic peirpheral system a litte
Allows registering arbitrary block lookup functions instead of a platform-specific capability. This is roughly what Fabric did before, but generalised to also take an invalidation callback. This callback is a little nasty - it needs to be a NonNullableConsumer on Forge, but that class isn't available on Fabric. For now, we make the lookup function (and thus the generic peripheral provider) generic on some <T extends Runnable> type, then specialise that on the Forge side. Hopefully we can clean this up when NeoForge reworks capabilities.
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.impl;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.peripheral.generic.ComponentLookup;
|
||||
import dan200.computercraft.shared.peripheral.generic.GenericPeripheralProvider;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* The registry for peripheral providers.
|
||||
* <p>
|
||||
* This lives in the {@code impl} package despite it not being part of the public API, in order to mirror Forge's class.
|
||||
*/
|
||||
public final class Peripherals {
|
||||
private static final GenericPeripheralProvider<Runnable> genericProvider = new GenericPeripheralProvider<>();
|
||||
|
||||
private Peripherals() {
|
||||
}
|
||||
|
||||
public static void addGenericLookup(ComponentLookup<? super Runnable> lookup) {
|
||||
genericProvider.registerLookup(lookup);
|
||||
}
|
||||
|
||||
public static @Nullable IPeripheral getGenericPeripheral(Level level, BlockPos pos, Direction side, @Nullable BlockEntity blockEntity, Runnable invalidate) {
|
||||
return genericProvider.getPeripheral(level, pos, side, blockEntity, invalidate);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ 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.impl.Peripherals;
|
||||
import dan200.computercraft.shared.command.CommandComputerCraft;
|
||||
import dan200.computercraft.shared.config.Config;
|
||||
import dan200.computercraft.shared.config.ConfigSpec;
|
||||
@@ -100,6 +101,8 @@ public class ComputerCraft {
|
||||
FabricDetailRegistries.FLUID_VARIANT.addProvider(FluidDetails::fill);
|
||||
|
||||
ComputerCraftAPI.registerGenericSource(new InventoryMethods());
|
||||
|
||||
Peripherals.addGenericLookup((world, pos, state, blockEntity, side, invalidate) -> InventoryMethods.extractContainer(world, pos, state, blockEntity, side));
|
||||
}
|
||||
|
||||
private record ReloadListener(String name, PreparableReloadListener listener)
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2020 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.shared.peripheral.generic;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.peripheral.generic.methods.InventoryMethods;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public class GenericPeripheralProvider {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(GenericPeripheralProvider.class);
|
||||
|
||||
interface Lookup<T> {
|
||||
@Nullable
|
||||
T find(Level world, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, Direction context);
|
||||
}
|
||||
|
||||
private static final List<Lookup<?>> lookups = List.of(
|
||||
InventoryMethods::extractContainer
|
||||
);
|
||||
|
||||
@Nullable
|
||||
public static IPeripheral getPeripheral(Level level, BlockPos pos, Direction side, @Nullable BlockEntity blockEntity) {
|
||||
if (blockEntity == null) return null;
|
||||
|
||||
var server = level.getServer();
|
||||
if (server == null) {
|
||||
LOG.warn("Fetching peripherals on a non-server level {}.", level, new IllegalStateException("Fetching peripherals on a non-server level."));
|
||||
return null;
|
||||
}
|
||||
|
||||
var builder = new GenericPeripheralBuilder(server);
|
||||
builder.addMethods(blockEntity);
|
||||
|
||||
for (var lookup : lookups) {
|
||||
var contents = lookup.find(level, pos, blockEntity.getBlockState(), blockEntity, side);
|
||||
if (contents != null) builder.addMethods(contents);
|
||||
}
|
||||
|
||||
return builder.toPeripheral(blockEntity, side);
|
||||
}
|
||||
}
|
||||
@@ -14,12 +14,12 @@ import dan200.computercraft.api.network.wired.WiredElement;
|
||||
import dan200.computercraft.api.node.wired.WiredElementLookup;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.peripheral.PeripheralLookup;
|
||||
import dan200.computercraft.impl.Peripherals;
|
||||
import dan200.computercraft.mixin.ArgumentTypeInfosAccessor;
|
||||
import dan200.computercraft.shared.config.ConfigFile;
|
||||
import dan200.computercraft.shared.network.NetworkMessage;
|
||||
import dan200.computercraft.shared.network.client.ClientNetworkContext;
|
||||
import dan200.computercraft.shared.network.container.ContainerData;
|
||||
import dan200.computercraft.shared.peripheral.generic.GenericPeripheralProvider;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import net.fabricmc.fabric.api.event.player.AttackEntityCallback;
|
||||
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
||||
@@ -202,7 +202,7 @@ public class PlatformHelperImpl implements PlatformHelper {
|
||||
|
||||
@Override
|
||||
public ComponentAccess<IPeripheral> createPeripheralAccess(Consumer<Direction> invalidate) {
|
||||
return new PeripheralAccessImpl();
|
||||
return new PeripheralAccessImpl(invalidate);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -476,8 +476,11 @@ public class PlatformHelperImpl implements PlatformHelper {
|
||||
}
|
||||
|
||||
private static final class PeripheralAccessImpl extends ComponentAccessImpl<IPeripheral> {
|
||||
private PeripheralAccessImpl() {
|
||||
private final Runnable[] invalidators = new Runnable[6];
|
||||
|
||||
private PeripheralAccessImpl(Consumer<Direction> invalidate) {
|
||||
super(PeripheralLookup.get());
|
||||
for (var dir : Direction.values()) invalidators[dir.ordinal()] = () -> invalidate.accept(dir);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -487,7 +490,8 @@ public class PlatformHelperImpl implements PlatformHelper {
|
||||
if (result != null) return result;
|
||||
|
||||
var cache = caches[direction.ordinal()];
|
||||
return GenericPeripheralProvider.getPeripheral(level, cache.getPos(), direction.getOpposite(), cache.getBlockEntity());
|
||||
var invalidate = invalidators[direction.ordinal()];
|
||||
return Peripherals.getGenericPeripheral(level, cache.getPos(), direction.getOpposite(), cache.getBlockEntity(), invalidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user