Add bus cable block.
This commit is contained in:
@@ -2,6 +2,7 @@ package li.cil.oc2;
|
||||
|
||||
public final class Constants {
|
||||
public static final String COMPUTER_BLOCK_NAME = "computer";
|
||||
public static final String BUS_CABLE_BLOCK_NAME = "bus_cable";
|
||||
public static final String REDSTONE_INTERFACE_BLOCK_NAME = "redstone_interface";
|
||||
public static final String SCREEN_BLOCK_NAME = "screen";
|
||||
}
|
||||
|
||||
@@ -4,10 +4,12 @@ import li.cil.ceres.Ceres;
|
||||
import li.cil.oc2.api.API;
|
||||
import li.cil.oc2.client.ClientSetup;
|
||||
import li.cil.oc2.common.CommonSetup;
|
||||
import li.cil.oc2.common.block.BusCableBlock;
|
||||
import li.cil.oc2.common.block.ComputerBlock;
|
||||
import li.cil.oc2.common.block.RedstoneInterfaceBlock;
|
||||
import li.cil.oc2.common.block.ScreenBlock;
|
||||
import li.cil.oc2.common.container.ComputerContainer;
|
||||
import li.cil.oc2.common.tile.BusCableTileEntity;
|
||||
import li.cil.oc2.common.tile.ComputerTileEntity;
|
||||
import li.cil.sedna.devicetree.DeviceTreeRegistry;
|
||||
import net.minecraft.block.Block;
|
||||
@@ -37,16 +39,19 @@ public final class OpenComputers {
|
||||
|
||||
public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, API.MOD_ID);
|
||||
public static final RegistryObject<Block> COMPUTER_BLOCK = BLOCKS.register(Constants.COMPUTER_BLOCK_NAME, ComputerBlock::new);
|
||||
public static final RegistryObject<Block> BUS_CABLE_BLOCK = BLOCKS.register(Constants.BUS_CABLE_BLOCK_NAME, BusCableBlock::new);
|
||||
public static final RegistryObject<Block> REDSTONE_INTERFACE_BLOCK = BLOCKS.register(Constants.REDSTONE_INTERFACE_BLOCK_NAME, RedstoneInterfaceBlock::new);
|
||||
public static final RegistryObject<Block> SCREEN_BLOCK = BLOCKS.register(Constants.SCREEN_BLOCK_NAME, ScreenBlock::new);
|
||||
|
||||
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, API.MOD_ID);
|
||||
public static final RegistryObject<Item> COMPUTER_ITEM = ITEMS.register(Constants.COMPUTER_BLOCK_NAME, () -> new BlockItem(COMPUTER_BLOCK.get(), new Item.Properties().group(ITEM_GROUP)));
|
||||
public static final RegistryObject<Item> BUS_CABLE_ITEM = ITEMS.register(Constants.BUS_CABLE_BLOCK_NAME, () -> new BlockItem(BUS_CABLE_BLOCK.get(), new Item.Properties().group(ITEM_GROUP)));
|
||||
public static final RegistryObject<Item> REDSTONE_INTERFACE_ITEM = ITEMS.register(Constants.REDSTONE_INTERFACE_BLOCK_NAME, () -> new BlockItem(REDSTONE_INTERFACE_BLOCK.get(), new Item.Properties().group(ITEM_GROUP)));
|
||||
public static final RegistryObject<Item> SCREEN_ITEM = ITEMS.register(Constants.SCREEN_BLOCK_NAME, () -> new BlockItem(SCREEN_BLOCK.get(), new Item.Properties().group(ITEM_GROUP)));
|
||||
|
||||
public static final DeferredRegister<TileEntityType<?>> TILES = DeferredRegister.create(ForgeRegistries.TILE_ENTITIES, API.MOD_ID);
|
||||
public static final RegistryObject<TileEntityType<ComputerTileEntity>> COMPUTER_TILE_ENTITY = TILES.register(Constants.COMPUTER_BLOCK_NAME, () -> TileEntityType.Builder.create(ComputerTileEntity::new, COMPUTER_BLOCK.get()).build(null));
|
||||
public static final RegistryObject<TileEntityType<BusCableTileEntity>> BUS_CABLE_TILE_ENTITY = TILES.register(Constants.BUS_CABLE_BLOCK_NAME, () -> TileEntityType.Builder.create(BusCableTileEntity::new, BUS_CABLE_BLOCK.get()).build(null));
|
||||
|
||||
public static final DeferredRegister<ContainerType<?>> CONTAINERS = DeferredRegister.create(ForgeRegistries.CONTAINERS, API.MOD_ID);
|
||||
public static final RegistryObject<ContainerType<ComputerContainer>> COMPUTER_CONTAINER = CONTAINERS.register(Constants.COMPUTER_BLOCK_NAME, () -> IForgeContainerType.create((id, inventory, data) -> {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package li.cil.oc2.common;
|
||||
|
||||
import li.cil.oc2.common.capabilities.DeviceBusElementCapability;
|
||||
import li.cil.oc2.common.device.DeviceMethodParameterTypeAdapters;
|
||||
import li.cil.oc2.common.device.Providers;
|
||||
import li.cil.oc2.common.network.Network;
|
||||
import li.cil.oc2.common.vm.Allocator;
|
||||
import li.cil.oc2.serialization.BlobStorage;
|
||||
|
||||
41
src/main/java/li/cil/oc2/common/block/BusCableBlock.java
Normal file
41
src/main/java/li/cil/oc2/common/block/BusCableBlock.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package li.cil.oc2.common.block;
|
||||
|
||||
import li.cil.oc2.OpenComputers;
|
||||
import li.cil.oc2.common.tile.BusCableTileEntity;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class BusCableBlock extends Block {
|
||||
public BusCableBlock() {
|
||||
super(Properties.create(Material.IRON).sound(SoundType.METAL));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(final BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TileEntity createTileEntity(final BlockState state, final IBlockReader world) {
|
||||
return OpenComputers.BUS_CABLE_TILE_ENTITY.get().create();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void neighborChanged(final BlockState state, final World world, final BlockPos pos, final Block changedBlock, final BlockPos changedBlockPos, final boolean isMoving) {
|
||||
final TileEntity tileEntity = world.getTileEntity(pos);
|
||||
if (tileEntity instanceof BusCableTileEntity) {
|
||||
final BusCableTileEntity busCable = (BusCableTileEntity) tileEntity;
|
||||
busCable.handleNeighborChanged(changedBlockPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package li.cil.oc2.common.bus;
|
||||
|
||||
import li.cil.oc2.api.bus.DeviceBus;
|
||||
import li.cil.oc2.api.bus.DeviceBusElement;
|
||||
import li.cil.oc2.common.ServerScheduler;
|
||||
import li.cil.oc2.common.device.CompoundDevice;
|
||||
import li.cil.oc2.common.device.IdentifiableDeviceImpl;
|
||||
import li.cil.oc2.common.device.Providers;
|
||||
import li.cil.oc2.common.util.NBTTagIds;
|
||||
import li.cil.oc2.common.util.TileEntityUtils;
|
||||
import li.cil.oc2.common.util.WorldUtils;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.INBTSerializable;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class TileEntityDeviceBusElement implements INBTSerializable<CompoundNBT> {
|
||||
private static final String DEVICE_IDS_NBT_TAG_NAME = "deviceIds";
|
||||
private static final String DEVICE_ID_NBT_TAG_NAME = "deviceId";
|
||||
|
||||
private static final int NEIGHBOR_COUNT = 6;
|
||||
|
||||
private final TileEntity tileEntity;
|
||||
|
||||
private final DeviceBusElementImpl busElement = new DeviceBusElementImpl();
|
||||
private final UUID[] deviceIds = new UUID[NEIGHBOR_COUNT];
|
||||
private final IdentifiableDeviceImpl[] devices = new IdentifiableDeviceImpl[NEIGHBOR_COUNT];
|
||||
|
||||
public TileEntityDeviceBusElement(final TileEntity tileEntity) {
|
||||
this.tileEntity = tileEntity;
|
||||
|
||||
for (int i = 0; i < NEIGHBOR_COUNT; i++) {
|
||||
deviceIds[i] = UUID.randomUUID();
|
||||
}
|
||||
}
|
||||
|
||||
public DeviceBusElementImpl getBusElement() {
|
||||
return busElement;
|
||||
}
|
||||
|
||||
public void handleNeighborChanged(final BlockPos pos) {
|
||||
final World world = tileEntity.getWorld();
|
||||
if (world == null || world.isRemote()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final BlockPos toPos = pos.subtract(tileEntity.getPos());
|
||||
final Direction direction = Direction.byLong(toPos.getX(), toPos.getY(), toPos.getZ());
|
||||
if (direction == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int index = direction.getIndex();
|
||||
|
||||
final LazyOptional<CompoundDevice> device = Providers.getDevice(world, pos, direction);
|
||||
final IdentifiableDeviceImpl identifiableDevice;
|
||||
|
||||
if (device.isPresent()) {
|
||||
identifiableDevice = new IdentifiableDeviceImpl(device, deviceIds[index]);
|
||||
device.addListener((ignored) -> handleNeighborChanged(pos));
|
||||
} else {
|
||||
identifiableDevice = null;
|
||||
}
|
||||
|
||||
if (Objects.equals(devices[index], identifiableDevice)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (devices[index] != null) {
|
||||
busElement.removeDevice(devices[index]);
|
||||
}
|
||||
|
||||
devices[index] = identifiableDevice;
|
||||
|
||||
if (devices[index] != null) {
|
||||
busElement.addDevice(devices[index]);
|
||||
}
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
final World world = tileEntity.getWorld();
|
||||
if (world == null || world.isRemote()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ServerScheduler.schedule(world, () -> {
|
||||
if (tileEntity.isRemoved()) return;
|
||||
scanNeighborsForBusElements(tileEntity.getWorld());
|
||||
scanNeighborsForDevices();
|
||||
});
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
busElement.scheduleScan();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT serializeNBT() {
|
||||
final ListNBT deviceIdsNbt = new ListNBT();
|
||||
for (int i = 0; i < NEIGHBOR_COUNT; i++) {
|
||||
final CompoundNBT deviceIdNbt = new CompoundNBT();
|
||||
deviceIdNbt.putUniqueId(DEVICE_ID_NBT_TAG_NAME, deviceIds[i]);
|
||||
deviceIdsNbt.add(deviceIdNbt);
|
||||
}
|
||||
|
||||
final CompoundNBT compound = new CompoundNBT();
|
||||
compound.put(DEVICE_IDS_NBT_TAG_NAME, deviceIdsNbt);
|
||||
return compound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserializeNBT(final CompoundNBT compound) {
|
||||
final ListNBT deviceIdsNbt = compound.getList(DEVICE_IDS_NBT_TAG_NAME, NBTTagIds.TAG_COMPOUND);
|
||||
for (int i = 0; i < Math.min(deviceIdsNbt.size(), NEIGHBOR_COUNT); i++) {
|
||||
final CompoundNBT deviceIdNbt = deviceIdsNbt.getCompound(i);
|
||||
if (deviceIdNbt.hasUniqueId(DEVICE_ID_NBT_TAG_NAME)) {
|
||||
deviceIds[i] = deviceIdNbt.getUniqueId(DEVICE_ID_NBT_TAG_NAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CompoundNBT write(final CompoundNBT compound) {
|
||||
final ListNBT deviceIdsNbt = new ListNBT();
|
||||
for (int i = 0; i < NEIGHBOR_COUNT; i++) {
|
||||
final CompoundNBT deviceIdNbt = new CompoundNBT();
|
||||
deviceIdNbt.putUniqueId(DEVICE_ID_NBT_TAG_NAME, deviceIds[i]);
|
||||
deviceIdsNbt.add(deviceIdNbt);
|
||||
}
|
||||
compound.put(DEVICE_IDS_NBT_TAG_NAME, deviceIdsNbt);
|
||||
|
||||
return compound;
|
||||
}
|
||||
|
||||
private void scanNeighborsForDevices() {
|
||||
for (final Direction direction : Direction.values()) {
|
||||
handleNeighborChanged(tileEntity.getPos().offset(direction));
|
||||
}
|
||||
}
|
||||
|
||||
private void scanNeighborsForBusElements(final World world) {
|
||||
final BlockPos pos = tileEntity.getPos();
|
||||
for (final Direction direction : Direction.values()) {
|
||||
final BlockPos neighborPos = pos.offset(direction);
|
||||
final TileEntity tileEntity = WorldUtils.getTileEntityIfChunkExists(world, neighborPos);
|
||||
if (tileEntity == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final Optional<DeviceBusElement> capability = TileEntityUtils.getInterfaceForSide(tileEntity, DeviceBusElement.class, direction.getOpposite());
|
||||
capability.ifPresent(DeviceBus::scheduleScan);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package li.cil.oc2.common.device;
|
||||
|
||||
import li.cil.oc2.api.device.provider.BlockDeviceQuery;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class BlockDeviceQueryImpl implements BlockDeviceQuery {
|
||||
private final World world;
|
||||
private final BlockPos pos;
|
||||
@Nullable private final Direction side;
|
||||
|
||||
public BlockDeviceQueryImpl(final World world, final BlockPos pos, @Nullable final Direction side) {
|
||||
this.world = world;
|
||||
this.pos = pos;
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getQueryPosition() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Direction getQuerySide() {
|
||||
return side;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package li.cil.oc2.common.device;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
import li.cil.oc2.api.imc.DeviceMethodParameterTypeAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public final class DeviceMethodParameterTypeAdapters {
|
||||
private static final ArrayList<DeviceMethodParameterTypeAdapter> TYPE_ADAPTERS = new ArrayList<>();
|
||||
|
||||
public static void addTypeAdapter(final Class<?> type, final Object typeAdapter) {
|
||||
addTypeAdapter(new DeviceMethodParameterTypeAdapter(type, typeAdapter));
|
||||
}
|
||||
|
||||
public static void addTypeAdapter(final DeviceMethodParameterTypeAdapter value) {
|
||||
TYPE_ADAPTERS.add(value);
|
||||
}
|
||||
|
||||
public static GsonBuilder beginBuildGson() {
|
||||
final GsonBuilder builder = new GsonBuilder()
|
||||
.serializeNulls();
|
||||
|
||||
for (final DeviceMethodParameterTypeAdapter value : TYPE_ADAPTERS) {
|
||||
builder.registerTypeAdapter(value.type, value.typeAdapter);
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -3,16 +3,23 @@ package li.cil.oc2.common.device;
|
||||
import li.cil.oc2.api.device.Device;
|
||||
import li.cil.oc2.api.device.DeviceMethod;
|
||||
import li.cil.oc2.api.device.IdentifiableDevice;
|
||||
import li.cil.oc2.common.util.LazyOptionalUtils;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class IdentifiableDeviceImpl implements IdentifiableDevice {
|
||||
private final Device device;
|
||||
private final LazyOptional<? extends Device> device;
|
||||
private final UUID uuid;
|
||||
|
||||
public IdentifiableDeviceImpl(final Device device, final UUID uuid) {
|
||||
this(LazyOptional.of(() -> device), uuid);
|
||||
}
|
||||
|
||||
public IdentifiableDeviceImpl(final LazyOptional<? extends Device> device, final UUID uuid) {
|
||||
this.device = device;
|
||||
this.uuid = uuid;
|
||||
}
|
||||
@@ -24,12 +31,12 @@ public final class IdentifiableDeviceImpl implements IdentifiableDevice {
|
||||
|
||||
@Override
|
||||
public List<String> getTypeNames() {
|
||||
return device.getTypeNames();
|
||||
return device.map(Device::getTypeNames).orElse(Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DeviceMethod> getMethods() {
|
||||
return device.getMethods();
|
||||
return device.map(Device::getMethods).orElse(Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -38,11 +45,11 @@ public final class IdentifiableDeviceImpl implements IdentifiableDevice {
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final IdentifiableDeviceImpl that = (IdentifiableDeviceImpl) o;
|
||||
return uuid.equals(that.uuid) &&
|
||||
device.equals(that.device);
|
||||
LazyOptionalUtils.equals(device, that.device);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(uuid, device);
|
||||
return Objects.hash(uuid, LazyOptionalUtils.hashCode(device));
|
||||
}
|
||||
}
|
||||
|
||||
66
src/main/java/li/cil/oc2/common/device/Providers.java
Normal file
66
src/main/java/li/cil/oc2/common/device/Providers.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package li.cil.oc2.common.device;
|
||||
|
||||
import li.cil.oc2.api.device.Device;
|
||||
import li.cil.oc2.api.device.provider.DeviceProvider;
|
||||
import li.cil.oc2.api.device.provider.DeviceQuery;
|
||||
import li.cil.oc2.common.device.provider.EnergyStorageDeviceProvider;
|
||||
import li.cil.oc2.common.device.provider.FluidHandlerDeviceProvider;
|
||||
import li.cil.oc2.common.device.provider.ItemHandlerDeviceProvider;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public final class Providers {
|
||||
private static final ArrayList<DeviceProvider> DEVICE_PROVIDERS = new ArrayList<>();
|
||||
|
||||
public static void initialize() {
|
||||
addProvider(new EnergyStorageDeviceProvider());
|
||||
addProvider(new FluidHandlerDeviceProvider());
|
||||
addProvider(new ItemHandlerDeviceProvider());
|
||||
}
|
||||
|
||||
public static void addProvider(final DeviceProvider provider) {
|
||||
if (!DEVICE_PROVIDERS.contains(provider)) {
|
||||
DEVICE_PROVIDERS.add(provider);
|
||||
}
|
||||
}
|
||||
|
||||
public static LazyOptional<CompoundDevice> getDevice(final TileEntity tileEntity, final Direction side) {
|
||||
final World world = tileEntity.getWorld();
|
||||
final BlockPos pos = tileEntity.getPos();
|
||||
|
||||
if (world == null) throw new IllegalArgumentException();
|
||||
|
||||
return getDevice(world, pos, side);
|
||||
}
|
||||
|
||||
public static LazyOptional<CompoundDevice> getDevice(final World world, final BlockPos pos, final Direction side) {
|
||||
return getDevice(new BlockDeviceQueryImpl(world, pos, side));
|
||||
}
|
||||
|
||||
public static LazyOptional<CompoundDevice> getDevice(final DeviceQuery query) {
|
||||
final ArrayList<Device> devices = new ArrayList<>();
|
||||
final ArrayList<LazyOptional<Device>> optionals = new ArrayList<>();
|
||||
for (final DeviceProvider provider : DEVICE_PROVIDERS) {
|
||||
final LazyOptional<Device> optional = provider.getDevice(query);
|
||||
optional.ifPresent((device) -> {
|
||||
devices.add(device);
|
||||
optionals.add(optional);
|
||||
});
|
||||
}
|
||||
|
||||
if (devices.isEmpty()) {
|
||||
return LazyOptional.empty();
|
||||
} else {
|
||||
final LazyOptional<CompoundDevice> compoundOptional = LazyOptional.of(() -> new CompoundDevice(devices));
|
||||
for (final LazyOptional<Device> optional : optionals) {
|
||||
optional.addListener((ignored) -> compoundOptional.invalidate());
|
||||
}
|
||||
return compoundOptional;
|
||||
}
|
||||
}
|
||||
}
|
||||
66
src/main/java/li/cil/oc2/common/tile/AbstractTileEntity.java
Normal file
66
src/main/java/li/cil/oc2/common/tile/AbstractTileEntity.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package li.cil.oc2.common.tile;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
|
||||
public abstract class AbstractTileEntity extends TileEntity {
|
||||
protected final HashMap<Capability<?>, LazyOptional<?>> capabilities = new HashMap<>();
|
||||
|
||||
protected AbstractTileEntity(final TileEntityType<?> tileEntityType) {
|
||||
super(tileEntityType);
|
||||
}
|
||||
|
||||
protected <T> void addCapability(final Capability<T> capability, final T value) {
|
||||
capabilities.put(capability, LazyOptional.of(() -> value));
|
||||
}
|
||||
|
||||
protected void initialize() {
|
||||
}
|
||||
|
||||
protected void dispose() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@NotNull final Capability<T> capability, @Nullable final Direction side) {
|
||||
final LazyOptional<?> optional = capabilities.get(capability);
|
||||
if (optional != null) {
|
||||
return optional.cast();
|
||||
} else {
|
||||
return super.getCapability(capability, side);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkUnloaded() {
|
||||
invalidateCaps();
|
||||
dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void invalidateCaps() {
|
||||
super.invalidateCaps();
|
||||
for (final LazyOptional<?> capability : capabilities.values()) {
|
||||
capability.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
49
src/main/java/li/cil/oc2/common/tile/BusCableTileEntity.java
Normal file
49
src/main/java/li/cil/oc2/common/tile/BusCableTileEntity.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package li.cil.oc2.common.tile;
|
||||
|
||||
import li.cil.oc2.OpenComputers;
|
||||
import li.cil.oc2.common.bus.TileEntityDeviceBusElement;
|
||||
import li.cil.oc2.common.capabilities.Capabilities;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class BusCableTileEntity extends AbstractTileEntity {
|
||||
private static final String BUS_ELEMENT_NBT_TAG_NAME = "busElement";
|
||||
|
||||
private final TileEntityDeviceBusElement busElement;
|
||||
|
||||
public BusCableTileEntity() {
|
||||
super(OpenComputers.BUS_CABLE_TILE_ENTITY.get());
|
||||
|
||||
busElement = new TileEntityDeviceBusElement(this);
|
||||
addCapability(Capabilities.DEVICE_BUS_ELEMENT_CAPABILITY, busElement.getBusElement());
|
||||
}
|
||||
|
||||
public void handleNeighborChanged(final BlockPos pos) {
|
||||
busElement.handleNeighborChanged(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
busElement.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispose() {
|
||||
super.dispose();
|
||||
busElement.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
compound = super.write(compound);
|
||||
compound.put(BUS_ELEMENT_NBT_TAG_NAME, busElement.serializeNBT());
|
||||
return compound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(final CompoundNBT compound) {
|
||||
super.read(compound);
|
||||
busElement.deserializeNBT(compound.getCompound(BUS_ELEMENT_NBT_TAG_NAME));
|
||||
}
|
||||
}
|
||||
25
src/main/java/li/cil/oc2/common/util/LazyOptionalUtils.java
Normal file
25
src/main/java/li/cil/oc2/common/util/LazyOptionalUtils.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package li.cil.oc2.common.util;
|
||||
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class LazyOptionalUtils {
|
||||
public static <T1, T2> boolean equals(final LazyOptional<T1> optionalA, final LazyOptional<T2> optionalB) {
|
||||
if (optionalA.isPresent() != optionalB.isPresent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!optionalA.isPresent()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final T1 valueA = optionalA.orElseThrow(AssertionError::new);
|
||||
final T2 valueB = optionalB.orElseThrow(AssertionError::new);
|
||||
return Objects.equals(valueA, valueB);
|
||||
}
|
||||
|
||||
public static <T> int hashCode(final LazyOptional<T> optional) {
|
||||
return optional.map(Objects::hash).orElse(0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user