diff --git a/src/main/java/li/cil/oc2/common/bus/device/item/AbstractHardDriveVMDevice.java b/src/main/java/li/cil/oc2/common/bus/device/item/AbstractHardDriveVMDevice.java index b043ac01..40181b77 100644 --- a/src/main/java/li/cil/oc2/common/bus/device/item/AbstractHardDriveVMDevice.java +++ b/src/main/java/li/cil/oc2/common/bus/device/item/AbstractHardDriveVMDevice.java @@ -3,6 +3,8 @@ package li.cil.oc2.common.bus.device.item; import li.cil.oc2.api.bus.device.ItemDevice; import li.cil.oc2.api.bus.device.vm.*; import li.cil.oc2.common.bus.device.util.IdentityProxy; +import li.cil.oc2.common.bus.device.util.OptionalAddress; +import li.cil.oc2.common.bus.device.util.OptionalInterrupt; import li.cil.oc2.common.serialization.BlobStorage; import li.cil.oc2.common.serialization.NBTSerialization; import li.cil.oc2.common.util.NBTTagIds; @@ -14,8 +16,6 @@ import net.minecraft.nbt.CompoundNBT; import java.io.InputStream; import java.io.OutputStream; import java.util.Optional; -import java.util.OptionalInt; -import java.util.OptionalLong; import java.util.UUID; public abstract class AbstractHardDriveVMDevice extends IdentityProxy implements VMDevice, VMDeviceLifecycleListener, ItemDevice { @@ -33,9 +33,9 @@ public abstract class AbstractHardDriveVMDevice extends I /////////////////////////////////////////////////////////////// // Online persisted data. + private final OptionalAddress address = new OptionalAddress(); + private final OptionalInterrupt interrupt = new OptionalInterrupt(); private CompoundNBT deviceNbt; - private Long address; - private Integer interrupt; // Offline persisted data. private UUID blobHandle; @@ -54,11 +54,13 @@ public abstract class AbstractHardDriveVMDevice extends I return VMDeviceLoadResult.fail(); } - if (!claimAddress(context)) { + if (!address.claim(context, device)) { return VMDeviceLoadResult.fail(); } - if (!claimInterrupt(context)) { + if (interrupt.claim(context)) { + device.getInterrupt().set(interrupt.getAsInt(), context.getInterruptController()); + } else { return VMDeviceLoadResult.fail(); } @@ -114,11 +116,11 @@ public abstract class AbstractHardDriveVMDevice extends I if (deviceNbt != null) { nbt.put(DEVICE_NBT_TAG_NAME, deviceNbt); } - if (address != null) { - nbt.putLong(ADDRESS_NBT_TAG_NAME, address); + if (address.isPresent()) { + nbt.putLong(ADDRESS_NBT_TAG_NAME, address.getAsLong()); } - if (interrupt != null) { - nbt.putInt(INTERRUPT_NBT_TAG_NAME, interrupt); + if (interrupt.isPresent()) { + nbt.putInt(INTERRUPT_NBT_TAG_NAME, interrupt.getAsInt()); } if (blobHandle != null) { @@ -138,10 +140,10 @@ public abstract class AbstractHardDriveVMDevice extends I deviceNbt = nbt.getCompound(DEVICE_NBT_TAG_NAME); } if (nbt.contains(ADDRESS_NBT_TAG_NAME, NBTTagIds.TAG_LONG)) { - address = nbt.getLong(ADDRESS_NBT_TAG_NAME); + address.set(nbt.getLong(ADDRESS_NBT_TAG_NAME)); } if (nbt.contains(INTERRUPT_NBT_TAG_NAME, NBTTagIds.TAG_INT)) { - interrupt = nbt.getInt(INTERRUPT_NBT_TAG_NAME); + interrupt.set(nbt.getInt(INTERRUPT_NBT_TAG_NAME)); } } @@ -168,42 +170,6 @@ public abstract class AbstractHardDriveVMDevice extends I return true; } - private boolean claimAddress(final VMContext context) { - final OptionalLong claimedAddress; - if (this.address != null) { - claimedAddress = context.getMemoryRangeAllocator().claimMemoryRange(this.address, device); - } else { - claimedAddress = context.getMemoryRangeAllocator().claimMemoryRange(device); - } - - if (!claimedAddress.isPresent()) { - return false; - } - - this.address = claimedAddress.getAsLong(); - - return true; - } - - private boolean claimInterrupt(final VMContext context) { - final OptionalInt claimedInterrupt; - if (this.interrupt != null) { - claimedInterrupt = context.getInterruptAllocator().claimInterrupt(this.interrupt); - } else { - claimedInterrupt = context.getInterruptAllocator().claimInterrupt(); - } - - if (!claimedInterrupt.isPresent()) { - return false; - } - - this.interrupt = claimedInterrupt.getAsInt(); - - device.getInterrupt().set(this.interrupt, context.getInterruptController()); - - return true; - } - private void loadPersistedState() { if (blobHandle != null) { jobHandle = BlobStorage.submitLoad(blobHandle, getDeserializationStream(data)); @@ -238,11 +204,11 @@ public abstract class AbstractHardDriveVMDevice extends I } data = null; + jobHandle = null; device = null; deviceNbt = null; - address = null; - interrupt = null; - jobHandle = null; + address.clear(); + interrupt.clear(); } } diff --git a/src/main/java/li/cil/oc2/common/bus/device/item/MemoryDevice.java b/src/main/java/li/cil/oc2/common/bus/device/item/MemoryDevice.java index 6e635ed9..babe69df 100644 --- a/src/main/java/li/cil/oc2/common/bus/device/item/MemoryDevice.java +++ b/src/main/java/li/cil/oc2/common/bus/device/item/MemoryDevice.java @@ -4,6 +4,7 @@ import li.cil.oc2.api.bus.device.ItemDevice; import li.cil.oc2.api.bus.device.vm.*; import li.cil.oc2.common.Config; import li.cil.oc2.common.bus.device.util.IdentityProxy; +import li.cil.oc2.common.bus.device.util.OptionalAddress; import li.cil.oc2.common.item.MemoryItem; import li.cil.oc2.common.serialization.BlobStorage; import li.cil.oc2.common.util.NBTTagIds; @@ -15,7 +16,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.math.MathHelper; -import java.util.OptionalLong; import java.util.UUID; public final class MemoryDevice extends IdentityProxy implements VMDevice, VMDeviceLifecycleListener, ItemDevice { @@ -30,8 +30,8 @@ public final class MemoryDevice extends IdentityProxy implements VMDe /////////////////////////////////////////////////////////////// + private final OptionalAddress address = new OptionalAddress(); private UUID blobHandle; - private Long address; /////////////////////////////////////////////////////////////// @@ -48,7 +48,7 @@ public final class MemoryDevice extends IdentityProxy implements VMDe return VMDeviceLoadResult.fail(); } - if (!claimAddress(context)) { + if (!address.claim(context, device)) { return VMDeviceLoadResult.fail(); } @@ -79,8 +79,8 @@ public final class MemoryDevice extends IdentityProxy implements VMDe jobHandle = BlobStorage.submitSave(blobHandle, new PhysicalMemoryInputStream(device)); } - if (address != null) { - nbt.putLong(ADDRESS_NBT_TAG_NAME, address); + if (address.isPresent()) { + nbt.putLong(ADDRESS_NBT_TAG_NAME, address.getAsLong()); } return nbt; @@ -92,7 +92,7 @@ public final class MemoryDevice extends IdentityProxy implements VMDe blobHandle = nbt.getUniqueId(BLOB_HANDLE_NBT_TAG_NAME); } if (nbt.contains(ADDRESS_NBT_TAG_NAME, NBTTagIds.TAG_LONG)) { - address = nbt.getLong(ADDRESS_NBT_TAG_NAME); + address.set(nbt.getLong(ADDRESS_NBT_TAG_NAME)); } } @@ -108,23 +108,6 @@ public final class MemoryDevice extends IdentityProxy implements VMDe return true; } - private boolean claimAddress(final VMContext context) { - final OptionalLong claimedAddress; - if (this.address != null) { - claimedAddress = context.getMemoryRangeAllocator().claimMemoryRange(this.address, device); - } else { - claimedAddress = context.getMemoryRangeAllocator().claimMemoryRange(device); - } - - if (!claimedAddress.isPresent()) { - return false; - } - - this.address = claimedAddress.getAsLong(); - - return true; - } - private void loadPersistedState() { if (blobHandle != null) { jobHandle = BlobStorage.submitLoad(blobHandle, new PhysicalMemoryOutputStream(device)); @@ -142,9 +125,9 @@ public final class MemoryDevice extends IdentityProxy implements VMDe // Memory is volatile, so free up our persisted blob when device is unloaded. BlobStorage.freeHandle(blobHandle); blobHandle = null; + jobHandle = null; device = null; - address = null; - jobHandle = null; + address.clear(); } } diff --git a/src/main/java/li/cil/oc2/common/bus/device/util/OptionalAddress.java b/src/main/java/li/cil/oc2/common/bus/device/util/OptionalAddress.java new file mode 100644 index 00000000..209cdee1 --- /dev/null +++ b/src/main/java/li/cil/oc2/common/bus/device/util/OptionalAddress.java @@ -0,0 +1,42 @@ +package li.cil.oc2.common.bus.device.util; + +import li.cil.oc2.api.bus.device.vm.VMContext; +import li.cil.sedna.api.device.MemoryMappedDevice; + +import java.util.OptionalLong; + +public final class OptionalAddress { + private Long value; + + public boolean isPresent() { + return value != null; + } + + public long getAsLong() { + return value; + } + + public void set(final long value) { + this.value = value; + } + + public void clear() { + this.value = null; + } + + public boolean claim(final VMContext context, final MemoryMappedDevice device) { + final OptionalLong claimedAddress; + if (value == null) { + claimedAddress = context.getMemoryRangeAllocator().claimMemoryRange(device); + } else { + claimedAddress = context.getMemoryRangeAllocator().claimMemoryRange(value, device); + } + + if (claimedAddress.isPresent()) { + value = claimedAddress.getAsLong(); + return true; + } else { + return false; + } + } +} diff --git a/src/main/java/li/cil/oc2/common/bus/device/util/OptionalInterrupt.java b/src/main/java/li/cil/oc2/common/bus/device/util/OptionalInterrupt.java new file mode 100644 index 00000000..50e1e3fe --- /dev/null +++ b/src/main/java/li/cil/oc2/common/bus/device/util/OptionalInterrupt.java @@ -0,0 +1,41 @@ +package li.cil.oc2.common.bus.device.util; + +import li.cil.oc2.api.bus.device.vm.VMContext; + +import java.util.OptionalInt; + +public final class OptionalInterrupt { + private Integer value; + + public boolean isPresent() { + return value != null; + } + + public int getAsInt() { + return value; + } + + public void set(final int value) { + this.value = value; + } + + public void clear() { + this.value = null; + } + + public boolean claim(final VMContext context) { + final OptionalInt claimedInterrupt; + if (value == null) { + claimedInterrupt = context.getInterruptAllocator().claimInterrupt(); + } else { + claimedInterrupt = context.getInterruptAllocator().claimInterrupt(value); + } + + if (claimedInterrupt.isPresent()) { + value = claimedInterrupt.getAsInt(); + return true; + } else { + return false; + } + } +}