diff --git a/build.gradle b/build.gradle
index a6a3dd02..b6dcccb0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -55,11 +55,11 @@ dependencies {
compileOnly 'org.jetbrains:annotations:16.0.2'
- implementation 'li.cil.oc2:oc2-sedna:0.0.1+260'
+ implementation 'li.cil.oc2:oc2-sedna:0.0.1+262'
// These three will be provided by oc2-sedna in standalone.
implementation 'li.cil.ceres:ceres:0.0.2+19'
- implementation 'li.cil.sedna:sedna:0.0.1+93'
+ implementation 'li.cil.sedna:sedna:0.0.1+95'
implementation 'li.cil.sedna:sedna-buildroot:0.0.1+10'
compileOnly fg.deobf("mezz.jei:jei-${minecraft_version}:${jei_version}:api")
diff --git a/src/main/java/li/cil/oc2/api/bus/device/vm/InterruptAllocator.java b/src/main/java/li/cil/oc2/api/bus/device/vm/InterruptAllocator.java
index 7675fc00..3c908553 100644
--- a/src/main/java/li/cil/oc2/api/bus/device/vm/InterruptAllocator.java
+++ b/src/main/java/li/cil/oc2/api/bus/device/vm/InterruptAllocator.java
@@ -13,14 +13,14 @@ import java.util.OptionalInt;
*/
public interface InterruptAllocator {
/**
- * Tries to reserve an interrupt with the specified index. The returned interrupt
- * may differ from the one provided, if the interrupt has already been claimed by
- * some other device. In this case, the result will be same as calling {@link #claimInterrupt()}.
+ * Tries to reserve an interrupt with the specified index. This may fail if the
+ * interrupt has already been claimed. Use {@link #claimInterrupt()} to obtain
+ * a free interrupt.
*
* @param interrupt the interrupt to claim.
- * @return the interrupt that was claimed, if any.
+ * @return {@code true} if the interrupt could be claimed; {@code false} otherwise.
*/
- OptionalInt claimInterrupt(int interrupt);
+ boolean claimInterrupt(int interrupt);
/**
* Tries to claim the next free interrupt. If no more interrupts are available,
diff --git a/src/main/java/li/cil/oc2/api/bus/device/vm/MemoryRangeAllocator.java b/src/main/java/li/cil/oc2/api/bus/device/vm/MemoryRangeAllocator.java
index 02031715..690929cb 100644
--- a/src/main/java/li/cil/oc2/api/bus/device/vm/MemoryRangeAllocator.java
+++ b/src/main/java/li/cil/oc2/api/bus/device/vm/MemoryRangeAllocator.java
@@ -15,21 +15,23 @@ import java.util.OptionalLong;
public interface MemoryRangeAllocator {
/**
* Tries to add a {@link MemoryMappedDevice} to the memory map at the specified
- * address. The returned address may differ from the address provided, if the
- * device cannot fit into the memory map at the specified address. In this case,
- * the result will be the same as calling {@link #claimMemoryRange(MemoryMappedDevice)}.
+ * address. This may fail if some other device is already mapped to part of the
+ * range. Use {@link #claimMemoryRange(MemoryMappedDevice)} to claim an unused
+ * memory range.
*
* @param address the address to add the specified device at.
* @param device the device to add at the specified address.
- * @return the address the device was added at, if any.
+ * @return {@code true} if the memory range could be claimed; {@code false} otherwise.
*/
- OptionalLong claimMemoryRange(long address, MemoryMappedDevice device);
+ boolean claimMemoryRange(long address, MemoryMappedDevice device);
/**
* Tries to add a {@link MemoryMappedDevice} to the memory map at an address
- * determined by the virtual machine. This may take into account the type of
- * device being added. Typically, {@link li.cil.sedna.api.device.PhysicalMemory}
- * devices will be allocated in a different memory region than regular devices.
+ * determined by the virtual machine.
+ *
+ * This may take into account the type of device being added. For example,
+ * {@link li.cil.sedna.api.device.PhysicalMemory} devices will typically be
+ * allocated in a different memory region than regular devices.
*
* If the device could not fit into the memory map at all, this will return
* {@link OptionalLong#empty()}.
diff --git a/src/main/java/li/cil/oc2/api/bus/device/vm/VMContext.java b/src/main/java/li/cil/oc2/api/bus/device/vm/VMContext.java
index 8b0d9d1a..c9cf2186 100644
--- a/src/main/java/li/cil/oc2/api/bus/device/vm/VMContext.java
+++ b/src/main/java/li/cil/oc2/api/bus/device/vm/VMContext.java
@@ -1,7 +1,6 @@
package li.cil.oc2.api.bus.device.vm;
import li.cil.oc2.api.bus.DeviceBus;
-import li.cil.oc2.api.bus.device.vm.event.VMLifecycleEventBus;
import li.cil.sedna.api.device.InterruptController;
import li.cil.sedna.api.device.MemoryMappedDevice;
import li.cil.sedna.api.memory.MemoryMap;
@@ -93,4 +92,17 @@ public interface VMContext {
* @return the event bus.
*/
VMLifecycleEventBus getEventBus();
+
+ /**
+ * Waits for the executor thread of the virtual machine to finish running.
+ *
+ * Events subscribers can only be registered inside {@link VMDevice#load(VMContext)}.
+ * Trying to register subscribers after that method has returned will result in an
+ * exception.
+ *
+ * Note that this may trigger a {@link li.cil.oc2.api.bus.device.vm.event.VMPausingEvent}
+ * if the virtual machine has not been paused before. Calling this on a paused virtual
+ * machine is a no-op.
+ */
+ void joinWorkerThread();
}
diff --git a/src/main/java/li/cil/oc2/api/bus/device/vm/VMLifecycleEventBus.java b/src/main/java/li/cil/oc2/api/bus/device/vm/VMLifecycleEventBus.java
new file mode 100644
index 00000000..7f0001c8
--- /dev/null
+++ b/src/main/java/li/cil/oc2/api/bus/device/vm/VMLifecycleEventBus.java
@@ -0,0 +1,13 @@
+package li.cil.oc2.api.bus.device.vm;
+
+/**
+ * Allows registering for {@link li.cil.oc2.api.bus.device.vm.event.VMLifecycleEvent}s.
+ */
+public interface VMLifecycleEventBus {
+ /**
+ * Registers the specified object as a subscriber for events.
+ *
+ * @param subscriber the object to subscribe methods of.
+ */
+ void register(Object subscriber);
+}
diff --git a/src/main/java/li/cil/oc2/api/bus/device/vm/event/VMLifecycleEventBus.java b/src/main/java/li/cil/oc2/api/bus/device/vm/event/VMLifecycleEventBus.java
deleted file mode 100644
index a1614531..00000000
--- a/src/main/java/li/cil/oc2/api/bus/device/vm/event/VMLifecycleEventBus.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package li.cil.oc2.api.bus.device.vm.event;
-
-public interface VMLifecycleEventBus {
- void register(Object object);
-
- void unregister(Object object);
-}
diff --git a/src/main/java/li/cil/oc2/client/gui/ComputerTerminalScreen.java b/src/main/java/li/cil/oc2/client/gui/ComputerTerminalScreen.java
index 14329aed..74cfed90 100644
--- a/src/main/java/li/cil/oc2/client/gui/ComputerTerminalScreen.java
+++ b/src/main/java/li/cil/oc2/client/gui/ComputerTerminalScreen.java
@@ -36,7 +36,7 @@ public final class ComputerTerminalScreen extends Screen {
terminalWidget.renderBackground(matrixStack, mouseX, mouseY);
super.render(matrixStack, mouseX, mouseY, partialTicks);
- terminalWidget.render(matrixStack, computer.getState().getBootError());
+ terminalWidget.render(matrixStack, computer.getVirtualMachine().getBootError());
}
@Override
@@ -95,7 +95,7 @@ public final class ComputerTerminalScreen extends Screen {
@Override
protected boolean isRunning() {
- return computer.getState().isRunning();
+ return computer.getVirtualMachine().isRunning();
}
@Override
diff --git a/src/main/java/li/cil/oc2/client/gui/RobotTerminalScreen.java b/src/main/java/li/cil/oc2/client/gui/RobotTerminalScreen.java
index 576b1aea..d7c5cb48 100644
--- a/src/main/java/li/cil/oc2/client/gui/RobotTerminalScreen.java
+++ b/src/main/java/li/cil/oc2/client/gui/RobotTerminalScreen.java
@@ -47,7 +47,7 @@ public final class RobotTerminalScreen extends ContainerScreen {
if (itemHandler.getSlots() > 0) {
diff --git a/src/main/java/li/cil/oc2/common/container/RobotContainer.java b/src/main/java/li/cil/oc2/common/container/RobotContainer.java
index c955e033..ecf5687c 100644
--- a/src/main/java/li/cil/oc2/common/container/RobotContainer.java
+++ b/src/main/java/li/cil/oc2/common/container/RobotContainer.java
@@ -2,7 +2,7 @@ package li.cil.oc2.common.container;
import li.cil.oc2.api.bus.device.DeviceTypes;
import li.cil.oc2.common.entity.RobotEntity;
-import li.cil.oc2.common.vm.VirtualMachineItemStackHandlers;
+import li.cil.oc2.common.vm.VMItemStackHandlers;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
@@ -33,7 +33,7 @@ public final class RobotContainer extends AbstractContainer {
super(Containers.ROBOT_CONTAINER.get(), id);
this.robot = robot;
- final VirtualMachineItemStackHandlers handlers = robot.getItemStackHandlers();
+ final VMItemStackHandlers handlers = robot.getItemStackHandlers();
handlers.getItemHandler(DeviceTypes.FLASH_MEMORY).ifPresent(itemHandler -> {
if (itemHandler.getSlots() > 0) {
diff --git a/src/main/java/li/cil/oc2/common/entity/RobotEntity.java b/src/main/java/li/cil/oc2/common/entity/RobotEntity.java
index 5723313f..a77d4c82 100644
--- a/src/main/java/li/cil/oc2/common/entity/RobotEntity.java
+++ b/src/main/java/li/cil/oc2/common/entity/RobotEntity.java
@@ -22,10 +22,7 @@ import li.cil.oc2.common.item.Items;
import li.cil.oc2.common.network.Network;
import li.cil.oc2.common.network.message.*;
import li.cil.oc2.common.serialization.NBTSerialization;
-import li.cil.oc2.common.util.ItemStackUtils;
-import li.cil.oc2.common.util.NBTTagIds;
-import li.cil.oc2.common.util.NBTUtils;
-import li.cil.oc2.common.util.WorldUtils;
+import li.cil.oc2.common.util.*;
import li.cil.oc2.common.vm.*;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@@ -106,7 +103,7 @@ public final class RobotEntity extends Entity implements Robot {
private final AnimationState animationState = new AnimationState();
private final RobotActionProcessor actionProcessor = new RobotActionProcessor();
private final Terminal terminal = new Terminal();
- private final RobotVirtualMachineState state;
+ private final RobotVirtualMachine virtualMachine;
private final RobotItemStackHandlers deviceItems = new RobotItemStackHandlers();
private final ItemStackHandler inventory = new FixedSizeItemStackHandler(INVENTORY_SIZE);
private final RobotBusElement busElement = new RobotBusElement();
@@ -120,8 +117,8 @@ public final class RobotEntity extends Entity implements Robot {
setNoGravity(true);
final RobotBusController busController = new RobotBusController(busElement);
- state = new RobotVirtualMachineState(busController, new CommonVirtualMachine(busController));
- state.virtualMachine.rtcMinecraft.setWorld(world);
+ virtualMachine = new RobotVirtualMachine(busController);
+ virtualMachine.state.builtinDevices.rtcMinecraft.setWorld(world);
deviceItems.busElement.addDevice(new ObjectDevice(new RobotDevice(), "robot"));
}
@@ -137,11 +134,11 @@ public final class RobotEntity extends Entity implements Robot {
return terminal;
}
- public VirtualMachineState getState() {
- return state;
+ public VirtualMachine getVirtualMachine() {
+ return virtualMachine;
}
- public VirtualMachineItemStackHandlers getItemStackHandlers() {
+ public VMItemStackHandlers getItemStackHandlers() {
return deviceItems;
}
@@ -175,7 +172,7 @@ public final class RobotEntity extends Entity implements Robot {
return optional;
}
- for (final Device device : state.busController.getDevices()) {
+ for (final Device device : virtualMachine.busController.getDevices()) {
if (device instanceof ICapabilityProvider) {
final LazyOptional value = ((ICapabilityProvider) device).getCapability(capability, side);
if (value.isPresent()) {
@@ -197,7 +194,7 @@ public final class RobotEntity extends Entity implements Robot {
return;
}
- state.start();
+ virtualMachine.start();
}
public void stop() {
@@ -206,7 +203,7 @@ public final class RobotEntity extends Entity implements Robot {
return;
}
- state.stop();
+ virtualMachine.stop();
}
public void dropSelf() {
@@ -242,7 +239,7 @@ public final class RobotEntity extends Entity implements Robot {
super.tick();
if (!isClient) {
- state.tick();
+ virtualMachine.tick();
}
actionProcessor.tick();
@@ -316,7 +313,7 @@ public final class RobotEntity extends Entity implements Robot {
handleUnload();
// Full unload to release out-of-nbt persisted runtime-only data such as ram.
- state.virtualMachine.vmAdapter.unload();
+ virtualMachine.state.vmAdapter.unload();
}
@Override
@@ -369,7 +366,7 @@ public final class RobotEntity extends Entity implements Robot {
@Override
protected void writeAdditional(final CompoundNBT tag) {
- tag.put(STATE_TAG_NAME, state.serialize());
+ tag.put(STATE_TAG_NAME, virtualMachine.serialize());
tag.put(TERMINAL_TAG_NAME, NBTSerialization.serialize(terminal));
tag.put(COMMAND_PROCESSOR_TAG_NAME, actionProcessor.serialize());
tag.put(BUS_ELEMENT_TAG_NAME, busElement.serialize());
@@ -380,7 +377,7 @@ public final class RobotEntity extends Entity implements Robot {
@Override
protected void readAdditional(final CompoundNBT tag) {
- state.deserialize(tag.getCompound(STATE_TAG_NAME));
+ virtualMachine.deserialize(tag.getCompound(STATE_TAG_NAME));
NBTSerialization.deserialize(tag.getCompound(TERMINAL_TAG_NAME), terminal);
actionProcessor.deserialize(tag.getCompound(COMMAND_PROCESSOR_TAG_NAME));
busElement.deserialize(tag.getCompound(BUS_ELEMENT_TAG_NAME));
@@ -448,9 +445,7 @@ public final class RobotEntity extends Entity implements Robot {
}
private void handleUnload() {
- state.joinVirtualMachine();
- state.virtualMachine.vmAdapter.suspend();
- state.busController.dispose();
+ virtualMachine.unload();
}
private void openTerminalScreen(final ServerPlayerEntity player) {
@@ -528,7 +523,7 @@ public final class RobotEntity extends Entity implements Robot {
public float topRenderHover = -(hashCode() & 0xFFFF); // init to "random" to avoid synchronous hovering
public void update(final float deltaTime, final Random random) {
- if (getState().isRunning() || actionProcessor.hasQueuedActions()) {
+ if (getVirtualMachine().isRunning() || actionProcessor.hasQueuedActions()) {
topRenderHover = topRenderHover + deltaTime * HOVER_ANIMATION_SPEED;
final float topOffsetY = MathHelper.sin(topRenderHover) / 32f;
@@ -696,7 +691,7 @@ public final class RobotEntity extends Entity implements Robot {
return false;
}
- if (!getState().isRunning()) {
+ if (!getVirtualMachine().isRunning()) {
return false;
}
@@ -713,7 +708,7 @@ public final class RobotEntity extends Entity implements Robot {
}
}
- private final class RobotItemStackHandlers extends AbstractVirtualMachineItemStackHandlers {
+ private final class RobotItemStackHandlers extends AbstractVMItemStackHandlers {
public RobotItemStackHandlers() {
super(
GroupDefinition.of(DeviceTypes.MEMORY, MEMORY_SLOTS),
@@ -773,53 +768,54 @@ public final class RobotEntity extends Entity implements Robot {
@Override
protected void onBeforeScan() {
- state.reload();
- state.virtualMachine.rpcAdapter.pause();
+ virtualMachine.pauseAndReload();
}
@Override
protected void onAfterDeviceScan(final boolean didDevicesChange) {
- state.virtualMachine.rpcAdapter.resume(didDevicesChange);
+ virtualMachine.resume(didDevicesChange);
}
@Override
protected void onDevicesAdded(final Collection devices) {
- state.virtualMachine.vmAdapter.addDevices(devices);
+ virtualMachine.state.vmAdapter.addDevices(devices);
}
@Override
protected void onDevicesRemoved(final Collection devices) {
- state.virtualMachine.vmAdapter.removeDevices(devices);
+ virtualMachine.state.vmAdapter.removeDevices(devices);
}
}
- private final class RobotVirtualMachineRunner extends AbstractTerminalVirtualMachineRunner {
- public RobotVirtualMachineRunner(final CommonVirtualMachine virtualMachine, final Terminal terminal) {
+ private final class RobotVMRunner extends AbstractTerminalVMRunner {
+ public RobotVMRunner(final AbstractVirtualMachine virtualMachine, final Terminal terminal) {
super(virtualMachine, terminal);
}
@Override
protected void sendTerminalUpdateToClient(final ByteBuffer output) {
- final RobotTerminalOutputMessage message = new RobotTerminalOutputMessage(RobotEntity.this, output);
- Network.sendToClientsTrackingEntity(message, RobotEntity.this);
+ Network.sendToClientsTrackingEntity(new RobotTerminalOutputMessage(RobotEntity.this, output), RobotEntity.this);
}
}
- private final class RobotVirtualMachineState extends AbstractVirtualMachineState {
- private RobotVirtualMachineState(final RobotBusController busController, final CommonVirtualMachine virtualMachine) {
- super(busController, virtualMachine);
- virtualMachine.vmAdapter.setDefaultAddressProvider(deviceItems::getDefaultDeviceAddress);
+ private final class RobotVirtualMachine extends AbstractVirtualMachine {
+ private RobotVirtualMachine(final RobotBusController busController) {
+ super(busController);
+ state.vmAdapter.setBaseAddressProvider(deviceItems::getDeviceAddressBase);
}
@Override
- protected AbstractTerminalVirtualMachineRunner createRunner() {
- return new RobotVirtualMachineRunner(virtualMachine, terminal);
+ protected AbstractTerminalVMRunner createRunner() {
+ return new RobotVMRunner(this, terminal);
}
@Override
public void stopRunnerAndReset() {
super.stopRunnerAndReset();
+ TerminalUtils.resetTerminal(terminal, output -> Network.sendToClientsTrackingEntity(
+ new RobotTerminalOutputMessage(RobotEntity.this, output), RobotEntity.this));
+
actionProcessor.clear();
}
@@ -829,7 +825,7 @@ public final class RobotEntity extends Entity implements Robot {
}
@Override
- protected void handleRunStateChanged(final RunState value) {
+ protected void handleRunStateChanged(final VMRunState value) {
Network.sendToClientsTrackingEntity(new RobotRunStateMessage(RobotEntity.this), RobotEntity.this);
}
diff --git a/src/main/java/li/cil/oc2/common/item/BusInterfaceItem.java b/src/main/java/li/cil/oc2/common/item/BusInterfaceItem.java
index 92adb67b..0a014a34 100644
--- a/src/main/java/li/cil/oc2/common/item/BusInterfaceItem.java
+++ b/src/main/java/li/cil/oc2/common/item/BusInterfaceItem.java
@@ -3,7 +3,6 @@ package li.cil.oc2.common.item;
import li.cil.oc2.common.block.Blocks;
import li.cil.oc2.common.block.BusCableBlock;
import net.minecraft.block.BlockState;
-import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemUseContext;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
diff --git a/src/main/java/li/cil/oc2/common/network/message/ComputerBootErrorMessage.java b/src/main/java/li/cil/oc2/common/network/message/ComputerBootErrorMessage.java
index a37d0d07..4fcc7f82 100644
--- a/src/main/java/li/cil/oc2/common/network/message/ComputerBootErrorMessage.java
+++ b/src/main/java/li/cil/oc2/common/network/message/ComputerBootErrorMessage.java
@@ -17,7 +17,7 @@ public final class ComputerBootErrorMessage {
public ComputerBootErrorMessage(final ComputerTileEntity tileEntity) {
this.pos = tileEntity.getPos();
- this.value = tileEntity.getState().getBootError();
+ this.value = tileEntity.getVirtualMachine().getBootError();
}
public ComputerBootErrorMessage(final PacketBuffer buffer) {
@@ -28,7 +28,7 @@ public final class ComputerBootErrorMessage {
public static boolean handleMessage(final ComputerBootErrorMessage message, final Supplier context) {
context.get().enqueueWork(() -> MessageUtils.withClientTileEntityAt(message.pos, ComputerTileEntity.class,
- (tileEntity) -> tileEntity.getState().setBootErrorClient(message.value)));
+ (tileEntity) -> tileEntity.getVirtualMachine().setBootErrorClient(message.value)));
return true;
}
diff --git a/src/main/java/li/cil/oc2/common/network/message/ComputerBusStateMessage.java b/src/main/java/li/cil/oc2/common/network/message/ComputerBusStateMessage.java
index 0bdea435..8e4e5335 100644
--- a/src/main/java/li/cil/oc2/common/network/message/ComputerBusStateMessage.java
+++ b/src/main/java/li/cil/oc2/common/network/message/ComputerBusStateMessage.java
@@ -17,7 +17,7 @@ public final class ComputerBusStateMessage {
public ComputerBusStateMessage(final ComputerTileEntity tileEntity) {
this.pos = tileEntity.getPos();
- this.value = tileEntity.getState().getBusState();
+ this.value = tileEntity.getVirtualMachine().getBusState();
}
public ComputerBusStateMessage(final PacketBuffer buffer) {
@@ -28,7 +28,7 @@ public final class ComputerBusStateMessage {
public static boolean handleMessage(final ComputerBusStateMessage message, final Supplier context) {
context.get().enqueueWork(() -> MessageUtils.withClientTileEntityAt(message.pos, ComputerTileEntity.class,
- (tileEntity) -> tileEntity.getState().setBusStateClient(message.value)));
+ (tileEntity) -> tileEntity.getVirtualMachine().setBusStateClient(message.value)));
return true;
}
diff --git a/src/main/java/li/cil/oc2/common/network/message/ComputerRunStateMessage.java b/src/main/java/li/cil/oc2/common/network/message/ComputerRunStateMessage.java
index 755217e2..edb3a5d6 100644
--- a/src/main/java/li/cil/oc2/common/network/message/ComputerRunStateMessage.java
+++ b/src/main/java/li/cil/oc2/common/network/message/ComputerRunStateMessage.java
@@ -2,7 +2,7 @@ package li.cil.oc2.common.network.message;
import li.cil.oc2.common.network.MessageUtils;
import li.cil.oc2.common.tileentity.ComputerTileEntity;
-import li.cil.oc2.common.vm.VirtualMachineState;
+import li.cil.oc2.common.vm.VMRunState;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.network.NetworkEvent;
@@ -11,13 +11,13 @@ import java.util.function.Supplier;
public final class ComputerRunStateMessage {
private BlockPos pos;
- private VirtualMachineState.RunState value;
+ private VMRunState value;
///////////////////////////////////////////////////////////////////
public ComputerRunStateMessage(final ComputerTileEntity tileEntity) {
this.pos = tileEntity.getPos();
- this.value = tileEntity.getState().getRunState();
+ this.value = tileEntity.getVirtualMachine().getRunState();
}
public ComputerRunStateMessage(final PacketBuffer buffer) {
@@ -28,13 +28,13 @@ public final class ComputerRunStateMessage {
public static boolean handleMessage(final ComputerRunStateMessage message, final Supplier context) {
context.get().enqueueWork(() -> MessageUtils.withClientTileEntityAt(message.pos, ComputerTileEntity.class,
- (tileEntity) -> tileEntity.getState().setRunStateClient(message.value)));
+ (tileEntity) -> tileEntity.getVirtualMachine().setRunStateClient(message.value)));
return true;
}
public void fromBytes(final PacketBuffer buffer) {
pos = buffer.readBlockPos();
- value = buffer.readEnumValue(VirtualMachineState.RunState.class);
+ value = buffer.readEnumValue(VMRunState.class);
}
public static void toBytes(final ComputerRunStateMessage message, final PacketBuffer buffer) {
diff --git a/src/main/java/li/cil/oc2/common/network/message/RobotBootErrorMessage.java b/src/main/java/li/cil/oc2/common/network/message/RobotBootErrorMessage.java
index e1e7e555..56529752 100644
--- a/src/main/java/li/cil/oc2/common/network/message/RobotBootErrorMessage.java
+++ b/src/main/java/li/cil/oc2/common/network/message/RobotBootErrorMessage.java
@@ -16,7 +16,7 @@ public final class RobotBootErrorMessage {
public RobotBootErrorMessage(final RobotEntity robot) {
this.entityId = robot.getEntityId();
- this.value = robot.getState().getBootError();
+ this.value = robot.getVirtualMachine().getBootError();
}
public RobotBootErrorMessage(final PacketBuffer buffer) {
@@ -27,7 +27,7 @@ public final class RobotBootErrorMessage {
public static boolean handleMessage(final RobotBootErrorMessage message, final Supplier context) {
context.get().enqueueWork(() -> MessageUtils.withClientEntity(message.entityId, RobotEntity.class,
- (robot) -> robot.getState().setBootErrorClient(message.value)));
+ (robot) -> robot.getVirtualMachine().setBootErrorClient(message.value)));
return true;
}
diff --git a/src/main/java/li/cil/oc2/common/network/message/RobotBusStateMessage.java b/src/main/java/li/cil/oc2/common/network/message/RobotBusStateMessage.java
index d6cdf62f..91eb9b67 100644
--- a/src/main/java/li/cil/oc2/common/network/message/RobotBusStateMessage.java
+++ b/src/main/java/li/cil/oc2/common/network/message/RobotBusStateMessage.java
@@ -16,7 +16,7 @@ public final class RobotBusStateMessage {
public RobotBusStateMessage(final RobotEntity robot) {
this.entityId = robot.getEntityId();
- this.value = robot.getState().getBusState();
+ this.value = robot.getVirtualMachine().getBusState();
}
public RobotBusStateMessage(final PacketBuffer buffer) {
@@ -27,7 +27,7 @@ public final class RobotBusStateMessage {
public static boolean handleMessage(final RobotBusStateMessage message, final Supplier context) {
context.get().enqueueWork(() -> MessageUtils.withClientEntity(message.entityId, RobotEntity.class,
- (robot) -> robot.getState().setBusStateClient(message.value)));
+ (robot) -> robot.getVirtualMachine().setBusStateClient(message.value)));
return true;
}
diff --git a/src/main/java/li/cil/oc2/common/network/message/RobotInitializationMessage.java b/src/main/java/li/cil/oc2/common/network/message/RobotInitializationMessage.java
index 96c16700..193a826f 100644
--- a/src/main/java/li/cil/oc2/common/network/message/RobotInitializationMessage.java
+++ b/src/main/java/li/cil/oc2/common/network/message/RobotInitializationMessage.java
@@ -4,7 +4,7 @@ import li.cil.oc2.common.bus.AbstractDeviceBusController;
import li.cil.oc2.common.entity.RobotEntity;
import li.cil.oc2.common.network.MessageUtils;
import li.cil.oc2.common.serialization.NBTSerialization;
-import li.cil.oc2.common.vm.VirtualMachineState;
+import li.cil.oc2.common.vm.VMRunState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.text.ITextComponent;
@@ -15,7 +15,7 @@ import java.util.function.Supplier;
public final class RobotInitializationMessage {
private int entityId;
private AbstractDeviceBusController.BusState busState;
- private VirtualMachineState.RunState runState;
+ private VMRunState runState;
private ITextComponent bootError;
private CompoundNBT terminal;
@@ -23,9 +23,9 @@ public final class RobotInitializationMessage {
public RobotInitializationMessage(final RobotEntity robot) {
this.entityId = robot.getEntityId();
- this.busState = robot.getState().getBusState();
- this.runState = robot.getState().getRunState();
- this.bootError = robot.getState().getBootError();
+ this.busState = robot.getVirtualMachine().getBusState();
+ this.runState = robot.getVirtualMachine().getRunState();
+ this.bootError = robot.getVirtualMachine().getBootError();
this.terminal = NBTSerialization.serialize(robot.getTerminal());
}
@@ -38,9 +38,9 @@ public final class RobotInitializationMessage {
public static boolean handleMessage(final RobotInitializationMessage message, final Supplier context) {
context.get().enqueueWork(() -> MessageUtils.withClientEntity(message.entityId, RobotEntity.class,
(robot) -> {
- robot.getState().setBusStateClient(message.busState);
- robot.getState().setRunStateClient(message.runState);
- robot.getState().setBootErrorClient(message.bootError);
+ robot.getVirtualMachine().setBusStateClient(message.busState);
+ robot.getVirtualMachine().setRunStateClient(message.runState);
+ robot.getVirtualMachine().setBootErrorClient(message.bootError);
NBTSerialization.deserialize(message.terminal, robot.getTerminal());
}));
return true;
@@ -49,7 +49,7 @@ public final class RobotInitializationMessage {
public void fromBytes(final PacketBuffer buffer) {
entityId = buffer.readVarInt();
busState = buffer.readEnumValue(AbstractDeviceBusController.BusState.class);
- runState = buffer.readEnumValue(VirtualMachineState.RunState.class);
+ runState = buffer.readEnumValue(VMRunState.class);
bootError = buffer.readTextComponent();
terminal = buffer.readCompoundTag();
}
diff --git a/src/main/java/li/cil/oc2/common/network/message/RobotRunStateMessage.java b/src/main/java/li/cil/oc2/common/network/message/RobotRunStateMessage.java
index d2ec7c02..c2c192f3 100644
--- a/src/main/java/li/cil/oc2/common/network/message/RobotRunStateMessage.java
+++ b/src/main/java/li/cil/oc2/common/network/message/RobotRunStateMessage.java
@@ -2,7 +2,7 @@ package li.cil.oc2.common.network.message;
import li.cil.oc2.common.entity.RobotEntity;
import li.cil.oc2.common.network.MessageUtils;
-import li.cil.oc2.common.vm.VirtualMachineState;
+import li.cil.oc2.common.vm.VMRunState;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.network.NetworkEvent;
@@ -10,13 +10,13 @@ import java.util.function.Supplier;
public final class RobotRunStateMessage {
private int entityId;
- private VirtualMachineState.RunState value;
+ private VMRunState value;
///////////////////////////////////////////////////////////////////
public RobotRunStateMessage(final RobotEntity robot) {
this.entityId = robot.getEntityId();
- this.value = robot.getState().getRunState();
+ this.value = robot.getVirtualMachine().getRunState();
}
public RobotRunStateMessage(final PacketBuffer buffer) {
@@ -27,13 +27,13 @@ public final class RobotRunStateMessage {
public static boolean handleMessage(final RobotRunStateMessage message, final Supplier context) {
context.get().enqueueWork(() -> MessageUtils.withClientEntity(message.entityId, RobotEntity.class,
- (robot) -> robot.getState().setRunStateClient(message.value)));
+ (robot) -> robot.getVirtualMachine().setRunStateClient(message.value)));
return true;
}
public void fromBytes(final PacketBuffer buffer) {
entityId = buffer.readVarInt();
- value = buffer.readEnumValue(VirtualMachineState.RunState.class);
+ value = buffer.readEnumValue(VMRunState.class);
}
public static void toBytes(final RobotRunStateMessage message, final PacketBuffer buffer) {
diff --git a/src/main/java/li/cil/oc2/common/serialization/serializers/MemoryRangeListSerializer.java b/src/main/java/li/cil/oc2/common/serialization/serializers/MemoryRangeListSerializer.java
new file mode 100644
index 00000000..50cd0f33
--- /dev/null
+++ b/src/main/java/li/cil/oc2/common/serialization/serializers/MemoryRangeListSerializer.java
@@ -0,0 +1,43 @@
+package li.cil.oc2.common.serialization.serializers;
+
+import li.cil.ceres.api.DeserializationVisitor;
+import li.cil.ceres.api.SerializationException;
+import li.cil.ceres.api.SerializationVisitor;
+import li.cil.ceres.api.Serializer;
+import li.cil.oc2.common.vm.context.global.MemoryRangeList;
+import li.cil.sedna.api.memory.MemoryRange;
+
+import javax.annotation.Nullable;
+import java.util.Arrays;
+
+public final class MemoryRangeListSerializer implements Serializer {
+ @Override
+ public void serialize(final SerializationVisitor visitor, final Class type, final Object value) throws SerializationException {
+ final MemoryRangeList list = (MemoryRangeList) value;
+ visitor.putObject("value", MemoryRange[].class, list.toArray(new MemoryRange[0]));
+ }
+
+ @Nullable
+ @Override
+ public MemoryRangeList deserialize(final DeserializationVisitor visitor, final Class type, @Nullable final Object value) throws SerializationException {
+ MemoryRangeList list = (MemoryRangeList) value;
+ if (!visitor.exists("value")) {
+ return list;
+ }
+
+ final MemoryRange[] array = (MemoryRange[]) visitor.getObject("value", MemoryRange[].class, null);
+ if (array == null) {
+ return null;
+ }
+
+ if (list == null) {
+ list = new MemoryRangeList();
+ } else {
+ list.clear();
+ }
+
+ list.addAll(Arrays.asList(array));
+
+ return list;
+ }
+}
diff --git a/src/main/java/li/cil/oc2/common/serialization/serializers/MemoryRangeSerializer.java b/src/main/java/li/cil/oc2/common/serialization/serializers/MemoryRangeSerializer.java
new file mode 100644
index 00000000..5acd41c9
--- /dev/null
+++ b/src/main/java/li/cil/oc2/common/serialization/serializers/MemoryRangeSerializer.java
@@ -0,0 +1,26 @@
+package li.cil.oc2.common.serialization.serializers;
+
+import li.cil.ceres.api.DeserializationVisitor;
+import li.cil.ceres.api.SerializationException;
+import li.cil.ceres.api.SerializationVisitor;
+import li.cil.ceres.api.Serializer;
+import li.cil.sedna.api.memory.MemoryRange;
+import org.jetbrains.annotations.Nullable;
+
+public final class MemoryRangeSerializer implements Serializer {
+ @Override
+ public void serialize(final SerializationVisitor visitor, final Class type, final Object value) throws SerializationException {
+ final MemoryRange range = (MemoryRange) value;
+ visitor.putLong("start", range.start);
+ visitor.putLong("end", range.end);
+ }
+
+ @Override
+ public MemoryRange deserialize(final DeserializationVisitor visitor, final Class type, @Nullable final Object value) throws SerializationException {
+ if (!visitor.exists("start") || !visitor.exists("end")) {
+ return (MemoryRange) value;
+ }
+
+ return MemoryRange.of(visitor.getLong("start"), visitor.getLong("end"));
+ }
+}
diff --git a/src/main/java/li/cil/oc2/common/serialization/serializers/MessageJsonDeserializer.java b/src/main/java/li/cil/oc2/common/serialization/serializers/MessageJsonDeserializer.java
index 1e1431bb..f90efdb5 100644
--- a/src/main/java/li/cil/oc2/common/serialization/serializers/MessageJsonDeserializer.java
+++ b/src/main/java/li/cil/oc2/common/serialization/serializers/MessageJsonDeserializer.java
@@ -1,35 +1,35 @@
package li.cil.oc2.common.serialization.serializers;
import com.google.gson.*;
-import li.cil.oc2.common.bus.RPCAdapter;
+import li.cil.oc2.common.bus.RPCDeviceBusAdapter;
import java.lang.reflect.Type;
import java.util.UUID;
-public final class MessageJsonDeserializer implements JsonDeserializer {
+public final class MessageJsonDeserializer implements JsonDeserializer {
@Override
- public RPCAdapter.Message deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
+ public RPCDeviceBusAdapter.Message deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
final JsonObject jsonObject = json.getAsJsonObject();
final String messageType = jsonObject.get("type").getAsString();
final Object messageData;
switch (messageType) {
- case RPCAdapter.Message.MESSAGE_TYPE_LIST: {
+ case RPCDeviceBusAdapter.Message.MESSAGE_TYPE_LIST: {
messageData = null;
break;
}
- case RPCAdapter.Message.MESSAGE_TYPE_METHODS: {
+ case RPCDeviceBusAdapter.Message.MESSAGE_TYPE_METHODS: {
messageData = UUID.fromString(jsonObject.getAsJsonPrimitive("data").getAsString());
break;
}
- case RPCAdapter.Message.MESSAGE_TYPE_INVOKE_METHOD: {
- messageData = context.deserialize(jsonObject.getAsJsonObject("data"), RPCAdapter.MethodInvocation.class);
+ case RPCDeviceBusAdapter.Message.MESSAGE_TYPE_INVOKE_METHOD: {
+ messageData = context.deserialize(jsonObject.getAsJsonObject("data"), RPCDeviceBusAdapter.MethodInvocation.class);
break;
}
default: {
- throw new JsonParseException(RPCAdapter.ERROR_UNKNOWN_MESSAGE_TYPE);
+ throw new JsonParseException(RPCDeviceBusAdapter.ERROR_UNKNOWN_MESSAGE_TYPE);
}
}
- return new RPCAdapter.Message(messageType, messageData);
+ return new RPCDeviceBusAdapter.Message(messageType, messageData);
}
}
diff --git a/src/main/java/li/cil/oc2/common/serialization/serializers/MethodInvocationJsonDeserializer.java b/src/main/java/li/cil/oc2/common/serialization/serializers/MethodInvocationJsonDeserializer.java
index 7e252239..0d3d70f7 100644
--- a/src/main/java/li/cil/oc2/common/serialization/serializers/MethodInvocationJsonDeserializer.java
+++ b/src/main/java/li/cil/oc2/common/serialization/serializers/MethodInvocationJsonDeserializer.java
@@ -1,18 +1,18 @@
package li.cil.oc2.common.serialization.serializers;
import com.google.gson.*;
-import li.cil.oc2.common.bus.RPCAdapter;
+import li.cil.oc2.common.bus.RPCDeviceBusAdapter;
import java.lang.reflect.Type;
import java.util.UUID;
-public final class MethodInvocationJsonDeserializer implements JsonDeserializer {
+public final class MethodInvocationJsonDeserializer implements JsonDeserializer {
@Override
- public RPCAdapter.MethodInvocation deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
+ public RPCDeviceBusAdapter.MethodInvocation deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
final JsonObject jsonObject = json.getAsJsonObject();
final UUID deviceId = context.deserialize(jsonObject.get("deviceId"), UUID.class);
final String methodName = jsonObject.get("name").getAsString();
final JsonElement parameters = jsonObject.get("parameters");
- return new RPCAdapter.MethodInvocation(deviceId, methodName, parameters != null && parameters.isJsonArray() ? parameters.getAsJsonArray() : new JsonArray());
+ return new RPCDeviceBusAdapter.MethodInvocation(deviceId, methodName, parameters != null && parameters.isJsonArray() ? parameters.getAsJsonArray() : new JsonArray());
}
}
diff --git a/src/main/java/li/cil/oc2/common/serialization/serializers/RPCDeviceWithIdentifierJsonSerializer.java b/src/main/java/li/cil/oc2/common/serialization/serializers/RPCDeviceWithIdentifierJsonSerializer.java
index 2b66ed0c..97afc7ba 100644
--- a/src/main/java/li/cil/oc2/common/serialization/serializers/RPCDeviceWithIdentifierJsonSerializer.java
+++ b/src/main/java/li/cil/oc2/common/serialization/serializers/RPCDeviceWithIdentifierJsonSerializer.java
@@ -1,13 +1,13 @@
package li.cil.oc2.common.serialization.serializers;
import com.google.gson.*;
-import li.cil.oc2.common.bus.RPCAdapter;
+import li.cil.oc2.common.bus.RPCDeviceBusAdapter;
import java.lang.reflect.Type;
-public final class RPCDeviceWithIdentifierJsonSerializer implements JsonSerializer {
+public final class RPCDeviceWithIdentifierJsonSerializer implements JsonSerializer {
@Override
- public JsonElement serialize(final RPCAdapter.RPCDeviceWithIdentifier src, final Type typeOfSrc, final JsonSerializationContext context) {
+ public JsonElement serialize(final RPCDeviceBusAdapter.RPCDeviceWithIdentifier src, final Type typeOfSrc, final JsonSerializationContext context) {
if (src == null) {
return JsonNull.INSTANCE;
}
diff --git a/src/main/java/li/cil/oc2/common/serialization/serializers/Serializers.java b/src/main/java/li/cil/oc2/common/serialization/serializers/Serializers.java
index f3897b9b..98e8a5f0 100644
--- a/src/main/java/li/cil/oc2/common/serialization/serializers/Serializers.java
+++ b/src/main/java/li/cil/oc2/common/serialization/serializers/Serializers.java
@@ -2,6 +2,8 @@ package li.cil.oc2.common.serialization.serializers;
import com.google.gson.JsonArray;
import li.cil.ceres.Ceres;
+import li.cil.oc2.common.vm.context.global.MemoryRangeList;
+import li.cil.sedna.api.memory.MemoryRange;
import net.minecraft.util.text.ITextComponent;
public final class Serializers {
@@ -20,5 +22,7 @@ public final class Serializers {
Ceres.putSerializer(JsonArray.class, new JsonArraySerializer());
Ceres.putSerializer(ITextComponent.class, new TextComponentSerializer());
+ Ceres.putSerializer(MemoryRange.class, new MemoryRangeSerializer());
+ Ceres.putSerializer(MemoryRangeList.class, new MemoryRangeListSerializer());
}
}
diff --git a/src/main/java/li/cil/oc2/common/tileentity/BusCableTileEntity.java b/src/main/java/li/cil/oc2/common/tileentity/BusCableTileEntity.java
index 68c3eeb4..41290bfe 100644
--- a/src/main/java/li/cil/oc2/common/tileentity/BusCableTileEntity.java
+++ b/src/main/java/li/cil/oc2/common/tileentity/BusCableTileEntity.java
@@ -51,7 +51,7 @@ public final class BusCableTileEntity extends AbstractTileEntity {
@Override
public void read(final BlockState state, final CompoundNBT tag) {
super.read(state, tag);
- if (tag.contains(BUS_ELEMENT_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
+ if (tag.contains(BUS_ELEMENT_TAG_NAME, NBTTagIds.TAG_LIST)) {
busElement.deserializeNBT(tag.getList(BUS_ELEMENT_TAG_NAME, NBTTagIds.TAG_COMPOUND));
}
}
diff --git a/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java b/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java
index db8de2d1..6a09128d 100644
--- a/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java
+++ b/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java
@@ -22,6 +22,7 @@ import li.cil.oc2.common.serialization.NBTSerialization;
import li.cil.oc2.common.util.HorizontalBlockUtils;
import li.cil.oc2.common.util.ItemStackUtils;
import li.cil.oc2.common.util.NBTTagIds;
+import li.cil.oc2.common.util.TerminalUtils;
import li.cil.oc2.common.vm.*;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
@@ -61,9 +62,8 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
private final Terminal terminal = new Terminal();
private final TileEntityDeviceBusElement busElement = new ComputerBusElement();
-
- private final ComputerVirtualMachineState state;
private final ComputerItemStackHandlers items = new ComputerItemStackHandlers();
+ private final ComputerVirtualMachine virtualMachine = new ComputerVirtualMachine(new ComputerBusController(busElement), items::getDeviceAddressBase);
///////////////////////////////////////////////////////////////////
@@ -72,20 +72,17 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
// We want to unload devices even on world unload to free global resources.
setNeedsWorldUnloadEvent();
-
- final ComputerBusController busController = new ComputerBusController(busElement);
- state = new ComputerVirtualMachineState(busController, new CommonVirtualMachine(busController));
}
public Terminal getTerminal() {
return terminal;
}
- public VirtualMachineState getState() {
- return state;
+ public VirtualMachine getVirtualMachine() {
+ return virtualMachine;
}
- public VirtualMachineItemStackHandlers getItemStackHandlers() {
+ public VMItemStackHandlers getItemStackHandlers() {
return items;
}
@@ -95,7 +92,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
return;
}
- state.start();
+ virtualMachine.start();
}
public void stop() {
@@ -104,11 +101,11 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
return;
}
- state.stop();
+ virtualMachine.stop();
}
public void handleNeighborChanged() {
- state.busController.scheduleBusScan();
+ virtualMachine.busController.scheduleBusScan();
}
@Override
@@ -123,7 +120,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
}
final Direction localSide = HorizontalBlockUtils.toLocal(getBlockState(), side);
- for (final Device device : state.busController.getDevices()) {
+ for (final Device device : virtualMachine.busController.getDevices()) {
if (device instanceof ICapabilityProvider) {
final LazyOptional value = ((ICapabilityProvider) device).getCapability(capability, localSide);
if (value.isPresent()) {
@@ -156,17 +153,17 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
world.notifyNeighborsOfStateChange(getPos(), getBlockState().getBlock());
}
- state.tick();
+ virtualMachine.tick();
}
@Override
public void remove() {
super.remove();
- // Unload only suspends, but we want to do a full clean-up when we get
- // destroyed, so stuff inside us can delete out-of-nbt persisted runtime-
- // only data such as ram.
- state.virtualMachine.vmAdapter.unload();
+ // super.remove() calls onUnload. This in turn only suspends, but we want to do
+ // a full clean-up when we get destroyed, so stuff inside us can delete out-of-nbt
+ // persisted runtime-only data such as ram.
+ virtualMachine.state.vmAdapter.unload();
}
@Override
@@ -174,9 +171,9 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
final CompoundNBT tag = super.getUpdateTag();
tag.put(TERMINAL_TAG_NAME, NBTSerialization.serialize(terminal));
- tag.putInt(AbstractVirtualMachineState.BUS_STATE_TAG_NAME, state.getBusState().ordinal());
- tag.putInt(AbstractVirtualMachineState.RUN_STATE_TAG_NAME, state.getRunState().ordinal());
- tag.putString(AbstractVirtualMachineState.BOOT_ERROR_TAG_NAME, ITextComponent.Serializer.toJson(state.getBootError()));
+ tag.putInt(AbstractVirtualMachine.BUS_STATE_TAG_NAME, virtualMachine.getBusState().ordinal());
+ tag.putInt(AbstractVirtualMachine.RUN_STATE_TAG_NAME, virtualMachine.getRunState().ordinal());
+ tag.putString(AbstractVirtualMachine.BOOT_ERROR_TAG_NAME, ITextComponent.Serializer.toJson(virtualMachine.getBootError()));
return tag;
}
@@ -186,16 +183,16 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
super.handleUpdateTag(blockState, tag);
NBTSerialization.deserialize(tag.getCompound(TERMINAL_TAG_NAME), terminal);
- state.setBusStateClient(AbstractDeviceBusController.BusState.values()[tag.getInt(AbstractVirtualMachineState.BUS_STATE_TAG_NAME)]);
- state.setRunStateClient(VirtualMachineState.RunState.values()[tag.getInt(AbstractVirtualMachineState.RUN_STATE_TAG_NAME)]);
- state.setBootErrorClient(ITextComponent.Serializer.getComponentFromJson(tag.getString(AbstractVirtualMachineState.BOOT_ERROR_TAG_NAME)));
+ virtualMachine.setBusStateClient(AbstractDeviceBusController.BusState.values()[tag.getInt(AbstractVirtualMachine.BUS_STATE_TAG_NAME)]);
+ virtualMachine.setRunStateClient(VMRunState.values()[tag.getInt(AbstractVirtualMachine.RUN_STATE_TAG_NAME)]);
+ virtualMachine.setBootErrorClient(ITextComponent.Serializer.getComponentFromJson(tag.getString(AbstractVirtualMachine.BOOT_ERROR_TAG_NAME)));
}
@Override
public CompoundNBT write(CompoundNBT tag) {
tag = super.write(tag);
- tag.put(STATE_TAG_NAME, state.serialize());
+ tag.put(STATE_TAG_NAME, virtualMachine.serialize());
tag.put(TERMINAL_TAG_NAME, NBTSerialization.serialize(terminal));
tag.put(BUS_ELEMENT_TAG_NAME, NBTSerialization.serialize(busElement));
tag.put(Constants.INVENTORY_TAG_NAME, items.serialize());
@@ -207,7 +204,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
public void read(final BlockState blockState, final CompoundNBT tag) {
super.read(blockState, tag);
- state.deserialize(tag.getCompound(STATE_TAG_NAME));
+ virtualMachine.deserialize(tag.getCompound(STATE_TAG_NAME));
NBTSerialization.deserialize(tag.getCompound(TERMINAL_TAG_NAME), terminal);
if (tag.contains(BUS_ELEMENT_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
@@ -243,26 +240,26 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
super.loadServer();
busElement.initialize();
- state.virtualMachine.rtcMinecraft.setWorld(getWorld());
+ virtualMachine.state.builtinDevices.rtcMinecraft.setWorld(getWorld());
}
@Override
protected void unloadServer() {
super.unloadServer();
- state.joinVirtualMachine();
- state.virtualMachine.vmAdapter.suspend();
-
- state.busController.dispose();
+ virtualMachine.unload();
// This is necessary in case some other controller found us before our controller
- // did its scan, which can happen because the scan can happen with a delay.
+ // did its scan, which can happen because the scan can happen with a delay. In
+ // that case we don't know that controller and disposing our controller won't
+ // notify it, so we also send out a notification through our bus element, which
+ // would be registered with other controllers in that case.
busElement.scheduleScan();
}
///////////////////////////////////////////////////////////////////
- private final class ComputerItemStackHandlers extends AbstractVirtualMachineItemStackHandlers {
+ private final class ComputerItemStackHandlers extends AbstractVMItemStackHandlers {
public ComputerItemStackHandlers() {
super(
GroupDefinition.of(DeviceTypes.MEMORY, MEMORY_SLOTS),
@@ -292,23 +289,22 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
@Override
protected void onBeforeScan() {
- state.reload();
- state.virtualMachine.rpcAdapter.pause();
+ virtualMachine.pauseAndReload();
}
@Override
protected void onAfterDeviceScan(final boolean didDevicesChange) {
- state.virtualMachine.rpcAdapter.resume(didDevicesChange);
+ virtualMachine.resume(didDevicesChange);
}
@Override
protected void onDevicesAdded(final Collection devices) {
- state.virtualMachine.vmAdapter.addDevices(devices);
+ virtualMachine.state.vmAdapter.addDevices(devices);
}
@Override
protected void onDevicesRemoved(final Collection devices) {
- state.virtualMachine.vmAdapter.removeDevices(devices);
+ virtualMachine.state.vmAdapter.removeDevices(devices);
}
}
@@ -332,24 +328,24 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
}
}
- private final class ComputerVirtualMachineRunner extends AbstractTerminalVirtualMachineRunner {
- public ComputerVirtualMachineRunner(final CommonVirtualMachine virtualMachine, final Terminal terminal) {
+ private final class ComputerVMRunner extends AbstractTerminalVMRunner {
+ public ComputerVMRunner(final AbstractVirtualMachine virtualMachine, final Terminal terminal) {
super(virtualMachine, terminal);
}
@Override
protected void sendTerminalUpdateToClient(final ByteBuffer output) {
- final ComputerTerminalOutputMessage message = new ComputerTerminalOutputMessage(ComputerTileEntity.this, output);
- Network.sendToClientsTrackingChunk(message, state.chunk);
+ Network.sendToClientsTrackingChunk(new ComputerTerminalOutputMessage(ComputerTileEntity.this, output), virtualMachine.chunk);
}
}
- private final class ComputerVirtualMachineState extends AbstractVirtualMachineState {
+ private final class ComputerVirtualMachine extends AbstractVirtualMachine {
private Chunk chunk;
- private ComputerVirtualMachineState(final ComputerBusController busController, final CommonVirtualMachine virtualMachine) {
- super(busController, virtualMachine);
- virtualMachine.vmAdapter.setDefaultAddressProvider(items::getDefaultDeviceAddress);
+ private ComputerVirtualMachine(final AbstractDeviceBusController busController, final BaseAddressProvider baseAddressProvider) {
+ super(busController);
+ state.vmAdapter.setBaseAddressProvider(baseAddressProvider);
+ state.board.setStandardOutputDevice(state.builtinDevices.uart);
}
@Override
@@ -366,8 +362,16 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
}
@Override
- protected AbstractTerminalVirtualMachineRunner createRunner() {
- return new ComputerVirtualMachineRunner(virtualMachine, terminal);
+ public void stopRunnerAndReset() {
+ super.stopRunnerAndReset();
+
+ TerminalUtils.resetTerminal(terminal, output -> Network.sendToClientsTrackingChunk(
+ new ComputerTerminalOutputMessage(ComputerTileEntity.this, output), virtualMachine.chunk));
+ }
+
+ @Override
+ protected AbstractTerminalVMRunner createRunner() {
+ return new ComputerVMRunner(this, terminal);
}
@Override
@@ -382,7 +386,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
}
@Override
- protected void handleRunStateChanged(final RunState value) {
+ protected void handleRunStateChanged(final VMRunState value) {
// This method can be called from disposal logic, so if we are disposed quickly enough
// chunk may not be initialized yet. Avoid resulting NRE in network logic.
if (chunk != null) {
diff --git a/src/main/java/li/cil/oc2/common/tileentity/DiskDriveTileEntity.java b/src/main/java/li/cil/oc2/common/tileentity/DiskDriveTileEntity.java
index 803e5c10..39a83ea4 100644
--- a/src/main/java/li/cil/oc2/common/tileentity/DiskDriveTileEntity.java
+++ b/src/main/java/li/cil/oc2/common/tileentity/DiskDriveTileEntity.java
@@ -1,7 +1,9 @@
package li.cil.oc2.common.tileentity;
import li.cil.oc2.api.bus.device.data.BlockDeviceData;
+import li.cil.oc2.api.bus.device.vm.VMContext;
import li.cil.oc2.api.bus.device.vm.VMDevice;
+import li.cil.oc2.api.bus.device.vm.VMDeviceLoadResult;
import li.cil.oc2.common.Config;
import li.cil.oc2.common.Constants;
import li.cil.oc2.common.block.DiskDriveBlock;
@@ -186,6 +188,8 @@ public final class DiskDriveTileEntity extends AbstractTileEntity {
}
private final class DiskDriveVMDevice extends AbstractHardDriveVMDevice {
+ private VMContext context;
+
public DiskDriveVMDevice() {
super(DiskDriveTileEntity.this);
}
@@ -211,6 +215,12 @@ public final class DiskDriveTileEntity extends AbstractTileEntity {
updateBlockDevice(new CompoundNBT());
}
+ @Override
+ public VMDeviceLoadResult load(final VMContext context) {
+ this.context = context;
+ return super.load(context);
+ }
+
@Override
protected int getSize() {
return Config.maxFloppySize;
@@ -245,6 +255,10 @@ public final class DiskDriveTileEntity extends AbstractTileEntity {
@Override
protected Optional getSerializationStream(final BlockDevice device) {
+ if (context != null) {
+ context.joinWorkerThread();
+ }
+
if (device.isReadonly()) {
return Optional.empty();
} else {
@@ -254,6 +268,10 @@ public final class DiskDriveTileEntity extends AbstractTileEntity {
@Override
protected OutputStream getDeserializationStream(final BlockDevice device) {
+ if (context != null) {
+ context.joinWorkerThread();
+ }
+
return device.getOutputStream();
}
}
diff --git a/src/main/java/li/cil/oc2/common/util/TerminalUtils.java b/src/main/java/li/cil/oc2/common/util/TerminalUtils.java
new file mode 100644
index 00000000..044cdb1a
--- /dev/null
+++ b/src/main/java/li/cil/oc2/common/util/TerminalUtils.java
@@ -0,0 +1,27 @@
+package li.cil.oc2.common.util;
+
+import li.cil.oc2.common.vm.Terminal;
+
+import java.nio.ByteBuffer;
+import java.util.function.Consumer;
+
+public final class TerminalUtils {
+ private static final ByteBuffer TERMINAL_RESET_SEQUENCE = ByteBuffer.wrap(new byte[]{
+ // Make sure we're in normal mode.
+ 'J',
+ // Reset color and style.
+ '\033', '[', '0', 'm',
+ // Clear screen.
+ '\033', '[', '2', 'J'
+ });
+
+ ///////////////////////////////////////////////////////////////////
+
+ public static void resetTerminal(final Terminal terminal, final Consumer packetSender) {
+ TERMINAL_RESET_SEQUENCE.clear();
+ terminal.putOutput(TERMINAL_RESET_SEQUENCE);
+
+ TERMINAL_RESET_SEQUENCE.flip();
+ packetSender.accept(TERMINAL_RESET_SEQUENCE);
+ }
+}
diff --git a/src/main/java/li/cil/oc2/common/util/WorldUtils.java b/src/main/java/li/cil/oc2/common/util/WorldUtils.java
index 5496cfa6..7cc753ad 100644
--- a/src/main/java/li/cil/oc2/common/util/WorldUtils.java
+++ b/src/main/java/li/cil/oc2/common/util/WorldUtils.java
@@ -2,8 +2,6 @@ package li.cil.oc2.common.util;
import net.minecraft.block.Block;
import net.minecraft.block.SoundType;
-import net.minecraft.entity.Entity;
-import net.minecraft.entity.item.ItemEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
@@ -13,7 +11,6 @@ import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.IWorld;
import javax.annotation.Nullable;
-import java.util.List;
import java.util.function.Function;
public final class WorldUtils {
@@ -57,7 +54,7 @@ public final class WorldUtils {
return block.getClass().getSimpleName();
}
- public static void playSound(final IWorld world, final BlockPos pos, final SoundType soundType, Function soundEvent) {
+ public static void playSound(final IWorld world, final BlockPos pos, final SoundType soundType, final Function soundEvent) {
playSound(world, pos, soundType, soundEvent.apply(soundType));
}
diff --git a/src/main/java/li/cil/oc2/common/vm/AbstractTerminalVMRunner.java b/src/main/java/li/cil/oc2/common/vm/AbstractTerminalVMRunner.java
new file mode 100644
index 00000000..0fcb1502
--- /dev/null
+++ b/src/main/java/li/cil/oc2/common/vm/AbstractTerminalVMRunner.java
@@ -0,0 +1,80 @@
+package li.cil.oc2.common.vm;
+
+import it.unimi.dsi.fastutil.bytes.ByteArrayFIFOQueue;
+import li.cil.sedna.device.serial.UART16550A;
+
+import java.nio.ByteBuffer;
+
+public abstract class AbstractTerminalVMRunner extends VMRunner {
+ private final UART16550A uart;
+ private final Terminal terminal;
+
+ ///////////////////////////////////////////////////////////////////
+
+ // Thread-local buffers for lock-free read/writes in inner loop.
+ private final ByteArrayFIFOQueue outputBuffer = new ByteArrayFIFOQueue(1024);
+ private final ByteArrayFIFOQueue inputBuffer = new ByteArrayFIFOQueue(32);
+
+ ///////////////////////////////////////////////////////////////////
+
+ public AbstractTerminalVMRunner(final AbstractVirtualMachine virtualMachine, final Terminal terminal) {
+ super(virtualMachine);
+ this.terminal = terminal;
+ uart = virtualMachine.state.builtinDevices.uart;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+
+ protected abstract void sendTerminalUpdateToClient(final ByteBuffer output);
+
+ ///////////////////////////////////////////////////////////////////
+
+ @Override
+ protected void handleBeforeRun() {
+ super.handleBeforeRun();
+
+ int value;
+ while ((value = terminal.readInput()) != -1) {
+ inputBuffer.enqueue((byte) value);
+ }
+ }
+
+ @Override
+ protected void step(final int cyclesPerStep) {
+ super.step(cyclesPerStep);
+
+ while (!inputBuffer.isEmpty() && uart.canPutByte()) {
+ uart.putByte(inputBuffer.dequeueByte());
+ }
+ uart.flush();
+
+ int value;
+ while ((value = uart.read()) != -1) {
+ outputBuffer.enqueue((byte) value);
+ }
+ }
+
+ @Override
+ protected void handleAfterRun() {
+ super.handleAfterRun();
+
+ final ByteBuffer output = ByteBuffer.allocate(outputBuffer.size());
+ while (!outputBuffer.isEmpty()) {
+ output.put(outputBuffer.dequeueByte());
+ }
+
+ output.flip();
+ putTerminalOutput(output);
+ }
+
+ ///////////////////////////////////////////////////////////////////
+
+ private void putTerminalOutput(final ByteBuffer output) {
+ if (output.hasRemaining()) {
+ terminal.putOutput(output);
+
+ output.flip();
+ sendTerminalUpdateToClient(output);
+ }
+ }
+}
diff --git a/src/main/java/li/cil/oc2/common/vm/AbstractTerminalVirtualMachineRunner.java b/src/main/java/li/cil/oc2/common/vm/AbstractTerminalVirtualMachineRunner.java
deleted file mode 100644
index 047317c3..00000000
--- a/src/main/java/li/cil/oc2/common/vm/AbstractTerminalVirtualMachineRunner.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package li.cil.oc2.common.vm;
-
-import it.unimi.dsi.fastutil.bytes.ByteArrayFIFOQueue;
-import li.cil.ceres.api.Serialized;
-import li.cil.oc2.api.bus.device.vm.event.VMInitializationException;
-import li.cil.oc2.api.bus.device.vm.event.VMInitializingEvent;
-import li.cil.oc2.api.bus.device.vm.event.VMResumedRunningEvent;
-import li.cil.oc2.api.bus.device.vm.event.VMResumingRunningEvent;
-import li.cil.oc2.common.Constants;
-import net.minecraft.util.text.ITextComponent;
-import net.minecraft.util.text.TranslationTextComponent;
-import org.jetbrains.annotations.Nullable;
-
-import java.nio.ByteBuffer;
-
-public abstract class AbstractTerminalVirtualMachineRunner extends VirtualMachineRunner {
- private static final ByteBuffer TERMINAL_RESET_SEQUENCE = ByteBuffer.wrap(new byte[]{
- // Make sure we're in normal mode.
- 'J',
- // Reset color and style.
- '\033', '[', '0', 'm',
- // Clear screen.
- '\033', '[', '2', 'J'
- });
-
- private final CommonVirtualMachine virtualMachine;
- private final Terminal terminal;
-
- ///////////////////////////////////////////////////////////////////
-
- // Thread-local buffers for lock-free read/writes in inner loop.
- private final ByteArrayFIFOQueue outputBuffer = new ByteArrayFIFOQueue(1024);
- private final ByteArrayFIFOQueue inputBuffer = new ByteArrayFIFOQueue(32);
-
- private boolean firedResumeEvent;
- @Serialized private boolean firedInitializationEvent;
- @Serialized private ITextComponent runtimeError;
-
- ///////////////////////////////////////////////////////////////////
-
- public AbstractTerminalVirtualMachineRunner(final CommonVirtualMachine virtualMachine, final Terminal terminal) {
- super(virtualMachine.board);
- this.virtualMachine = virtualMachine;
- this.terminal = terminal;
- }
-
- ///////////////////////////////////////////////////////////////////
-
- protected abstract void sendTerminalUpdateToClient(final ByteBuffer output);
-
- ///////////////////////////////////////////////////////////////////
-
- public void resetTerminal() {
- TERMINAL_RESET_SEQUENCE.clear();
- putTerminalOutput(TERMINAL_RESET_SEQUENCE);
- }
-
- public void putTerminalOutput(final ByteBuffer output) {
- if (output.hasRemaining()) {
- terminal.putOutput(output);
-
- output.flip();
- sendTerminalUpdateToClient(output);
- }
- }
-
- public void scheduleResumeEvent() {
- firedResumeEvent = false;
- }
-
- @Nullable
- @Override
- public ITextComponent getRuntimeError() {
- return runtimeError;
- }
-
- @Override
- public void tick() {
- virtualMachine.rpcAdapter.tick();
-
- super.tick();
- }
-
- ///////////////////////////////////////////////////////////////////
-
- @Override
- protected void handleBeforeRun() {
- if (!firedInitializationEvent) {
- firedInitializationEvent = true;
- try {
- virtualMachine.vmAdapter.postLifecycleEvent(new VMInitializingEvent(virtualMachine.board.getDefaultProgramStart()));
- } catch (final VMInitializationException e) {
- virtualMachine.board.setRunning(false);
- runtimeError = e.getErrorMessage().orElse(new TranslationTextComponent(Constants.COMPUTER_ERROR_UNKNOWN));
- return;
- }
- }
-
- if (!firedResumeEvent) {
- firedResumeEvent = true;
- virtualMachine.vmAdapter.postLifecycleEvent(new VMResumingRunningEvent());
- virtualMachine.vmAdapter.postLifecycleEvent(new VMResumedRunningEvent());
- }
-
- int value;
- while ((value = terminal.readInput()) != -1) {
- inputBuffer.enqueue((byte) value);
- }
- }
-
- @Override
- protected void step(final int cyclesPerStep) {
- while (!inputBuffer.isEmpty() && virtualMachine.uart.canPutByte()) {
- virtualMachine.uart.putByte(inputBuffer.dequeueByte());
- }
- virtualMachine.uart.flush();
-
- int value;
- while ((value = virtualMachine.uart.read()) != -1) {
- outputBuffer.enqueue((byte) value);
- }
-
- virtualMachine.rpcAdapter.step(cyclesPerStep);
- }
-
- @Override
- protected void handleAfterRun() {
- final ByteBuffer output = ByteBuffer.allocate(outputBuffer.size());
- while (!outputBuffer.isEmpty()) {
- output.put(outputBuffer.dequeueByte());
- }
-
- output.flip();
- putTerminalOutput(output);
- }
-}
diff --git a/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineItemStackHandlers.java b/src/main/java/li/cil/oc2/common/vm/AbstractVMItemStackHandlers.java
similarity index 94%
rename from src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineItemStackHandlers.java
rename to src/main/java/li/cil/oc2/common/vm/AbstractVMItemStackHandlers.java
index ea1f47e5..d7bc1e30 100644
--- a/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineItemStackHandlers.java
+++ b/src/main/java/li/cil/oc2/common/vm/AbstractVMItemStackHandlers.java
@@ -19,7 +19,7 @@ import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
-public abstract class AbstractVirtualMachineItemStackHandlers implements VirtualMachineItemStackHandlers {
+public abstract class AbstractVMItemStackHandlers implements VMItemStackHandlers {
public static final class GroupDefinition {
public final DeviceType deviceType;
public final int count;
@@ -52,7 +52,7 @@ public abstract class AbstractVirtualMachineItemStackHandlers implements Virtual
///////////////////////////////////////////////////////////////////
- public AbstractVirtualMachineItemStackHandlers(final GroupDefinition... groups) {
+ public AbstractVMItemStackHandlers(final GroupDefinition... groups) {
for (final GroupDefinition group : groups) {
itemHandlers.put(group.deviceType, new ItemHandler(group.count, this::getDevices, group.deviceType));
}
@@ -77,7 +77,7 @@ public abstract class AbstractVirtualMachineItemStackHandlers implements Virtual
return true;
}
- public OptionalLong getDefaultDeviceAddress(final VMDevice wrapper) {
+ public OptionalLong getDeviceAddressBase(final VMDevice wrapper) {
long address = ITEM_DEVICE_BASE_ADDRESS;
for (final Map.Entry entry : itemHandlers.entrySet()) {
@@ -146,7 +146,7 @@ public abstract class AbstractVirtualMachineItemStackHandlers implements Virtual
@Override
protected void onContentsChanged(final int slot) {
super.onContentsChanged(slot);
- AbstractVirtualMachineItemStackHandlers.this.onContentsChanged(this, slot);
+ AbstractVMItemStackHandlers.this.onContentsChanged(this, slot);
}
}
diff --git a/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineState.java b/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachine.java
similarity index 68%
rename from src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineState.java
rename to src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachine.java
index c7b71f2a..2f71de7f 100644
--- a/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineState.java
+++ b/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachine.java
@@ -1,14 +1,18 @@
package li.cil.oc2.common.vm;
+import li.cil.ceres.api.Serialized;
import li.cil.oc2.api.bus.device.vm.FirmwareLoader;
import li.cil.oc2.api.bus.device.vm.VMDeviceLoadResult;
import li.cil.oc2.api.bus.device.vm.event.VMPausingEvent;
import li.cil.oc2.common.Constants;
import li.cil.oc2.common.bus.AbstractDeviceBusController;
+import li.cil.oc2.common.bus.RPCDeviceBusAdapter;
import li.cil.oc2.common.serialization.NBTSerialization;
import li.cil.oc2.common.util.NBTTagIds;
import li.cil.oc2.common.util.NBTUtils;
+import li.cil.oc2.common.vm.context.global.GlobalVMContext;
import li.cil.sedna.api.memory.MemoryAccessException;
+import li.cil.sedna.riscv.R5Board;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
@@ -20,12 +24,12 @@ import org.apache.logging.log4j.Logger;
import javax.annotation.Nullable;
import java.util.Objects;
-public abstract class AbstractVirtualMachineState implements VirtualMachineState {
+public abstract class AbstractVirtualMachine implements VirtualMachine {
private static final Logger LOGGER = LogManager.getLogger();
///////////////////////////////////////////////////////////////////
- private static final String VIRTUAL_MACHINE_TAG_NAME = "virtualMachine";
+ private static final String STATE_TAG_NAME = "state";
private static final String RUNNER_TAG_NAME = "runner";
public static final String BUS_STATE_TAG_NAME = "busState";
@@ -36,28 +40,54 @@ public abstract class AbstractVirtualMachineState device instanceof FirmwareLoader)) {
setBootError(new TranslationTextComponent(Constants.COMPUTER_ERROR_MISSING_FIRMWARE));
- setRunState(RunState.STOPPED);
+ setRunState(VMRunState.STOPPED);
break;
}
@@ -199,28 +240,28 @@ public abstract class AbstractVirtualMachineState
- uart.getInterrupt().set(interrupt, context.getInterruptController()));
- context.getMemoryRangeAllocator().claimMemoryRange(uart);
- board.setStandardOutputDevice(uart);
-
- vfs = new VirtIOFileSystemDevice(context.getMemoryMap(), "data", FileSystems.getLayeredFileSystem());
- context.getInterruptAllocator().claimInterrupt(VFS_INTERRUPT).ifPresent(interrupt ->
- vfs.getInterrupt().set(interrupt, context.getInterruptController()));
- context.getMemoryRangeAllocator().claimMemoryRange(vfs);
- }
-}
diff --git a/src/main/java/li/cil/oc2/common/vm/ManagedEventBus.java b/src/main/java/li/cil/oc2/common/vm/ManagedEventBus.java
deleted file mode 100644
index 175b785e..00000000
--- a/src/main/java/li/cil/oc2/common/vm/ManagedEventBus.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package li.cil.oc2.common.vm;
-
-import com.google.common.eventbus.EventBus;
-import li.cil.oc2.api.bus.device.vm.event.VMLifecycleEventBus;
-
-import java.util.ArrayList;
-
-@SuppressWarnings("UnstableApiUsage")
-public final class ManagedEventBus implements VMLifecycleEventBus {
- private final EventBus eventBus;
- private final ArrayList