diff --git a/src/main/java/li/cil/oc2/api/bus/device/Device.java b/src/main/java/li/cil/oc2/api/bus/device/Device.java
index b01d9356..1299e880 100644
--- a/src/main/java/li/cil/oc2/api/bus/device/Device.java
+++ b/src/main/java/li/cil/oc2/api/bus/device/Device.java
@@ -2,13 +2,9 @@ package li.cil.oc2.api.bus.device;
import li.cil.oc2.api.bus.DeviceBus;
import li.cil.oc2.api.bus.DeviceBusController;
-import li.cil.oc2.api.bus.DeviceBusElement;
import net.minecraft.nbt.CompoundNBT;
import net.minecraftforge.common.util.INBTSerializable;
-import java.util.Optional;
-import java.util.UUID;
-
/**
* Base interface for objects that can be registered as devices on a {@link DeviceBus}.
*
@@ -20,22 +16,6 @@ import java.util.UUID;
* detected.
*/
public interface Device extends INBTSerializable {
- /**
- * An identifier used to associate save data with this device.
- *
- * This is required for a device to be serialized. When this returns
- * {@link Optional#empty()}, {@link #serializeNBT()} and {@link #deserializeNBT(CompoundNBT)}
- * will not be called.
- *
- * Not to be confused with the identifiers used for devices on a {@link DeviceBus},
- * which are assigned by {@link DeviceBusElement}s to the devices they contain.
- *
- * @return a stable, unique identifier for this specific device type.
- */
- default Optional getSerializationKey() {
- return Optional.empty();
- }
-
@Override
default CompoundNBT serializeNBT() {
return new CompoundNBT();
diff --git a/src/main/java/li/cil/oc2/common/bus/AbstractGroupingDeviceBusElement.java b/src/main/java/li/cil/oc2/common/bus/AbstractGroupingDeviceBusElement.java
index 03b3ff9d..cdfab82c 100644
--- a/src/main/java/li/cil/oc2/common/bus/AbstractGroupingDeviceBusElement.java
+++ b/src/main/java/li/cil/oc2/common/bus/AbstractGroupingDeviceBusElement.java
@@ -1,12 +1,15 @@
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.util.NBTTagIds;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
+import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.util.INBTSerializable;
import java.util.*;
+import java.util.stream.Collectors;
public abstract class AbstractGroupingDeviceBusElement extends AbstractDeviceBusElement implements INBTSerializable {
private static final String DEVICE_ID_NBT_TAG_NAME = "deviceId";
@@ -15,7 +18,7 @@ public abstract class AbstractGroupingDeviceBusElement extends AbstractDeviceBus
///////////////////////////////////////////////////////////////////
protected final int groupCount;
- protected final ArrayList> devicesByGroup;
+ protected final ArrayList> devicesByGroup;
///////////////////////////////////////////////////////////////////
@@ -71,8 +74,11 @@ public abstract class AbstractGroupingDeviceBusElement extends AbstractDeviceBus
@Override
public Optional getDeviceIdentifier(final Device device) {
for (int i = 0; i < groupCount; i++) {
- if (devicesByGroup.get(i).contains(device)) {
- return Optional.of(deviceIds[i]);
+ final HashSet group = devicesByGroup.get(i);
+ for (final DeviceInfo deviceInfo : group) {
+ if (Objects.equals(device, deviceInfo.device)) {
+ return Optional.of(deviceIds[i]);
+ }
}
}
return super.getDeviceIdentifier(device);
@@ -80,32 +86,31 @@ public abstract class AbstractGroupingDeviceBusElement extends AbstractDeviceBus
///////////////////////////////////////////////////////////////////
- protected void setDevicesForGroup(final int index, final HashSet newDevices) {
- final HashSet oldDevices = devicesByGroup.get(index);
+ protected void setDevicesForGroup(final int index, final HashSet newDevices) {
+ final HashSet oldDevices = devicesByGroup.get(index);
if (Objects.equals(newDevices, oldDevices)) {
return;
}
- final HashSet removedDevices = new HashSet<>(oldDevices);
+ final HashSet removedDevices = new HashSet<>(oldDevices);
removedDevices.removeAll(newDevices);
- devices.removeAll(removedDevices);
+ devices.removeAll(removedDevices.stream().map(info -> info.device).collect(Collectors.toList()));
- final HashSet addedDevices = new HashSet<>(newDevices);
+ final HashSet addedDevices = new HashSet<>(newDevices);
addedDevices.removeAll(oldDevices);
- devices.addAll(addedDevices);
+ devices.addAll(addedDevices.stream().map(info -> info.device).collect(Collectors.toList()));
oldDevices.removeAll(removedDevices);
oldDevices.addAll(newDevices);
final CompoundNBT devicesNbt = deviceData[index];
- for (final Device device : removedDevices) {
- device.getSerializationKey().ifPresent(key ->
- devicesNbt.remove(key.toString()));
+ for (final DeviceInfo deviceInfo : removedDevices) {
+ getSerializationKey(deviceInfo).ifPresent(devicesNbt::remove);
}
- for (final Device device : addedDevices) {
- device.getSerializationKey().ifPresent(key -> {
- if (devicesNbt.contains(key.toString(), NBTTagIds.TAG_COMPOUND)) {
- device.deserializeNBT(devicesNbt.getCompound(key.toString()));
+ for (final DeviceInfo deviceInfo : addedDevices) {
+ getSerializationKey(deviceInfo).ifPresent(key -> {
+ if (devicesNbt.contains(key, NBTTagIds.TAG_COMPOUND)) {
+ deviceInfo.device.deserializeNBT(devicesNbt.getCompound(key));
}
});
}
@@ -118,11 +123,24 @@ public abstract class AbstractGroupingDeviceBusElement extends AbstractDeviceBus
private void serializeDevices() {
for (int i = 0; i < groupCount; i++) {
final CompoundNBT devicesNbt = new CompoundNBT();
- for (final Device device : devicesByGroup.get(i)) {
- device.getSerializationKey().ifPresent(key ->
- devicesNbt.put(key.toString(), device.serializeNBT()));
+ 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 getSerializationKey(final DeviceInfo info) {
+ final ResourceLocation providerName = info.provider.getRegistryName();
+ if (providerName == null) {
+ return Optional.empty();
+ }
+
+ return Optional.of(providerName.toString());
+ }
}
diff --git a/src/main/java/li/cil/oc2/common/bus/ItemHandlerDeviceBusElement.java b/src/main/java/li/cil/oc2/common/bus/ItemHandlerDeviceBusElement.java
index c263c20b..f52016af 100644
--- a/src/main/java/li/cil/oc2/common/bus/ItemHandlerDeviceBusElement.java
+++ b/src/main/java/li/cil/oc2/common/bus/ItemHandlerDeviceBusElement.java
@@ -1,6 +1,6 @@
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.Devices;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.LazyOptional;
@@ -19,12 +19,12 @@ public class ItemHandlerDeviceBusElement extends AbstractGroupingDeviceBusElemen
}
public void handleSlotChanged(final int slot) {
- final HashSet newDevices = new HashSet<>();
+ final HashSet newDevices = new HashSet<>();
final ItemStack stack = handler.getStackInSlot(slot);
if (!stack.isEmpty()) {
- for (final LazyOptional device : Devices.getDevices(stack)) {
- device.ifPresent(newDevices::add);
- device.addListener(unused -> handleSlotChanged(slot));
+ for (final LazyOptional info : Devices.getDevices(stack)) {
+ info.ifPresent(newDevices::add);
+ info.addListener(unused -> handleSlotChanged(slot));
}
}
diff --git a/src/main/java/li/cil/oc2/common/bus/TileEntityDeviceBusElement.java b/src/main/java/li/cil/oc2/common/bus/TileEntityDeviceBusElement.java
index c1e5ccd0..8c6b7211 100644
--- a/src/main/java/li/cil/oc2/common/bus/TileEntityDeviceBusElement.java
+++ b/src/main/java/li/cil/oc2/common/bus/TileEntityDeviceBusElement.java
@@ -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.api.bus.device.Device;
+import li.cil.oc2.common.bus.device.DeviceInfo;
import li.cil.oc2.common.bus.device.Devices;
import li.cil.oc2.common.capabilities.Capabilities;
import li.cil.oc2.common.util.ServerScheduler;
@@ -80,11 +80,11 @@ public class TileEntityDeviceBusElement extends AbstractGroupingDeviceBusElement
final int index = direction.getIndex();
- final HashSet newDevices = new HashSet<>();
+ final HashSet newDevices = new HashSet<>();
if (canConnectToSide(direction)) {
- for (final LazyOptional device : Devices.getDevices(world, pos, direction)) {
- device.ifPresent(newDevices::add);
- device.addListener(unused -> handleNeighborChanged(pos));
+ for (final LazyOptional deviceInfo : Devices.getDevices(world, pos, direction)) {
+ deviceInfo.ifPresent(newDevices::add);
+ deviceInfo.addListener(unused -> handleNeighborChanged(pos));
}
}
diff --git a/src/main/java/li/cil/oc2/common/bus/device/AbstractHardDiskDriveDevice.java b/src/main/java/li/cil/oc2/common/bus/device/AbstractHardDiskDriveDevice.java
index 53f69961..90d19ed2 100644
--- a/src/main/java/li/cil/oc2/common/bus/device/AbstractHardDiskDriveDevice.java
+++ b/src/main/java/li/cil/oc2/common/bus/device/AbstractHardDiskDriveDevice.java
@@ -18,8 +18,6 @@ import java.util.OptionalLong;
import java.util.UUID;
public abstract class AbstractHardDiskDriveDevice extends AbstractObjectProxy implements VMDevice, VMDeviceLifecycleListener {
- private static final UUID SERIALIZATION_KEY = UUID.fromString("8842cf60-a6e6-44d2-b442-380007625078");
-
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";
@@ -78,11 +76,6 @@ public abstract class AbstractHardDiskDriveDevice extends
}
}
- @Override
- public Optional getSerializationKey() {
- return Optional.of(SERIALIZATION_KEY);
- }
-
@Override
public CompoundNBT serializeNBT() {
final CompoundNBT nbt = new CompoundNBT();
diff --git a/src/main/java/li/cil/oc2/common/bus/device/DeviceInfo.java b/src/main/java/li/cil/oc2/common/bus/device/DeviceInfo.java
new file mode 100644
index 00000000..3450df01
--- /dev/null
+++ b/src/main/java/li/cil/oc2/common/bus/device/DeviceInfo.java
@@ -0,0 +1,29 @@
+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);
+ }
+}
diff --git a/src/main/java/li/cil/oc2/common/bus/device/Devices.java b/src/main/java/li/cil/oc2/common/bus/device/Devices.java
index c196a607..893d6f09 100644
--- a/src/main/java/li/cil/oc2/common/bus/device/Devices.java
+++ b/src/main/java/li/cil/oc2/common/bus/device/Devices.java
@@ -19,7 +19,7 @@ import java.util.ArrayList;
import java.util.List;
public final class Devices {
- public static List> getDevices(final TileEntity tileEntity, final Direction side) {
+ public static List> getDevices(final TileEntity tileEntity, final Direction side) {
final World world = tileEntity.getWorld();
final BlockPos pos = tileEntity.getPos();
@@ -28,21 +28,23 @@ public final class Devices {
return getDevices(world, pos, side);
}
- public static List> getDevices(final World world, final BlockPos pos, final Direction side) {
+ public static List> getDevices(final World world, final BlockPos pos, final Direction side) {
return getDevices(new BlockQuery(world, pos, side));
}
- public static List> getDevices(final ItemStack stack) {
+ public static List> getDevices(final ItemStack stack) {
return getDevices(new ItemQuery(stack));
}
- public static List> getDevices(final DeviceQuery query) {
+ public static List> getDevices(final DeviceQuery query) {
final IForgeRegistry providers = Providers.PROVIDERS_REGISTRY.get();
- final ArrayList> devices = new ArrayList<>();
+ final ArrayList> devices = new ArrayList<>();
for (final DeviceProvider provider : providers.getValues()) {
final LazyOptional device = provider.getDevice(query);
if (device.isPresent()) {
- devices.add(device);
+ final LazyOptional info = device.lazyMap(d -> new DeviceInfo(d, provider));
+ device.addListener(unused -> info.invalidate());
+ devices.add(info);
}
}
return devices;
diff --git a/src/main/java/li/cil/oc2/common/bus/device/MemoryDevice.java b/src/main/java/li/cil/oc2/common/bus/device/MemoryDevice.java
index 70a00748..50b31e3a 100644
--- a/src/main/java/li/cil/oc2/common/bus/device/MemoryDevice.java
+++ b/src/main/java/li/cil/oc2/common/bus/device/MemoryDevice.java
@@ -12,13 +12,10 @@ import li.cil.sedna.memory.PhysicalMemoryOutputStream;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
-import java.util.Optional;
import java.util.OptionalLong;
import java.util.UUID;
public final class MemoryDevice extends AbstractObjectProxy implements VMDevice, VMDeviceLifecycleListener {
- private static final UUID SERIALIZATION_KEY = UUID.fromString("c82f8c1c-d7ff-43b0-ab44-989e1fe818bb");
-
private static final String BLOB_HANDLE_NBT_TAG_NAME = "blob";
private static final String ADDRESS_NBT_TAG_NAME = "address";
@@ -67,11 +64,6 @@ public final class MemoryDevice extends AbstractObjectProxy implement
}
}
- @Override
- public Optional getSerializationKey() {
- return Optional.of(SERIALIZATION_KEY);
- }
-
@Override
public CompoundNBT serializeNBT() {
final CompoundNBT nbt = new CompoundNBT();
diff --git a/src/main/java/li/cil/oc2/common/bus/device/provider/MemoryItemDeviceProvider.java b/src/main/java/li/cil/oc2/common/bus/device/provider/MemoryItemDeviceProvider.java
index 17906a95..63d4ddec 100644
--- a/src/main/java/li/cil/oc2/common/bus/device/provider/MemoryItemDeviceProvider.java
+++ b/src/main/java/li/cil/oc2/common/bus/device/provider/MemoryItemDeviceProvider.java
@@ -18,7 +18,4 @@ public final class MemoryItemDeviceProvider extends AbstractItemDeviceProvider {
protected LazyOptional getItemDevice(final ItemDeviceQuery query) {
return LazyOptional.of(() -> new MemoryDevice(query.getItemStack()));
}
-
- ///////////////////////////////////////////////////////////////////
-
}