Split up providers by context/query type after all.
Added logic to allow item devices to store data to their stack and load it back when first initialized.
This commit is contained in:
9
src/main/java/li/cil/oc2/api/bus/device/ItemDevice.java
Normal file
9
src/main/java/li/cil/oc2/api/bus/device/ItemDevice.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package li.cil.oc2.api.bus.device;
|
||||
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
|
||||
public interface ItemDevice extends Device {
|
||||
void exportToItemStack(CompoundNBT nbt);
|
||||
|
||||
void importFromItemStack(CompoundNBT nbt);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package li.cil.oc2.api.bus.device.provider;
|
||||
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.registries.IForgeRegistryEntry;
|
||||
|
||||
/**
|
||||
* This is used to query for devices given a block face.
|
||||
* <p>
|
||||
* Implementations <em>may</em> return various device types depending on the query.
|
||||
* <p>
|
||||
* For identical queries and world state, implementations <em>should</em> return the same device.
|
||||
* Failing that, implementations <em>should</em> return instances that are equal to each other
|
||||
* when compared using {@link Object#equals(Object)} and have equal {@link Object#hashCode()}s.
|
||||
* <p>
|
||||
* This allows avoiding unnecessary re-initialization of devices that have not changed since a
|
||||
* previous scan.
|
||||
* <p>
|
||||
* This is also required to avoid device duplication when a device is connected to a
|
||||
* {@link li.cil.oc2.api.bus.DeviceBus} more than once. An example where this can occur are
|
||||
* blocks that expose the same device on all sides having connected cabling adjacent to more
|
||||
* than one face.
|
||||
* <p>
|
||||
* Providers can be registered via the provider registries, much like blocks and items
|
||||
* are registered. For example:
|
||||
* <pre>
|
||||
* class YourModInitialization {
|
||||
* static DeferredRegister<BlockDeviceProvider> BLOCK_DEVICE_PROVIDERS = DeferredRegister.create(BlockDeviceProvider.class, "your_mod_id");
|
||||
*
|
||||
* static void initialize() {
|
||||
* BLOCK_DEVICE_PROVIDERS.register("your_block_device_name", YourBlockDeviceProvider::new);
|
||||
*
|
||||
* BLOCK_DEVICE_PROVIDERS.register(FMLJavaModLoadingContext.get().getModEventBus());
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see li.cil.oc2.api.bus.device.rpc.RPCDevice
|
||||
* @see li.cil.oc2.api.bus.device.object.ObjectDevice
|
||||
* @see li.cil.oc2.api.bus.device.vm.VMDevice
|
||||
* @see BlockDeviceQuery
|
||||
*/
|
||||
public interface BlockDeviceProvider extends IForgeRegistryEntry<BlockDeviceProvider> {
|
||||
/**
|
||||
* Get a device for the specified query.
|
||||
*
|
||||
* @param query the query describing the object to get a {@link Device} for.
|
||||
* @return a device for the specified query, if available.
|
||||
*/
|
||||
LazyOptional<Device> getDevice(BlockDeviceQuery query);
|
||||
}
|
||||
@@ -8,8 +8,10 @@ import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Device query for a block in the world.
|
||||
*
|
||||
* @see BlockDeviceProvider
|
||||
*/
|
||||
public interface BlockDeviceQuery extends DeviceQuery {
|
||||
public interface BlockDeviceQuery {
|
||||
/**
|
||||
* The world containing the block this query is performed for.
|
||||
*
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
package li.cil.oc2.api.bus.device.provider;
|
||||
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.object.ObjectDevice;
|
||||
import li.cil.oc2.api.bus.device.rpc.RPCDevice;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.registries.IForgeRegistryEntry;
|
||||
|
||||
/**
|
||||
* Allows querying for devices given some context.
|
||||
* <p>
|
||||
* See the specializations of {@link DeviceQuery} for possible queries.
|
||||
* <ul>
|
||||
* <li>Implementations <em>may</em> handle multiple query types and return various device
|
||||
* types depending on the query.</li>
|
||||
* <li>
|
||||
* Implementations <em>should</em> return the same device for the same query.
|
||||
* <p>
|
||||
* Failing that, implementations <em>should</em> return instances that are equal to each
|
||||
* other when compared using {@link Object#equals(Object)} and have equal {@link Object#hashCode()}s.
|
||||
* <p>
|
||||
* This is required to avoid device duplication when a device is connected to a bus more
|
||||
* than once (e.g. for blocks when connected cables are adjacent to multiple faces of the
|
||||
* block).
|
||||
* </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Providers can be registered via the device provider registry, much like blocks and items
|
||||
* are registered. For example:
|
||||
* <pre>
|
||||
* class YourModInitialization {
|
||||
* static DeferredRegister<DeviceProvider> PROVIDERS = DeferredRegister.create(DeviceProvider.class, "your_mod_id");
|
||||
*
|
||||
* static void initialize() {
|
||||
* PROVIDERS.register("your_device_name", YourDeviceProvider::new);
|
||||
*
|
||||
* PROVIDERS.register(FMLJavaModLoadingContext.get().getModEventBus());
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see RPCDevice
|
||||
* @see ObjectDevice
|
||||
* @see DeviceQuery
|
||||
* @see BlockDeviceQuery
|
||||
*/
|
||||
public interface DeviceProvider extends IForgeRegistryEntry<DeviceProvider> {
|
||||
/**
|
||||
* Get a device for the specified query.
|
||||
*
|
||||
* @param query the query describing the object to get a {@link Device} for.
|
||||
* @return a device for the specified query, if available.
|
||||
*/
|
||||
LazyOptional<Device> getDevice(DeviceQuery query);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package li.cil.oc2.api.bus.device.provider;
|
||||
|
||||
/**
|
||||
* Base interface for all queries to {@link DeviceProvider}s.
|
||||
*
|
||||
* @see DeviceProvider
|
||||
* @see BlockDeviceQuery
|
||||
*/
|
||||
public interface DeviceQuery {
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package li.cil.oc2.api.bus.device.provider;
|
||||
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.ItemDevice;
|
||||
import net.minecraftforge.registries.IForgeRegistryEntry;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* This is used to query for devices given an item stack.
|
||||
* <p>
|
||||
* Implementations <em>may</em> return various device types depending on the query.
|
||||
* <p>
|
||||
* For identical queries, implementations <em>should</em> return the same device. Failing that,
|
||||
* implementations <em>should</em> return instances that are equal to each other when compared
|
||||
* using {@link Object#equals(Object)} and have equal {@link Object#hashCode()}s.
|
||||
* <p>
|
||||
* This allows avoiding unnecessary re-initialization of devices that have not changed since a
|
||||
* previous scan.
|
||||
* <p>
|
||||
* Providers can be registered via the provider registries, much like blocks and items
|
||||
* are registered. For example:
|
||||
* <pre>
|
||||
* class YourModInitialization {
|
||||
* static DeferredRegister<ItemDeviceProvider> ITEM_DEVICE_PROVIDERS = DeferredRegister.create(ItemDeviceProvider.class, "your_mod_id");
|
||||
*
|
||||
* static void initialize() {
|
||||
* ITEM_DEVICE_PROVIDERS.register("your_item_device_name", YourItemDeviceProvider::new);
|
||||
*
|
||||
* ITEM_DEVICE_PROVIDERS.register(FMLJavaModLoadingContext.get().getModEventBus());
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see li.cil.oc2.api.bus.device.rpc.RPCDevice
|
||||
* @see li.cil.oc2.api.bus.device.object.ObjectDevice
|
||||
* @see li.cil.oc2.api.bus.device.vm.VMDevice
|
||||
* @see ItemDeviceQuery
|
||||
*/
|
||||
public interface ItemDeviceProvider extends IForgeRegistryEntry<ItemDeviceProvider> {
|
||||
/**
|
||||
* Get a device for the specified query.
|
||||
*
|
||||
* @param query the query describing the object to get a {@link Device} for.
|
||||
* @return a device for the specified query, if available.
|
||||
*/
|
||||
Optional<ItemDevice> getDevice(ItemDeviceQuery query);
|
||||
}
|
||||
@@ -2,6 +2,16 @@ package li.cil.oc2.api.bus.device.provider;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public interface ItemDeviceQuery extends DeviceQuery {
|
||||
/**
|
||||
* Device query for an item stack.
|
||||
*
|
||||
* @see ItemDeviceProvider
|
||||
*/
|
||||
public interface ItemDeviceQuery {
|
||||
/**
|
||||
* The item stack this query is performed for.
|
||||
*
|
||||
* @return the item stack to get a device for.
|
||||
*/
|
||||
ItemStack getItemStack();
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package li.cil.oc2.api.bus.device.rpc;
|
||||
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.object.ObjectDevice;
|
||||
import li.cil.oc2.api.bus.device.provider.DeviceProvider;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -20,7 +19,8 @@ import java.util.List;
|
||||
* the {@link ObjectDevice} class.
|
||||
*
|
||||
* @see ObjectDevice
|
||||
* @see DeviceProvider
|
||||
* @see li.cil.oc2.api.bus.device.provider.BlockDeviceProvider
|
||||
* @see li.cil.oc2.api.bus.device.provider.ItemDeviceProvider
|
||||
*/
|
||||
public interface RPCDevice extends Device {
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,8 @@ import li.cil.sedna.api.device.MemoryMappedDevice;
|
||||
* for releasing unmanaged resources acquired in {@link #load(VMContext)}.
|
||||
*
|
||||
* @see VMDeviceLifecycleListener
|
||||
* @see li.cil.oc2.api.bus.device.provider.BlockDeviceProvider
|
||||
* @see li.cil.oc2.api.bus.device.provider.ItemDeviceProvider
|
||||
*/
|
||||
public interface VMDevice extends Device {
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,8 @@ public abstract class AbstractTileEntity extends TileEntity {
|
||||
super(tileEntityType);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@NotNull final Capability<T> capability, @Nullable final Direction side) {
|
||||
|
||||
@@ -27,6 +27,8 @@ public class BusCableTileEntity extends AbstractTileEntity {
|
||||
setCapabilityIfAbsent(Capabilities.DEVICE_BUS_ELEMENT_CAPABILITY, busElement);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public void handleNeighborChanged(final BlockPos pos) {
|
||||
busElement.handleNeighborChanged(pos);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package li.cil.oc2.common.block.entity;
|
||||
import it.unimi.dsi.fastutil.bytes.ByteArrayFIFOQueue;
|
||||
import li.cil.ceres.api.Serialized;
|
||||
import li.cil.oc2.Constants;
|
||||
import li.cil.oc2.api.API;
|
||||
import li.cil.oc2.api.bus.DeviceBusElement;
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.vm.VMContext;
|
||||
@@ -20,10 +19,7 @@ import li.cil.oc2.common.network.message.ComputerBusStateMessage;
|
||||
import li.cil.oc2.common.network.message.ComputerRunStateMessage;
|
||||
import li.cil.oc2.common.network.message.TerminalBlockOutputMessage;
|
||||
import li.cil.oc2.common.serialization.NBTSerialization;
|
||||
import li.cil.oc2.common.util.HorizontalBlockUtils;
|
||||
import li.cil.oc2.common.util.NBTTagIds;
|
||||
import li.cil.oc2.common.util.NBTUtils;
|
||||
import li.cil.oc2.common.util.ServerScheduler;
|
||||
import li.cil.oc2.common.util.*;
|
||||
import li.cil.oc2.common.vm.Terminal;
|
||||
import li.cil.oc2.common.vm.VirtualMachine;
|
||||
import li.cil.oc2.common.vm.VirtualMachineRunner;
|
||||
@@ -128,9 +124,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
|
||||
itemHandler.setStackInSlot(2, new ItemStack(Items.RAM_8M_ITEM.get()));
|
||||
|
||||
final ItemStack hdd = new ItemStack(Items.HDD_ITEM.get());
|
||||
final CompoundNBT hddInfo = new CompoundNBT();
|
||||
hddInfo.putString(Constants.HDD_BASE_NBT_TAG_NAME, "linux");
|
||||
hdd.setTagInfo(API.MOD_ID, hddInfo);
|
||||
ItemStackUtils.getOrCreateModDataTag(hdd).putString(Constants.HDD_BASE_NBT_TAG_NAME, "linux");
|
||||
itemHandler.setStackInSlot(4, hdd);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ public class RedstoneInterfaceTileEntity extends TileEntity implements NamedDevi
|
||||
super(TileEntities.REDSTONE_INTERFACE_TILE_ENTITY.get());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
compound = super.write(compound);
|
||||
|
||||
@@ -42,6 +42,8 @@ public abstract class AbstractDeviceBusController implements DeviceBusController
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public void dispose() {
|
||||
for (final DeviceBusElement element : elements) {
|
||||
element.removeController(this);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package li.cil.oc2.common.bus;
|
||||
|
||||
import li.cil.oc2.api.bus.device.provider.BlockDeviceProvider;
|
||||
import li.cil.oc2.common.bus.device.BlockDeviceInfo;
|
||||
|
||||
public abstract class AbstractGroupingBlockDeviceBusElement extends AbstractGroupingDeviceBusElement<BlockDeviceProvider, BlockDeviceInfo> {
|
||||
public AbstractGroupingBlockDeviceBusElement(final int groupCount) {
|
||||
super(groupCount);
|
||||
}
|
||||
}
|
||||
@@ -1,55 +1,58 @@
|
||||
package li.cil.oc2.common.bus;
|
||||
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.common.bus.device.DeviceInfo;
|
||||
import li.cil.oc2.common.bus.device.AbstractDeviceInfo;
|
||||
import li.cil.oc2.common.util.ItemDeviceUtils;
|
||||
import li.cil.oc2.common.util.NBTTagIds;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.util.INBTSerializable;
|
||||
import net.minecraftforge.registries.IForgeRegistryEntry;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class AbstractGroupingDeviceBusElement extends AbstractDeviceBusElement implements INBTSerializable<ListNBT> {
|
||||
private static final String DEVICE_ID_NBT_TAG_NAME = "deviceId";
|
||||
private static final String DEVICE_DATA_NBT_TAG_NAME = "deviceData";
|
||||
public abstract class AbstractGroupingDeviceBusElement<TProvider extends IForgeRegistryEntry<TProvider>, TDeviceInfo extends AbstractDeviceInfo<TProvider, ?>> extends AbstractDeviceBusElement implements INBTSerializable<ListNBT> {
|
||||
private static final String GROUP_ID_NBT_TAG_NAME = "groupId";
|
||||
private static final String GROUP_DATA_NBT_TAG_NAME = "groupData";
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected final int groupCount;
|
||||
protected final ArrayList<HashSet<DeviceInfo>> devicesByGroup;
|
||||
protected final ArrayList<HashSet<TDeviceInfo>> groups;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected final UUID[] deviceIds;
|
||||
protected final CompoundNBT[] deviceData;
|
||||
protected final UUID[] groupIds;
|
||||
protected final CompoundNBT[] groupData;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected AbstractGroupingDeviceBusElement(final int groupCount) {
|
||||
this.groupCount = groupCount;
|
||||
this.devicesByGroup = new ArrayList<>(groupCount);
|
||||
this.deviceIds = new UUID[groupCount];
|
||||
this.deviceData = new CompoundNBT[groupCount];
|
||||
this.groups = new ArrayList<>(groupCount);
|
||||
this.groupIds = new UUID[groupCount];
|
||||
this.groupData = new CompoundNBT[groupCount];
|
||||
|
||||
for (int i = 0; i < groupCount; i++) {
|
||||
devicesByGroup.add(new HashSet<>());
|
||||
deviceIds[i] = UUID.randomUUID();
|
||||
deviceData[i] = new CompoundNBT();
|
||||
groups.add(new HashSet<>());
|
||||
groupIds[i] = UUID.randomUUID();
|
||||
groupData[i] = new CompoundNBT();
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public ListNBT serializeNBT() {
|
||||
serializeDevices();
|
||||
|
||||
final ListNBT nbt = new ListNBT();
|
||||
for (int i = 0; i < groupCount; i++) {
|
||||
serializeDevices(i);
|
||||
|
||||
final CompoundNBT sideNbt = new CompoundNBT();
|
||||
|
||||
sideNbt.putUniqueId(DEVICE_ID_NBT_TAG_NAME, deviceIds[i]);
|
||||
sideNbt.put(DEVICE_DATA_NBT_TAG_NAME, deviceData[i]);
|
||||
sideNbt.putUniqueId(GROUP_ID_NBT_TAG_NAME, groupIds[i]);
|
||||
sideNbt.put(GROUP_DATA_NBT_TAG_NAME, groupData[i]);
|
||||
|
||||
nbt.add(sideNbt);
|
||||
}
|
||||
@@ -62,11 +65,11 @@ public abstract class AbstractGroupingDeviceBusElement extends AbstractDeviceBus
|
||||
for (int i = 0; i < count; i++) {
|
||||
final CompoundNBT sideNbt = nbt.getCompound(i);
|
||||
|
||||
if (sideNbt.hasUniqueId(DEVICE_ID_NBT_TAG_NAME)) {
|
||||
deviceIds[i] = sideNbt.getUniqueId(DEVICE_ID_NBT_TAG_NAME);
|
||||
if (sideNbt.hasUniqueId(GROUP_ID_NBT_TAG_NAME)) {
|
||||
groupIds[i] = sideNbt.getUniqueId(GROUP_ID_NBT_TAG_NAME);
|
||||
}
|
||||
if (sideNbt.contains(DEVICE_DATA_NBT_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
|
||||
deviceData[i] = sideNbt.getCompound(DEVICE_DATA_NBT_TAG_NAME);
|
||||
if (sideNbt.contains(GROUP_DATA_NBT_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
|
||||
groupData[i] = sideNbt.getCompound(GROUP_DATA_NBT_TAG_NAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,10 +77,10 @@ public abstract class AbstractGroupingDeviceBusElement extends AbstractDeviceBus
|
||||
@Override
|
||||
public Optional<UUID> getDeviceIdentifier(final Device device) {
|
||||
for (int i = 0; i < groupCount; i++) {
|
||||
final HashSet<DeviceInfo> group = devicesByGroup.get(i);
|
||||
for (final DeviceInfo deviceInfo : group) {
|
||||
final HashSet<TDeviceInfo> group = groups.get(i);
|
||||
for (final TDeviceInfo deviceInfo : group) {
|
||||
if (Objects.equals(device, deviceInfo.device)) {
|
||||
return Optional.of(deviceIds[i]);
|
||||
return Optional.of(groupIds[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,29 +89,29 @@ public abstract class AbstractGroupingDeviceBusElement extends AbstractDeviceBus
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected void setDevicesForGroup(final int index, final HashSet<DeviceInfo> newDevices) {
|
||||
final HashSet<DeviceInfo> oldDevices = devicesByGroup.get(index);
|
||||
protected final void setDevicesForGroup(final int index, final Set<TDeviceInfo> newDevices) {
|
||||
final HashSet<TDeviceInfo> oldDevices = groups.get(index);
|
||||
if (Objects.equals(newDevices, oldDevices)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final HashSet<DeviceInfo> removedDevices = new HashSet<>(oldDevices);
|
||||
final HashSet<TDeviceInfo> removedDevices = new HashSet<>(oldDevices);
|
||||
removedDevices.removeAll(newDevices);
|
||||
devices.removeAll(removedDevices.stream().map(info -> info.device).collect(Collectors.toList()));
|
||||
|
||||
final HashSet<DeviceInfo> addedDevices = new HashSet<>(newDevices);
|
||||
final HashSet<TDeviceInfo> addedDevices = new HashSet<>(newDevices);
|
||||
addedDevices.removeAll(oldDevices);
|
||||
devices.addAll(addedDevices.stream().map(info -> info.device).collect(Collectors.toList()));
|
||||
|
||||
oldDevices.removeAll(removedDevices);
|
||||
oldDevices.addAll(newDevices);
|
||||
|
||||
final CompoundNBT devicesNbt = deviceData[index];
|
||||
for (final DeviceInfo deviceInfo : removedDevices) {
|
||||
getSerializationKey(deviceInfo).ifPresent(devicesNbt::remove);
|
||||
final CompoundNBT devicesNbt = groupData[index];
|
||||
for (final TDeviceInfo deviceInfo : removedDevices) {
|
||||
ItemDeviceUtils.getItemDeviceDataKey(deviceInfo.provider).ifPresent(devicesNbt::remove);
|
||||
}
|
||||
for (final DeviceInfo deviceInfo : addedDevices) {
|
||||
getSerializationKey(deviceInfo).ifPresent(key -> {
|
||||
for (final TDeviceInfo deviceInfo : addedDevices) {
|
||||
ItemDeviceUtils.getItemDeviceDataKey(deviceInfo.provider).ifPresent(key -> {
|
||||
if (devicesNbt.contains(key, NBTTagIds.TAG_COMPOUND)) {
|
||||
deviceInfo.device.deserializeNBT(devicesNbt.getCompound(key));
|
||||
}
|
||||
@@ -120,27 +123,17 @@ public abstract class AbstractGroupingDeviceBusElement extends AbstractDeviceBus
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private void serializeDevices() {
|
||||
for (int i = 0; i < groupCount; i++) {
|
||||
final CompoundNBT devicesNbt = new CompoundNBT();
|
||||
for (final DeviceInfo deviceInfo : devicesByGroup.get(i)) {
|
||||
getSerializationKey(deviceInfo).ifPresent(key -> {
|
||||
final CompoundNBT deviceNbt = deviceInfo.device.serializeNBT();
|
||||
if (!deviceNbt.isEmpty()) {
|
||||
devicesNbt.put(key, deviceNbt);
|
||||
}
|
||||
});
|
||||
}
|
||||
deviceData[i] = devicesNbt;
|
||||
}
|
||||
}
|
||||
|
||||
private static Optional<String> getSerializationKey(final DeviceInfo info) {
|
||||
final ResourceLocation providerName = info.provider.getRegistryName();
|
||||
if (providerName == null) {
|
||||
return Optional.empty();
|
||||
private void serializeDevices(final int index) {
|
||||
final CompoundNBT devicesNbt = new CompoundNBT();
|
||||
for (final TDeviceInfo deviceInfo : groups.get(index)) {
|
||||
ItemDeviceUtils.getItemDeviceDataKey(deviceInfo.provider).ifPresent(key -> {
|
||||
final CompoundNBT deviceNbt = deviceInfo.device.serializeNBT();
|
||||
if (!deviceNbt.isEmpty()) {
|
||||
devicesNbt.put(key, deviceNbt);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return Optional.of(providerName.toString());
|
||||
groupData[index] = devicesNbt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package li.cil.oc2.common.bus;
|
||||
|
||||
import li.cil.oc2.api.bus.device.provider.ItemDeviceProvider;
|
||||
import li.cil.oc2.common.bus.device.ItemDeviceInfo;
|
||||
|
||||
public abstract class AbstractGroupingItemDeviceBusElement extends AbstractGroupingDeviceBusElement<ItemDeviceProvider, ItemDeviceInfo> {
|
||||
public AbstractGroupingItemDeviceBusElement(final int groupCount) {
|
||||
super(groupCount);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,64 @@
|
||||
package li.cil.oc2.common.bus;
|
||||
|
||||
import li.cil.oc2.common.bus.device.DeviceInfo;
|
||||
import li.cil.oc2.common.bus.device.Devices;
|
||||
import li.cil.oc2.common.bus.device.ItemDeviceInfo;
|
||||
import li.cil.oc2.common.util.ItemDeviceUtils;
|
||||
import li.cil.oc2.common.util.NBTTagIds;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class ItemHandlerDeviceBusElement extends AbstractGroupingDeviceBusElement {
|
||||
private final ItemStackHandler handler;
|
||||
public class ItemHandlerDeviceBusElement extends AbstractGroupingItemDeviceBusElement {
|
||||
public ItemHandlerDeviceBusElement(final int slotCount) {
|
||||
super(slotCount);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public ItemHandlerDeviceBusElement(final ItemStackHandler handler) {
|
||||
super(handler.getSlots());
|
||||
this.handler = handler;
|
||||
public void updateDevices(final int slot, final ItemStack stack) {
|
||||
if (!stack.isEmpty()) {
|
||||
final HashSet<ItemDeviceInfo> newDevices = new HashSet<>(Devices.getDevices(stack));
|
||||
importDeviceDataFromItemStack(stack, newDevices);
|
||||
setDevicesForGroup(slot, newDevices);
|
||||
} else {
|
||||
setDevicesForGroup(slot, Collections.emptySet());
|
||||
}
|
||||
}
|
||||
|
||||
public void handleSlotChanged(final int slot) {
|
||||
final HashSet<DeviceInfo> newDevices = new HashSet<>();
|
||||
final ItemStack stack = handler.getStackInSlot(slot);
|
||||
public void handleBeforeItemRemoved(final int slot, final ItemStack stack) {
|
||||
if (!stack.isEmpty()) {
|
||||
for (final LazyOptional<DeviceInfo> info : Devices.getDevices(stack)) {
|
||||
info.ifPresent(newDevices::add);
|
||||
info.addListener(unused -> handleSlotChanged(slot));
|
||||
}
|
||||
exportDeviceDataToItemStack(slot, stack);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private void exportDeviceDataToItemStack(final int slot, final ItemStack stack) {
|
||||
final CompoundNBT exportedNbt = new CompoundNBT();
|
||||
for (final ItemDeviceInfo info : groups.get(slot)) {
|
||||
ItemDeviceUtils.getItemDeviceDataKey(info.provider).ifPresent(key -> {
|
||||
final CompoundNBT deviceNbt = new CompoundNBT();
|
||||
info.device.exportToItemStack(deviceNbt);
|
||||
if (!deviceNbt.isEmpty()) {
|
||||
exportedNbt.put(key, deviceNbt);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setDevicesForGroup(slot, newDevices);
|
||||
ItemDeviceUtils.setItemDeviceData(stack, exportedNbt);
|
||||
}
|
||||
|
||||
private void importDeviceDataFromItemStack(final ItemStack stack, final HashSet<ItemDeviceInfo> devices) {
|
||||
ItemDeviceUtils.getItemDeviceData(stack).ifPresent(exportedNbt -> {
|
||||
for (final ItemDeviceInfo info : devices) {
|
||||
ItemDeviceUtils.getItemDeviceDataKey(info.provider).ifPresent(key -> {
|
||||
if (exportedNbt.contains(key, NBTTagIds.TAG_COMPOUND)) {
|
||||
info.device.importFromItemStack(exportedNbt.getCompound(key));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,8 @@ public final class RPCAdapter implements Steppable {
|
||||
.create();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public void reset() {
|
||||
transmitBuffer.clear();
|
||||
receiveBuffer = null;
|
||||
|
||||
@@ -2,7 +2,7 @@ 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.bus.device.DeviceInfo;
|
||||
import li.cil.oc2.common.bus.device.BlockDeviceInfo;
|
||||
import li.cil.oc2.common.bus.device.Devices;
|
||||
import li.cil.oc2.common.capabilities.Capabilities;
|
||||
import li.cil.oc2.common.util.ServerScheduler;
|
||||
@@ -21,7 +21,7 @@ import java.util.Optional;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class TileEntityDeviceBusElement extends AbstractGroupingDeviceBusElement {
|
||||
public class TileEntityDeviceBusElement extends AbstractGroupingBlockDeviceBusElement {
|
||||
private static final int NEIGHBOR_COUNT = 6;
|
||||
final Direction[] NEIGHBOR_DIRECTIONS = Direction.values();
|
||||
|
||||
@@ -36,6 +36,8 @@ public class TileEntityDeviceBusElement extends AbstractGroupingDeviceBusElement
|
||||
this.tileEntity = tileEntity;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public Optional<Collection<LazyOptional<DeviceBusElement>>> getNeighbors() {
|
||||
final World world = tileEntity.getWorld();
|
||||
@@ -80,9 +82,9 @@ public class TileEntityDeviceBusElement extends AbstractGroupingDeviceBusElement
|
||||
|
||||
final int index = direction.getIndex();
|
||||
|
||||
final HashSet<DeviceInfo> newDevices = new HashSet<>();
|
||||
final HashSet<BlockDeviceInfo> newDevices = new HashSet<>();
|
||||
if (canConnectToSide(direction)) {
|
||||
for (final LazyOptional<DeviceInfo> deviceInfo : Devices.getDevices(world, pos, direction)) {
|
||||
for (final LazyOptional<BlockDeviceInfo> deviceInfo : Devices.getDevices(world, pos, direction)) {
|
||||
deviceInfo.ifPresent(newDevices::add);
|
||||
deviceInfo.addListener(unused -> handleNeighborChanged(pos));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package li.cil.oc2.common.bus.device;
|
||||
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import net.minecraftforge.registries.IForgeRegistryEntry;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class AbstractDeviceInfo<TProvider extends IForgeRegistryEntry<TProvider>, TDevice extends Device> {
|
||||
public final TProvider provider;
|
||||
public final TDevice device;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected AbstractDeviceInfo(final TProvider provider, final TDevice device) {
|
||||
this.provider = provider;
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final AbstractDeviceInfo<?, ?> that = (AbstractDeviceInfo<?, ?>) o;
|
||||
return provider.equals(that.provider) && device.equals(that.device);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(provider, device);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package li.cil.oc2.common.bus.device;
|
||||
|
||||
import li.cil.oc2.api.bus.device.vm.*;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractObjectProxy;
|
||||
import li.cil.oc2.common.serialization.BlobStorage;
|
||||
import li.cil.oc2.common.serialization.NBTSerialization;
|
||||
import li.cil.oc2.common.util.NBTTagIds;
|
||||
@@ -17,7 +16,7 @@ import java.util.OptionalInt;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class AbstractHardDiskDriveDevice<T extends BlockDevice> extends AbstractObjectProxy<ItemStack> implements VMDevice, VMDeviceLifecycleListener {
|
||||
public abstract class AbstractHardDiskDriveDevice<T extends BlockDevice> extends AbstractItemDevice implements VMDevice, VMDeviceLifecycleListener {
|
||||
private static final String DEVICE_NBT_TAG_NAME = "device";
|
||||
private static final String ADDRESS_NBT_TAG_NAME = "address";
|
||||
private static final String INTERRUPT_NBT_TAG_NAME = "interrupt";
|
||||
@@ -45,6 +44,8 @@ public abstract class AbstractHardDiskDriveDevice<T extends BlockDevice> extends
|
||||
super(stack);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public VMDeviceLoadResult load(final VMContext context) {
|
||||
if (!allocateDevice(context)) {
|
||||
@@ -76,6 +77,20 @@ public abstract class AbstractHardDiskDriveDevice<T extends BlockDevice> extends
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportToItemStack(final CompoundNBT nbt) {
|
||||
if (blobHandle != null) {
|
||||
nbt.putUniqueId(BLOB_HANDLE_NBT_TAG_NAME, blobHandle);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importFromItemStack(final CompoundNBT nbt) {
|
||||
if (nbt.hasUniqueId(BLOB_HANDLE_NBT_TAG_NAME)) {
|
||||
blobHandle = nbt.getUniqueId(BLOB_HANDLE_NBT_TAG_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT serializeNBT() {
|
||||
final CompoundNBT nbt = new CompoundNBT();
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package li.cil.oc2.common.bus.device;
|
||||
|
||||
import li.cil.oc2.api.bus.device.ItemDevice;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
|
||||
public abstract class AbstractItemDevice extends AbstractObjectDevice<ItemStack> implements ItemDevice {
|
||||
public AbstractItemDevice(final ItemStack value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void exportToItemStack(final CompoundNBT nbt) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importFromItemStack(final CompoundNBT nbt) {
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,24 @@
|
||||
package li.cil.oc2.common.bus.device.provider.util;
|
||||
package li.cil.oc2.common.bus.device;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class AbstractObjectProxy<T> {
|
||||
public abstract class AbstractObjectDevice<T> {
|
||||
protected final T value;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public AbstractObjectProxy(final T value) {
|
||||
public AbstractObjectDevice(final T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final AbstractObjectProxy<?> that = (AbstractObjectProxy<?>) o;
|
||||
final AbstractObjectDevice<?> that = (AbstractObjectDevice<?>) o;
|
||||
return value.equals(that.value);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package li.cil.oc2.common.bus.device;
|
||||
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.provider.BlockDeviceProvider;
|
||||
|
||||
public final class BlockDeviceInfo extends AbstractDeviceInfo<BlockDeviceProvider, Device> {
|
||||
public BlockDeviceInfo(final BlockDeviceProvider blockDeviceProvider, final Device device) {
|
||||
super(blockDeviceProvider, device);
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package li.cil.oc2.common.bus.device;
|
||||
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.provider.DeviceProvider;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class DeviceInfo {
|
||||
public final Device device;
|
||||
public final DeviceProvider provider;
|
||||
|
||||
public DeviceInfo(final Device device, final DeviceProvider provider) {
|
||||
this.device = device;
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final DeviceInfo that = (DeviceInfo) o;
|
||||
return device.equals(that.device) && provider.equals(that.provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(device, provider);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package li.cil.oc2.common.bus.device;
|
||||
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.ItemDevice;
|
||||
import li.cil.oc2.api.bus.device.provider.BlockDeviceProvider;
|
||||
import li.cil.oc2.api.bus.device.provider.BlockDeviceQuery;
|
||||
import li.cil.oc2.api.bus.device.provider.DeviceProvider;
|
||||
import li.cil.oc2.api.bus.device.provider.DeviceQuery;
|
||||
import li.cil.oc2.api.bus.device.provider.ItemDeviceProvider;
|
||||
import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery;
|
||||
import li.cil.oc2.common.init.Providers;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -17,9 +18,10 @@ import net.minecraftforge.registries.IForgeRegistry;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class Devices {
|
||||
public static List<LazyOptional<DeviceInfo>> getDevices(final TileEntity tileEntity, final Direction side) {
|
||||
public static List<LazyOptional<BlockDeviceInfo>> getDevices(final TileEntity tileEntity, final Direction side) {
|
||||
final World world = tileEntity.getWorld();
|
||||
final BlockPos pos = tileEntity.getPos();
|
||||
|
||||
@@ -28,21 +30,23 @@ public final class Devices {
|
||||
return getDevices(world, pos, side);
|
||||
}
|
||||
|
||||
public static List<LazyOptional<DeviceInfo>> getDevices(final World world, final BlockPos pos, final Direction side) {
|
||||
public static List<LazyOptional<BlockDeviceInfo>> getDevices(final World world, final BlockPos pos, final Direction side) {
|
||||
return getDevices(new BlockQuery(world, pos, side));
|
||||
}
|
||||
|
||||
public static List<LazyOptional<DeviceInfo>> getDevices(final ItemStack stack) {
|
||||
public static List<ItemDeviceInfo> getDevices(final ItemStack stack) {
|
||||
return getDevices(new ItemQuery(stack));
|
||||
}
|
||||
|
||||
public static List<LazyOptional<DeviceInfo>> getDevices(final DeviceQuery query) {
|
||||
final IForgeRegistry<DeviceProvider> providers = Providers.PROVIDERS_REGISTRY.get();
|
||||
final ArrayList<LazyOptional<DeviceInfo>> devices = new ArrayList<>();
|
||||
for (final DeviceProvider provider : providers.getValues()) {
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private static List<LazyOptional<BlockDeviceInfo>> getDevices(final BlockQuery query) {
|
||||
final IForgeRegistry<BlockDeviceProvider> registry = Providers.BLOCK_DEVICE_PROVIDER_REGISTRY.get();
|
||||
final ArrayList<LazyOptional<BlockDeviceInfo>> devices = new ArrayList<>();
|
||||
for (final BlockDeviceProvider provider : registry.getValues()) {
|
||||
final LazyOptional<Device> device = provider.getDevice(query);
|
||||
if (device.isPresent()) {
|
||||
final LazyOptional<DeviceInfo> info = device.lazyMap(d -> new DeviceInfo(d, provider));
|
||||
final LazyOptional<BlockDeviceInfo> info = device.lazyMap(d -> new BlockDeviceInfo(provider, d));
|
||||
device.addListener(unused -> info.invalidate());
|
||||
devices.add(info);
|
||||
}
|
||||
@@ -50,6 +54,16 @@ public final class Devices {
|
||||
return devices;
|
||||
}
|
||||
|
||||
private static List<ItemDeviceInfo> getDevices(final ItemQuery query) {
|
||||
final IForgeRegistry<ItemDeviceProvider> registry = Providers.ITEM_DEVICE_PROVIDER_REGISTRY.get();
|
||||
final ArrayList<ItemDeviceInfo> devices = new ArrayList<>();
|
||||
for (final ItemDeviceProvider provider : registry.getValues()) {
|
||||
final Optional<ItemDevice> device = provider.getDevice(query);
|
||||
device.ifPresent(d -> devices.add(new ItemDeviceInfo(provider, d)));
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private static class BlockQuery implements BlockDeviceQuery {
|
||||
|
||||
@@ -11,12 +11,16 @@ public final class HardDiskDriveDevice extends AbstractHardDiskDriveDevice<ByteB
|
||||
private final int size;
|
||||
private final boolean readonly;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public HardDiskDriveDevice(final ItemStack stack, final int size, final boolean readonly) {
|
||||
super(stack);
|
||||
this.size = size;
|
||||
this.readonly = readonly;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected int getSize() {
|
||||
return size;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package li.cil.oc2.common.bus.device;
|
||||
|
||||
import li.cil.oc2.api.bus.device.ItemDevice;
|
||||
import li.cil.oc2.api.bus.device.provider.ItemDeviceProvider;
|
||||
|
||||
public class ItemDeviceInfo extends AbstractDeviceInfo<ItemDeviceProvider, ItemDevice> {
|
||||
public ItemDeviceInfo(final ItemDeviceProvider itemDeviceProvider, final ItemDevice device) {
|
||||
super(itemDeviceProvider, device);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package li.cil.oc2.common.bus.device;
|
||||
|
||||
import li.cil.oc2.Constants;
|
||||
import li.cil.oc2.api.bus.device.vm.*;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractObjectProxy;
|
||||
import li.cil.oc2.common.serialization.BlobStorage;
|
||||
import li.cil.oc2.common.util.NBTTagIds;
|
||||
import li.cil.sedna.api.device.PhysicalMemory;
|
||||
@@ -15,7 +14,7 @@ import net.minecraft.nbt.CompoundNBT;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class MemoryDevice extends AbstractObjectProxy<ItemStack> implements VMDevice, VMDeviceLifecycleListener {
|
||||
public final class MemoryDevice extends AbstractItemDevice implements VMDevice, VMDeviceLifecycleListener {
|
||||
private static final String BLOB_HANDLE_NBT_TAG_NAME = "blob";
|
||||
private static final String ADDRESS_NBT_TAG_NAME = "address";
|
||||
|
||||
@@ -37,6 +36,8 @@ public final class MemoryDevice extends AbstractObjectProxy<ItemStack> implement
|
||||
super(value);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public VMDeviceLoadResult load(final VMContext context) {
|
||||
if (!allocateDevice(context)) {
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
package li.cil.oc2.common.bus.device.provider;
|
||||
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.object.Callbacks;
|
||||
import li.cil.oc2.api.bus.device.object.ObjectDevice;
|
||||
import li.cil.oc2.api.bus.device.provider.BlockDeviceQuery;
|
||||
import li.cil.oc2.api.bus.device.provider.DeviceQuery;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractDeviceProvider;
|
||||
import li.cil.oc2.common.util.WorldUtils;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
public final class BlockDeviceProvider extends AbstractDeviceProvider {
|
||||
@Override
|
||||
public LazyOptional<Device> getDevice(final DeviceQuery query) {
|
||||
if (!(query instanceof BlockDeviceQuery)) {
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
final BlockDeviceQuery blockQuery = (BlockDeviceQuery) query;
|
||||
final BlockState blockState = blockQuery.getWorld().getBlockState(blockQuery.getQueryPosition());
|
||||
if (blockState.getBlock().isAir(blockState, blockQuery.getWorld(), blockQuery.getQueryPosition())) {
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
final Block block = blockState.getBlock();
|
||||
if (!Callbacks.hasMethods(block)) {
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
final String typeName = WorldUtils.getBlockName(blockQuery.getWorld(), blockQuery.getQueryPosition());
|
||||
return LazyOptional.of(() -> new ObjectDevice(block, typeName));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package li.cil.oc2.common.bus.device.provider;
|
||||
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.object.Callbacks;
|
||||
import li.cil.oc2.api.bus.device.object.ObjectDevice;
|
||||
import li.cil.oc2.api.bus.device.provider.BlockDeviceQuery;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractBlockDeviceProvider;
|
||||
import li.cil.oc2.common.util.WorldUtils;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
public final class BlockStateDeviceProvider extends AbstractBlockDeviceProvider {
|
||||
@Override
|
||||
public LazyOptional<Device> getDevice(final BlockDeviceQuery query) {
|
||||
final World world = query.getWorld();
|
||||
final BlockPos position = query.getQueryPosition();
|
||||
|
||||
final BlockState blockState = world.getBlockState(position);
|
||||
final Block block = blockState.getBlock();
|
||||
|
||||
if (block.isAir(blockState, world, position)) {
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
if (!Callbacks.hasMethods(block)) {
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
final String typeName = WorldUtils.getBlockName(world, position);
|
||||
return LazyOptional.of(() -> new ObjectDevice(block, typeName));
|
||||
}
|
||||
}
|
||||
@@ -4,31 +4,32 @@ import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.object.Callback;
|
||||
import li.cil.oc2.api.bus.device.object.ObjectDevice;
|
||||
import li.cil.oc2.api.bus.device.provider.BlockDeviceQuery;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractCapabilityAnyTileEntityDeviceProvider;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractObjectProxy;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractTileEntityCapabilityDeviceProvider;
|
||||
import li.cil.oc2.common.bus.device.AbstractObjectDevice;
|
||||
import li.cil.oc2.common.capabilities.Capabilities;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.energy.IEnergyStorage;
|
||||
|
||||
public final class EnergyStorageDeviceProvider extends AbstractCapabilityAnyTileEntityDeviceProvider<IEnergyStorage> {
|
||||
public final class EnergyStorageBlockDeviceProvider extends AbstractTileEntityCapabilityDeviceProvider<IEnergyStorage, TileEntity> {
|
||||
private static final String ENERGY_STORAGE_TYPE_NAME = "energyStorage";
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public EnergyStorageDeviceProvider() {
|
||||
public EnergyStorageBlockDeviceProvider() {
|
||||
super(() -> Capabilities.ENERGY_STORAGE_CAPABILITY);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected LazyOptional<Device> getDevice(final BlockDeviceQuery query, final IEnergyStorage value) {
|
||||
protected LazyOptional<Device> getBlockDevice(final BlockDeviceQuery query, final IEnergyStorage value) {
|
||||
return LazyOptional.of(() -> new ObjectDevice(new EnergyStorageDevice(value), ENERGY_STORAGE_TYPE_NAME));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static final class EnergyStorageDevice extends AbstractObjectProxy<IEnergyStorage> {
|
||||
public static final class EnergyStorageDevice extends AbstractObjectDevice<IEnergyStorage> {
|
||||
public EnergyStorageDevice(final IEnergyStorage energyStorage) {
|
||||
super(energyStorage);
|
||||
}
|
||||
@@ -4,32 +4,33 @@ import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.object.Callback;
|
||||
import li.cil.oc2.api.bus.device.object.ObjectDevice;
|
||||
import li.cil.oc2.api.bus.device.provider.BlockDeviceQuery;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractCapabilityAnyTileEntityDeviceProvider;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractObjectProxy;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractTileEntityCapabilityDeviceProvider;
|
||||
import li.cil.oc2.common.bus.device.AbstractObjectDevice;
|
||||
import li.cil.oc2.common.capabilities.Capabilities;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
|
||||
public final class FluidHandlerDeviceProvider extends AbstractCapabilityAnyTileEntityDeviceProvider<IFluidHandler> {
|
||||
public final class FluidHandlerBlockDeviceProvider extends AbstractTileEntityCapabilityDeviceProvider<IFluidHandler, TileEntity> {
|
||||
private static final String FLUID_HANDLER_TYPE_NAME = "fluidHandler";
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public FluidHandlerDeviceProvider() {
|
||||
public FluidHandlerBlockDeviceProvider() {
|
||||
super(() -> Capabilities.FLUID_HANDLER_CAPABILITY);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected LazyOptional<Device> getDevice(final BlockDeviceQuery query, final IFluidHandler value) {
|
||||
protected LazyOptional<Device> getBlockDevice(final BlockDeviceQuery query, final IFluidHandler value) {
|
||||
return LazyOptional.of(() -> new ObjectDevice(new FluidHandlerDevice(value), FLUID_HANDLER_TYPE_NAME));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static final class FluidHandlerDevice extends AbstractObjectProxy<IFluidHandler> {
|
||||
public static final class FluidHandlerDevice extends AbstractObjectDevice<IFluidHandler> {
|
||||
public FluidHandlerDevice(final IFluidHandler fluidHandler) {
|
||||
super(fluidHandler);
|
||||
}
|
||||
@@ -2,70 +2,88 @@ package li.cil.oc2.common.bus.device.provider;
|
||||
|
||||
import li.cil.oc2.Config;
|
||||
import li.cil.oc2.Constants;
|
||||
import li.cil.oc2.api.API;
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.ItemDevice;
|
||||
import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery;
|
||||
import li.cil.oc2.common.bus.device.HardDiskDriveDevice;
|
||||
import li.cil.oc2.common.bus.device.SparseHardDiskDriveDevice;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractItemDeviceProvider;
|
||||
import li.cil.oc2.common.init.Items;
|
||||
import li.cil.oc2.common.util.ItemStackUtils;
|
||||
import li.cil.oc2.common.util.NBTTagIds;
|
||||
import li.cil.sedna.api.device.BlockDevice;
|
||||
import li.cil.sedna.buildroot.Buildroot;
|
||||
import li.cil.sedna.device.block.ByteBufferBlockDevice;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class HardDriveItemDeviceProvider extends AbstractItemDeviceProvider {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private static final ByteBufferBlockDevice ROOT_FS;
|
||||
|
||||
static {
|
||||
ByteBufferBlockDevice rootfs;
|
||||
try {
|
||||
rootfs = ByteBufferBlockDevice.createFromStream(Buildroot.getRootFilesystem(), true);
|
||||
} catch (final IOException e) {
|
||||
LOGGER.error(e);
|
||||
rootfs = ByteBufferBlockDevice.create(0, true);
|
||||
}
|
||||
ROOT_FS = rootfs;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public HardDriveItemDeviceProvider() {
|
||||
super(Items.HDD_ITEM.get());
|
||||
super(Items.HDD_ITEM);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected LazyOptional<Device> getItemDevice(final ItemDeviceQuery query) {
|
||||
protected Optional<ItemDevice> getItemDevice(final ItemDeviceQuery query) {
|
||||
final ItemStack stack = query.getItemStack();
|
||||
|
||||
final CompoundNBT info = stack.getChildTag(API.MOD_ID);
|
||||
final CompoundNBT info = ItemStackUtils.getModDataTag(stack);
|
||||
if (info == null) {
|
||||
return LazyOptional.empty();
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
final boolean readonly = info.getBoolean(Constants.HDD_READONLY_NBT_TAG_NAME);
|
||||
if (info.contains(Constants.HDD_BASE_NBT_TAG_NAME, NBTTagIds.TAG_STRING)) {
|
||||
final String baseName = info.getString(Constants.HDD_BASE_NBT_TAG_NAME);
|
||||
|
||||
BlockDevice base = null;
|
||||
|
||||
// TODO Allow registering additional base file systems?
|
||||
if (Objects.equals(baseName, "linux")) {
|
||||
try {
|
||||
base = ByteBufferBlockDevice.createFromStream(Buildroot.getRootFilesystem(), true);
|
||||
} catch (final IOException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
}
|
||||
final BlockDevice base = getBaseBlockDevice(baseName);
|
||||
|
||||
if (base != null) {
|
||||
final BlockDevice baseForClosure = base;
|
||||
return LazyOptional.of(() -> new SparseHardDiskDriveDevice(stack, baseForClosure, readonly));
|
||||
return Optional.of(new SparseHardDiskDriveDevice(stack, base, readonly));
|
||||
}
|
||||
} else if (info.contains(Constants.HDD_SIZE_NBT_TAG_NAME, NBTTagIds.TAG_INT)) {
|
||||
final int size = Math.max(0, Math.min(Config.maxHddSize, info.getInt(Constants.HDD_SIZE_NBT_TAG_NAME)));
|
||||
return LazyOptional.of(() -> new HardDiskDriveDevice(stack, size, readonly));
|
||||
return Optional.of(new HardDiskDriveDevice(stack, size, readonly));
|
||||
}
|
||||
|
||||
return LazyOptional.empty();
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Nullable
|
||||
private static BlockDevice getBaseBlockDevice(final String name) {
|
||||
// TODO Allow registering additional base file systems.
|
||||
if (Objects.equals(name, "linux")) {
|
||||
return ROOT_FS;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,32 +4,33 @@ import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.object.Callback;
|
||||
import li.cil.oc2.api.bus.device.object.ObjectDevice;
|
||||
import li.cil.oc2.api.bus.device.provider.BlockDeviceQuery;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractCapabilityAnyTileEntityDeviceProvider;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractObjectProxy;
|
||||
import li.cil.oc2.common.bus.device.AbstractObjectDevice;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractTileEntityCapabilityDeviceProvider;
|
||||
import li.cil.oc2.common.capabilities.Capabilities;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public final class ItemHandlerDeviceProvider extends AbstractCapabilityAnyTileEntityDeviceProvider<IItemHandler> {
|
||||
public final class ItemHandlerBlockDeviceProvider extends AbstractTileEntityCapabilityDeviceProvider<IItemHandler, TileEntity> {
|
||||
private static final String ITEM_HANDLER_TYPE_NAME = "itemHandler";
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public ItemHandlerDeviceProvider() {
|
||||
public ItemHandlerBlockDeviceProvider() {
|
||||
super(() -> Capabilities.ITEM_HANDLER_CAPABILITY);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected LazyOptional<Device> getDevice(final BlockDeviceQuery query, final IItemHandler value) {
|
||||
protected LazyOptional<Device> getBlockDevice(final BlockDeviceQuery query, final IItemHandler value) {
|
||||
return LazyOptional.of(() -> new ObjectDevice(new ItemHandlerDevice(value), ITEM_HANDLER_TYPE_NAME));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static final class ItemHandlerDevice extends AbstractObjectProxy<IItemHandler> {
|
||||
public static final class ItemHandlerDevice extends AbstractObjectDevice<IItemHandler> {
|
||||
public ItemHandlerDevice(final IItemHandler itemHandler) {
|
||||
super(itemHandler);
|
||||
}
|
||||
@@ -1,21 +1,22 @@
|
||||
package li.cil.oc2.common.bus.device.provider;
|
||||
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.ItemDevice;
|
||||
import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery;
|
||||
import li.cil.oc2.common.bus.device.MemoryDevice;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractItemDeviceProvider;
|
||||
import li.cil.oc2.common.init.Items;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public final class MemoryItemDeviceProvider extends AbstractItemDeviceProvider {
|
||||
public MemoryItemDeviceProvider() {
|
||||
super(Items.RAM_8M_ITEM.get());
|
||||
super(Items.RAM_8M_ITEM);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected LazyOptional<Device> getItemDevice(final ItemDeviceQuery query) {
|
||||
return LazyOptional.of(() -> new MemoryDevice(query.getItemStack()));
|
||||
protected Optional<ItemDevice> getItemDevice(final ItemDeviceQuery query) {
|
||||
return Optional.of(new MemoryDevice(query.getItemStack()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,15 +7,12 @@ import li.cil.oc2.api.bus.device.provider.BlockDeviceQuery;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractTileEntityDeviceProvider;
|
||||
import li.cil.oc2.common.util.WorldUtils;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
public final class TileEntityDeviceProvider extends AbstractTileEntityDeviceProvider<TileEntity> {
|
||||
public TileEntityDeviceProvider() {
|
||||
super(TileEntity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyOptional<Device> getDevice(final BlockDeviceQuery query, final TileEntity tileEntity) {
|
||||
public LazyOptional<Device> getBlockDevice(final BlockDeviceQuery query, final TileEntity tileEntity) {
|
||||
if (Callbacks.hasMethods(tileEntity)) {
|
||||
return LazyOptional.of(() -> {
|
||||
final String typeName = WorldUtils.getBlockName(query.getWorld(), query.getQueryPosition());
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package li.cil.oc2.common.bus.device.provider.util;
|
||||
|
||||
import li.cil.oc2.api.bus.device.provider.BlockDeviceProvider;
|
||||
import net.minecraftforge.registries.ForgeRegistryEntry;
|
||||
|
||||
public abstract class AbstractBlockDeviceProvider extends ForgeRegistryEntry<BlockDeviceProvider> implements BlockDeviceProvider {
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package li.cil.oc2.common.bus.device.provider.util;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public abstract class AbstractCapabilityAnyTileEntityDeviceProvider<TCapability> extends AbstractCapabilityTileEntityDeviceProvider<TCapability, TileEntity> {
|
||||
public AbstractCapabilityAnyTileEntityDeviceProvider(final Supplier<Capability<TCapability>> capabilitySupplier) {
|
||||
super(TileEntity.class, capabilitySupplier);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package li.cil.oc2.common.bus.device.provider.util;
|
||||
|
||||
import li.cil.oc2.api.bus.device.provider.DeviceProvider;
|
||||
import net.minecraftforge.registries.ForgeRegistryEntry;
|
||||
|
||||
public abstract class AbstractDeviceProvider extends ForgeRegistryEntry<DeviceProvider> implements DeviceProvider {
|
||||
}
|
||||
@@ -1,37 +1,45 @@
|
||||
package li.cil.oc2.common.bus.device.provider.util;
|
||||
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.provider.DeviceQuery;
|
||||
import li.cil.oc2.api.bus.device.ItemDevice;
|
||||
import li.cil.oc2.api.bus.device.provider.ItemDeviceProvider;
|
||||
import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fml.RegistryObject;
|
||||
import net.minecraftforge.registries.ForgeRegistryEntry;
|
||||
|
||||
public abstract class AbstractItemDeviceProvider extends AbstractDeviceProvider {
|
||||
private final Item item;
|
||||
import java.util.Optional;
|
||||
|
||||
protected AbstractItemDeviceProvider(final Item item) {
|
||||
public abstract class AbstractItemDeviceProvider extends ForgeRegistryEntry<ItemDeviceProvider> implements ItemDeviceProvider {
|
||||
private final RegistryObject<Item> item;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected AbstractItemDeviceProvider(final RegistryObject<Item> item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyOptional<Device> getDevice(final DeviceQuery query) {
|
||||
if (!(query instanceof ItemDeviceQuery)) {
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
final ItemDeviceQuery itemDeviceQuery = (ItemDeviceQuery) query;
|
||||
final ItemStack stack = itemDeviceQuery.getItemStack();
|
||||
if (stack.isEmpty()) {
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
if (stack.getItem() != item) {
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
return getItemDevice(itemDeviceQuery);
|
||||
protected AbstractItemDeviceProvider() {
|
||||
this.item = null;
|
||||
}
|
||||
|
||||
protected abstract LazyOptional<Device> getItemDevice(final ItemDeviceQuery query);
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public final Optional<ItemDevice> getDevice(final ItemDeviceQuery query) {
|
||||
final ItemStack stack = query.getItemStack();
|
||||
if (stack.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (item != null && stack.getItem() != item.get()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return getItemDevice(query);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected abstract Optional<ItemDevice> getItemDevice(final ItemDeviceQuery query);
|
||||
}
|
||||
|
||||
@@ -3,23 +3,30 @@ package li.cil.oc2.common.bus.device.provider.util;
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.provider.BlockDeviceQuery;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public abstract class AbstractCapabilityTileEntityDeviceProvider<TCapability, TTileEntity extends TileEntity> extends AbstractTileEntityDeviceProvider<TTileEntity> {
|
||||
public abstract class AbstractTileEntityCapabilityDeviceProvider<TCapability, TTileEntity extends TileEntity> extends AbstractTileEntityDeviceProvider<TTileEntity> {
|
||||
private final Supplier<Capability<TCapability>> capabilitySupplier;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected AbstractCapabilityTileEntityDeviceProvider(final Class<TTileEntity> tileEntityType, final Supplier<Capability<TCapability>> capabilitySupplier) {
|
||||
protected AbstractTileEntityCapabilityDeviceProvider(final TileEntityType<TTileEntity> tileEntityType, final Supplier<Capability<TCapability>> capabilitySupplier) {
|
||||
super(tileEntityType);
|
||||
this.capabilitySupplier = capabilitySupplier;
|
||||
}
|
||||
|
||||
protected AbstractTileEntityCapabilityDeviceProvider(final Supplier<Capability<TCapability>> capabilitySupplier) {
|
||||
this.capabilitySupplier = capabilitySupplier;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected final LazyOptional<Device> getDevice(final BlockDeviceQuery blockQuery, final TileEntity tileEntity) {
|
||||
protected final LazyOptional<Device> getBlockDevice(final BlockDeviceQuery blockQuery, final TileEntity tileEntity) {
|
||||
final Capability<TCapability> capability = capabilitySupplier.get();
|
||||
if (capability == null) throw new IllegalStateException();
|
||||
final LazyOptional<TCapability> optional = tileEntity.getCapability(capability, blockQuery.getQuerySide());
|
||||
@@ -28,10 +35,10 @@ public abstract class AbstractCapabilityTileEntityDeviceProvider<TCapability, TT
|
||||
}
|
||||
|
||||
final TCapability value = optional.orElseThrow(AssertionError::new);
|
||||
final LazyOptional<Device> device = getDevice(blockQuery, value);
|
||||
final LazyOptional<Device> device = getBlockDevice(blockQuery, value);
|
||||
optional.addListener(ignored -> device.invalidate());
|
||||
return device;
|
||||
}
|
||||
|
||||
protected abstract LazyOptional<Device> getDevice(final BlockDeviceQuery query, final TCapability value);
|
||||
protected abstract LazyOptional<Device> getBlockDevice(final BlockDeviceQuery query, final TCapability value);
|
||||
}
|
||||
@@ -2,37 +2,42 @@ package li.cil.oc2.common.bus.device.provider.util;
|
||||
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
import li.cil.oc2.api.bus.device.provider.BlockDeviceQuery;
|
||||
import li.cil.oc2.api.bus.device.provider.DeviceQuery;
|
||||
import li.cil.oc2.common.util.WorldUtils;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
public abstract class AbstractTileEntityDeviceProvider<T extends TileEntity> extends AbstractDeviceProvider {
|
||||
private final Class<T> tileEntityType;
|
||||
public abstract class AbstractTileEntityDeviceProvider<T extends TileEntity> extends AbstractBlockDeviceProvider {
|
||||
private final TileEntityType<T> tileEntityType;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected AbstractTileEntityDeviceProvider(final Class<T> tileEntityType) {
|
||||
protected AbstractTileEntityDeviceProvider(final TileEntityType<T> tileEntityType) {
|
||||
this.tileEntityType = tileEntityType;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public LazyOptional<Device> getDevice(final DeviceQuery query) {
|
||||
if (!(query instanceof BlockDeviceQuery)) {
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
final BlockDeviceQuery blockQuery = (BlockDeviceQuery) query;
|
||||
final TileEntity tileEntity = WorldUtils.getTileEntityIfChunkExists(blockQuery.getWorld(), blockQuery.getQueryPosition());
|
||||
if (!tileEntityType.isInstance(tileEntity)) {
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
return getDevice(blockQuery, (T) tileEntity);
|
||||
protected AbstractTileEntityDeviceProvider() {
|
||||
this.tileEntityType = null;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected abstract LazyOptional<Device> getDevice(final BlockDeviceQuery query, final T tileEntity);
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final LazyOptional<Device> getDevice(final BlockDeviceQuery query) {
|
||||
final TileEntity tileEntity = WorldUtils.getTileEntityIfChunkExists(query.getWorld(), query.getQueryPosition());
|
||||
if (tileEntity == null) {
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
if (tileEntityType != null && tileEntity.getType() != tileEntityType) {
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
return getBlockDevice(query, (T) tileEntity);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected abstract LazyOptional<Device> getBlockDevice(final BlockDeviceQuery query, final T tileEntity);
|
||||
}
|
||||
|
||||
@@ -24,9 +24,11 @@ public class DeviceItemStackHandler extends ItemStackHandler {
|
||||
|
||||
public DeviceItemStackHandler(final NonNullList<ItemStack> stacks) {
|
||||
super(stacks);
|
||||
this.busElement = new ItemHandlerDeviceBusElement(this);
|
||||
this.busElement = new ItemHandlerDeviceBusElement(getSlots());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public DeviceBusElement getBusElement() {
|
||||
return busElement;
|
||||
}
|
||||
@@ -42,14 +44,19 @@ public class DeviceItemStackHandler extends ItemStackHandler {
|
||||
public void deserializeNBT(final CompoundNBT nbt) {
|
||||
super.deserializeNBT(nbt);
|
||||
busElement.deserializeNBT(nbt.getList(BUS_ELEMENT_NBT_TAG_NAME, NBTTagIds.TAG_COMPOUND));
|
||||
for (int i = 0; i < getSlots(); i++) {
|
||||
busElement.handleSlotChanged(i);
|
||||
for (int slot = 0; slot < getSlots(); slot++) {
|
||||
busElement.updateDevices(slot, getStackInSlot(slot));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public boolean isItemValid(final int slot, @NotNull final ItemStack stack) {
|
||||
return super.isItemValid(slot, stack);
|
||||
public ItemStack extractItem(final int slot, final int amount, final boolean simulate) {
|
||||
if (!simulate && amount > 0) {
|
||||
busElement.handleBeforeItemRemoved(slot, getStackInSlot(slot));
|
||||
}
|
||||
|
||||
return super.extractItem(slot, amount, simulate);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,11 +64,16 @@ public class DeviceItemStackHandler extends ItemStackHandler {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValid(final int slot, @NotNull final ItemStack stack) {
|
||||
return super.isItemValid(slot, stack);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected void onContentsChanged(final int slot) {
|
||||
super.onContentsChanged(slot);
|
||||
busElement.handleSlotChanged(slot);
|
||||
busElement.updateDevices(slot, getStackInSlot(slot));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package li.cil.oc2.common.init;
|
||||
|
||||
import li.cil.oc2.api.API;
|
||||
import li.cil.oc2.api.bus.device.provider.DeviceProvider;
|
||||
import li.cil.oc2.api.bus.device.provider.BlockDeviceProvider;
|
||||
import li.cil.oc2.api.bus.device.provider.ItemDeviceProvider;
|
||||
import li.cil.oc2.common.bus.device.provider.*;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
@@ -11,25 +12,28 @@ import net.minecraftforge.registries.RegistryBuilder;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class Providers {
|
||||
private static final DeferredRegister<DeviceProvider> PROVIDERS = DeferredRegister.create(DeviceProvider.class, API.MOD_ID);
|
||||
private static final DeferredRegister<BlockDeviceProvider> BLOCK_DEVICE_PROVIDERS = DeferredRegister.create(BlockDeviceProvider.class, API.MOD_ID);
|
||||
private static final DeferredRegister<ItemDeviceProvider> ITEM_DEVICE_PROVIDERS = DeferredRegister.create(ItemDeviceProvider.class, API.MOD_ID);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static final Supplier<IForgeRegistry<DeviceProvider>> PROVIDERS_REGISTRY = PROVIDERS.makeRegistry("device_providers", RegistryBuilder::new);
|
||||
public static final Supplier<IForgeRegistry<BlockDeviceProvider>> BLOCK_DEVICE_PROVIDER_REGISTRY = BLOCK_DEVICE_PROVIDERS.makeRegistry("block_device_providers", RegistryBuilder::new);
|
||||
public static final Supplier<IForgeRegistry<ItemDeviceProvider>> ITEM_DEVICE_PROVIDER_REGISTRY = ITEM_DEVICE_PROVIDERS.makeRegistry("item_device_providers", RegistryBuilder::new);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static void initialize() {
|
||||
PROVIDERS.register("block", BlockDeviceProvider::new);
|
||||
PROVIDERS.register("tile_entity", TileEntityDeviceProvider::new);
|
||||
BLOCK_DEVICE_PROVIDERS.register("block", BlockStateDeviceProvider::new);
|
||||
BLOCK_DEVICE_PROVIDERS.register("tile_entity", TileEntityDeviceProvider::new);
|
||||
|
||||
PROVIDERS.register("energy_storage", EnergyStorageDeviceProvider::new);
|
||||
PROVIDERS.register("fluid_handler", FluidHandlerDeviceProvider::new);
|
||||
PROVIDERS.register("item_handler", ItemHandlerDeviceProvider::new);
|
||||
BLOCK_DEVICE_PROVIDERS.register("energy_storage", EnergyStorageBlockDeviceProvider::new);
|
||||
BLOCK_DEVICE_PROVIDERS.register("fluid_handler", FluidHandlerBlockDeviceProvider::new);
|
||||
BLOCK_DEVICE_PROVIDERS.register("item_handler", ItemHandlerBlockDeviceProvider::new);
|
||||
|
||||
PROVIDERS.register("item_memory", MemoryItemDeviceProvider::new);
|
||||
PROVIDERS.register("item_hard_drive", HardDriveItemDeviceProvider::new);
|
||||
ITEM_DEVICE_PROVIDERS.register("item_memory", MemoryItemDeviceProvider::new);
|
||||
ITEM_DEVICE_PROVIDERS.register("item_hard_drive", HardDriveItemDeviceProvider::new);
|
||||
|
||||
PROVIDERS.register(FMLJavaModLoadingContext.get().getModEventBus());
|
||||
BLOCK_DEVICE_PROVIDERS.register(FMLJavaModLoadingContext.get().getModEventBus());
|
||||
ITEM_DEVICE_PROVIDERS.register(FMLJavaModLoadingContext.get().getModEventBus());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ public final class Network {
|
||||
PROTOCOL_VERSION::equals
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private static int nextPacketId = 1;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -21,6 +21,8 @@ public abstract class AbstractTerminalBlockMessage {
|
||||
fromBytes(buffer);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public void fromBytes(final PacketBuffer buffer) {
|
||||
pos = buffer.readBlockPos();
|
||||
data = buffer.readByteArray();
|
||||
|
||||
@@ -24,6 +24,8 @@ public class ComputerBusStateMessage {
|
||||
fromBytes(buffer);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static boolean handleMessage(final ComputerBusStateMessage message, final Supplier<NetworkEvent.Context> context) {
|
||||
context.get().enqueueWork(() -> MessageUtils.withClientTileEntityAt(message.pos, ComputerTileEntity.class,
|
||||
(tileEntity) -> tileEntity.setBusStateClient(message.busState)));
|
||||
|
||||
@@ -23,6 +23,8 @@ public class ComputerRunStateMessage {
|
||||
fromBytes(buffer);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static boolean handleMessage(final ComputerRunStateMessage message, final Supplier<NetworkEvent.Context> context) {
|
||||
context.get().enqueueWork(() -> MessageUtils.withClientTileEntityAt(message.pos, ComputerTileEntity.class,
|
||||
(tileEntity) -> tileEntity.setRunStateClient(message.runState)));
|
||||
|
||||
@@ -17,6 +17,8 @@ public final class TerminalBlockInputMessage extends AbstractTerminalBlockMessag
|
||||
super(buffer);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static boolean handleMessage(final AbstractTerminalBlockMessage message, final Supplier<NetworkEvent.Context> context) {
|
||||
context.get().enqueueWork(() -> MessageUtils.withServerTileEntityAt(context, message.pos, ComputerTileEntity.class,
|
||||
(tileEntity) -> tileEntity.getTerminal().putInput(ByteBuffer.wrap(message.data))));
|
||||
|
||||
@@ -17,6 +17,8 @@ public final class TerminalBlockOutputMessage extends AbstractTerminalBlockMessa
|
||||
super(buffer);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static boolean handleMessage(final AbstractTerminalBlockMessage message, final Supplier<NetworkEvent.Context> context) {
|
||||
context.get().enqueueWork(() -> MessageUtils.withClientTileEntityAt(message.pos, ComputerTileEntity.class,
|
||||
tileEntity -> tileEntity.getTerminal().putOutput(ByteBuffer.wrap(message.data))));
|
||||
|
||||
@@ -9,6 +9,8 @@ import javax.annotation.Nullable;
|
||||
public final class HorizontalBlockUtils {
|
||||
public static final int HORIZONTAL_DIRECTION_COUNT = 4;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Nullable
|
||||
public static Direction toLocal(final BlockState blockState, @Nullable final Direction direction) {
|
||||
if (direction == null) {
|
||||
|
||||
49
src/main/java/li/cil/oc2/common/util/ItemDeviceUtils.java
Normal file
49
src/main/java/li/cil/oc2/common/util/ItemDeviceUtils.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package li.cil.oc2.common.util;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.registries.IForgeRegistryEntry;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class ItemDeviceUtils {
|
||||
private static final String ITEM_DEVICE_DATA_NBT_TAG_NAME = "item_device";
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static Optional<CompoundNBT> getItemDeviceData(final ItemStack stack) {
|
||||
if (stack.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
final CompoundNBT nbt = ItemStackUtils.getModDataTag(stack);
|
||||
if (nbt == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(nbt.getCompound(ITEM_DEVICE_DATA_NBT_TAG_NAME));
|
||||
}
|
||||
|
||||
public static void setItemDeviceData(final ItemStack stack, final CompoundNBT data) {
|
||||
if (data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStackUtils.getOrCreateModDataTag(stack).put(ITEM_DEVICE_DATA_NBT_TAG_NAME, data);
|
||||
}
|
||||
|
||||
public static Optional<String> getItemDeviceDataKey(@Nullable final IForgeRegistryEntry<?> provider) {
|
||||
if (provider == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
final ResourceLocation providerName = provider.getRegistryName();
|
||||
if (providerName == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(providerName.toString());
|
||||
}
|
||||
}
|
||||
26
src/main/java/li/cil/oc2/common/util/ItemStackUtils.java
Normal file
26
src/main/java/li/cil/oc2/common/util/ItemStackUtils.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package li.cil.oc2.common.util;
|
||||
|
||||
import li.cil.oc2.api.API;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class ItemStackUtils {
|
||||
@Nullable
|
||||
public static CompoundNBT getModDataTag(final ItemStack stack) {
|
||||
if (stack.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return stack.getChildTag(API.MOD_ID);
|
||||
}
|
||||
|
||||
public static CompoundNBT getOrCreateModDataTag(final ItemStack stack) {
|
||||
if (stack.isEmpty()) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
return stack.getOrCreateChildTag(API.MOD_ID);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,8 @@ public final class ManagedInterruptAllocator implements InterruptAllocator {
|
||||
this.interruptCount = interruptCount;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public void freeze() {
|
||||
isFrozen = true;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ public final class ManagedInterruptController implements InterruptController {
|
||||
this.allocator = allocator;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public void invalidate() {
|
||||
isValid = false;
|
||||
interruptController.lowerInterrupts(raisedInterrupts);
|
||||
|
||||
@@ -9,6 +9,8 @@ public final class ManagedMemoryAllocator implements MemoryAllocator {
|
||||
private final ArrayList<UUID> claimedMemory = new ArrayList<>();
|
||||
private boolean isFrozen;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public void freeze() {
|
||||
isFrozen = true;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ final class ManagedMemoryMap implements MemoryMap {
|
||||
this.memoryMap = memoryMap;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public OptionalLong findFreeRange(final long start, final long end, final int size) {
|
||||
return memoryMap.findFreeRange(start, end, size);
|
||||
|
||||
@@ -14,10 +14,14 @@ public final class ManagedMemoryRangeAllocator implements MemoryRangeAllocator {
|
||||
private final ArrayList<MemoryMappedDevice> managedDevices = new ArrayList<>();
|
||||
private boolean isFrozen;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public ManagedMemoryRangeAllocator(final Board board) {
|
||||
this.board = board;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public void freeze() {
|
||||
isFrozen = true;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ public final class ManagedVMContext implements VMContext {
|
||||
this.memoryAllocator = new ManagedMemoryAllocator();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public void freeze() {
|
||||
memoryRangeAllocator.freeze();
|
||||
interruptAllocator.freeze();
|
||||
|
||||
@@ -57,12 +57,16 @@ public final class Terminal {
|
||||
private static final byte DEFAULT_COLORS = COLOR_WHITE << COLOR_FOREGROUND_SHIFT;
|
||||
private static final byte DEFAULT_STYLE = 0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public enum State { // Must be public for serialization.
|
||||
NORMAL, // Currently reading characters normally.
|
||||
ESCAPE, // Last character was ESC, figure out what kind next.
|
||||
SEQUENCE, // Know what sequence we have, now parsing it.
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private final ByteArrayFIFOQueue input = new ByteArrayFIFOQueue(32);
|
||||
private final byte[] buffer = new byte[WIDTH * HEIGHT];
|
||||
private final byte[] colors = new byte[WIDTH * HEIGHT];
|
||||
@@ -85,10 +89,14 @@ public final class Terminal {
|
||||
private transient Object renderer;
|
||||
private transient boolean displayOnly; // Set on client to not send responses to status requests.
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public Terminal() {
|
||||
clear();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setDisplayOnly(final boolean value) {
|
||||
displayOnly = value;
|
||||
}
|
||||
@@ -331,6 +339,8 @@ public final class Terminal {
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private void selectStyle(final int sgr) {
|
||||
switch (sgr) {
|
||||
case 0: { // Reset / Normal
|
||||
@@ -476,6 +486,8 @@ public final class Terminal {
|
||||
dirty.set(-1);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private static final class Renderer {
|
||||
private static final ResourceLocation LOCATION_FONT_TEXTURE = new ResourceLocation(API.MOD_ID, "textures/font/terminus.png");
|
||||
@@ -506,15 +518,21 @@ public final class Terminal {
|
||||
0x777777, // White
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
private final Terminal terminal;
|
||||
|
||||
private final Object[] lines = new Object[HEIGHT]; // Cached vertex buffers for rendering, untyped for server.
|
||||
private Object lastMatrix; // Untyped for server.
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
public Renderer(final Terminal terminal) {
|
||||
this.terminal = terminal;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
public void render(final AtomicInteger dirty, final MatrixStack stack) {
|
||||
validateLineCache(dirty, stack);
|
||||
renderBuffer();
|
||||
@@ -524,6 +542,8 @@ public final class Terminal {
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
private void renderBuffer() {
|
||||
GlStateManager.depthMask(false);
|
||||
Minecraft.getInstance().getTextureManager().bindTexture(LOCATION_FONT_TEXTURE);
|
||||
|
||||
@@ -7,22 +7,12 @@ import li.cil.oc2.api.bus.device.vm.MemoryRangeAllocator;
|
||||
import li.cil.oc2.api.bus.device.vm.VMContext;
|
||||
import li.cil.oc2.common.bus.RPCAdapter;
|
||||
import li.cil.sedna.api.device.InterruptController;
|
||||
import li.cil.sedna.buildroot.Buildroot;
|
||||
import li.cil.sedna.device.block.ByteBufferBlockDevice;
|
||||
import li.cil.sedna.device.rtc.GoldfishRTC;
|
||||
import li.cil.sedna.device.serial.UART16550A;
|
||||
import li.cil.sedna.device.virtio.VirtIOConsoleDevice;
|
||||
import li.cil.sedna.riscv.R5Board;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class VirtualMachine {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
// We report a clock rate to the VM such that for the VM it looks as though
|
||||
// passes as much faster as MC time passes faster than real time.
|
||||
public static final int REPORTED_CPU_FREQUENCY = 700_000;
|
||||
@@ -32,19 +22,6 @@ public final class VirtualMachine {
|
||||
private static final int RTC_INTERRUPT = 0x2;
|
||||
private static final int RPC_INTERRUPT = 0x3;
|
||||
|
||||
private static final ByteBufferBlockDevice ROOT_FS;
|
||||
|
||||
static {
|
||||
ByteBufferBlockDevice rootfs;
|
||||
try {
|
||||
rootfs = ByteBufferBlockDevice.createFromStream(Buildroot.getRootFilesystem(), true);
|
||||
} catch (final IOException e) {
|
||||
LOGGER.error(e);
|
||||
rootfs = ByteBufferBlockDevice.create(0, true);
|
||||
}
|
||||
ROOT_FS = rootfs;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public final MinecraftRealTimeCounter rtc = new MinecraftRealTimeCounter();
|
||||
@@ -92,6 +69,8 @@ public final class VirtualMachine {
|
||||
board.setStandardOutputDevice(uart);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public void reset() {
|
||||
board.reset();
|
||||
rpcAdapter.reset();
|
||||
|
||||
@@ -33,6 +33,8 @@ public final class VirtualMachineDeviceBusAdapter {
|
||||
this.claimedInterrupts.set(0);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public VMContext getGlobalContext() {
|
||||
return globalContext;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ public class VirtualMachineRunner implements Runnable {
|
||||
this.board = board;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public void tick() {
|
||||
cycleLimit += getCyclesPerTick();
|
||||
if (timeQuotaInMillis.addAndGet(TIMESLICE_IN_MS) > 0 && lastSchedule == null || lastSchedule.isDone() || lastSchedule.isCancelled()) {
|
||||
|
||||
Reference in New Issue
Block a user