diff --git a/src/main/java/li/cil/oc2/api/bus/device/vm/VMDeviceLoadResult.java b/src/main/java/li/cil/oc2/api/bus/device/vm/VMDeviceLoadResult.java index c83502bf..5add0ca4 100644 --- a/src/main/java/li/cil/oc2/api/bus/device/vm/VMDeviceLoadResult.java +++ b/src/main/java/li/cil/oc2/api/bus/device/vm/VMDeviceLoadResult.java @@ -1,5 +1,9 @@ package li.cil.oc2.api.bus.device.vm; +import net.minecraft.util.text.ITextComponent; + +import javax.annotation.Nullable; + public final class VMDeviceLoadResult { public static VMDeviceLoadResult success() { return new VMDeviceLoadResult(true); @@ -10,6 +14,7 @@ public final class VMDeviceLoadResult { } private final boolean wasSuccessful; + @Nullable private ITextComponent message; private VMDeviceLoadResult(final boolean wasSuccessful) { this.wasSuccessful = wasSuccessful; @@ -18,4 +23,14 @@ public final class VMDeviceLoadResult { public boolean wasSuccessful() { return wasSuccessful; } + + public VMDeviceLoadResult withErrorMessage(final ITextComponent value) { + message = value; + return this; + } + + @Nullable + public ITextComponent getErrorMessage() { + return message; + } } diff --git a/src/main/java/li/cil/oc2/common/block/entity/ComputerTileEntity.java b/src/main/java/li/cil/oc2/common/block/entity/ComputerTileEntity.java index a7b8f012..7d5a2c52 100644 --- a/src/main/java/li/cil/oc2/common/block/entity/ComputerTileEntity.java +++ b/src/main/java/li/cil/oc2/common/block/entity/ComputerTileEntity.java @@ -9,6 +9,7 @@ import li.cil.oc2.api.bus.device.Device; 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.VMDeviceLifecycleEventType; +import li.cil.oc2.api.bus.device.vm.VMDeviceLoadResult; import li.cil.oc2.common.block.ComputerBlock; import li.cil.oc2.common.bus.AbstractDeviceBusController; import li.cil.oc2.common.bus.TileEntityDeviceBusController; @@ -251,7 +252,13 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic break; } - if (!virtualMachine.vmAdapter.load()) { + final VMDeviceLoadResult loadResult = virtualMachine.vmAdapter.load(); + if (!loadResult.wasSuccessful()) { + if (loadResult.getErrorMessage() != null) { + setBootError(loadResult.getErrorMessage()); + } else { + setBootError(new TranslationTextComponent(Constants.COMPUTER_BOOT_ERROR_UNKNOWN)); + } loadDevicesDelay = DEVICE_LOAD_RETRY_INTERVAL; break; } @@ -441,6 +448,10 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic } private void setBootError(@Nullable final ITextComponent value) { + if (Objects.equals(value, bootError)) { + return; + } + bootError = value; final ComputerBootErrorMessage message = new ComputerBootErrorMessage(this); Network.sendToClientsTrackingChunk(message, chunk); diff --git a/src/main/java/li/cil/oc2/common/vm/VirtualMachineDeviceBusAdapter.java b/src/main/java/li/cil/oc2/common/vm/VirtualMachineDeviceBusAdapter.java index 19351cfd..86a846d2 100644 --- a/src/main/java/li/cil/oc2/common/vm/VirtualMachineDeviceBusAdapter.java +++ b/src/main/java/li/cil/oc2/common/vm/VirtualMachineDeviceBusAdapter.java @@ -45,8 +45,7 @@ public final class VirtualMachineDeviceBusAdapter { defaultAddressProvider = provider; } - public boolean load() { - boolean anyFailed = false; + public VMDeviceLoadResult load() { for (int i = 0; i < incompleteLoads.size(); i++) { final VMDevice device = incompleteLoads.get(i); @@ -60,24 +59,19 @@ public final class VirtualMachineDeviceBusAdapter { context.freeze(); if (!result.wasSuccessful()) { - anyFailed = true; for (; i >= 0; i--) { deviceContexts.get(incompleteLoads.get(i)).invalidate(); } - break; + return result; } } - if (anyFailed) { - return false; - } - incompleteLoads.clear(); reservedInterrupts.clear(); reservedInterrupts.or(claimedInterrupts); - return true; + return VMDeviceLoadResult.success(); } public void unload() { diff --git a/src/test/java/li/cil/oc2/common/bus/VMDeviceTests.java b/src/test/java/li/cil/oc2/common/bus/VMDeviceTests.java index 512c6261..27d4eaaf 100644 --- a/src/test/java/li/cil/oc2/common/bus/VMDeviceTests.java +++ b/src/test/java/li/cil/oc2/common/bus/VMDeviceTests.java @@ -59,11 +59,11 @@ public final class VMDeviceTests { when(device2.load(any())).thenReturn(VMDeviceLoadResult.success()); adapter.addDevices(Collections.singleton(device1)); - assertTrue(adapter.load()); + assertTrue(adapter.load().wasSuccessful()); verify(device1).load(any()); adapter.addDevices(Collections.singleton(device2)); - assertTrue(adapter.load()); + assertTrue(adapter.load().wasSuccessful()); verifyNoMoreInteractions(device1); verify(device2).load(any()); @@ -75,7 +75,7 @@ public final class VMDeviceTests { when(device.load(any())).thenReturn(VMDeviceLoadResult.success()); adapter.addDevices(Collections.singleton(device)); - assertTrue(adapter.load()); + assertTrue(adapter.load().wasSuccessful()); adapter.removeDevices(Collections.singleton(device)); verify(device).handleLifecycleEvent(VMDeviceLifecycleEventType.UNLOAD); @@ -87,7 +87,7 @@ public final class VMDeviceTests { when(device.load(any())).thenReturn(VMDeviceLoadResult.success()); adapter.addDevices(Collections.singleton(device)); - assertTrue(adapter.load()); + assertTrue(adapter.load().wasSuccessful()); adapter.unload(); verify(device).handleLifecycleEvent(VMDeviceLifecycleEventType.UNLOAD); @@ -99,13 +99,13 @@ public final class VMDeviceTests { when(device.load(any())).thenReturn(VMDeviceLoadResult.success()); adapter.addDevices(Collections.singleton(device)); - assertTrue(adapter.load()); + assertTrue(adapter.load().wasSuccessful()); verify(device).load(any()); adapter.unload(); verify(device).handleLifecycleEvent(VMDeviceLifecycleEventType.UNLOAD); - assertTrue(adapter.load()); + assertTrue(adapter.load().wasSuccessful()); verify(device, times(2)).load(any()); } @@ -120,7 +120,7 @@ public final class VMDeviceTests { }); adapter.addDevices(Collections.singleton(device)); - assertTrue(adapter.load()); + assertTrue(adapter.load().wasSuccessful()); verify(device).load(any()); } @@ -141,7 +141,7 @@ public final class VMDeviceTests { adapter.getGlobalContext().getInterruptAllocator().claimInterrupt(claimedInterrupt); adapter.addDevices(Collections.singleton(device)); - assertTrue(adapter.load()); + assertTrue(adapter.load().wasSuccessful()); } @Test @@ -160,7 +160,7 @@ public final class VMDeviceTests { }); adapter.addDevices(Collections.singleton(device)); - assertTrue(adapter.load()); + assertTrue(adapter.load().wasSuccessful()); final int claimedInterruptMask = 1 << deviceData.interrupt; deviceData.context.getInterruptController().raiseInterrupts(claimedInterruptMask); @@ -178,7 +178,7 @@ public final class VMDeviceTests { }); adapter.addDevices(Collections.singleton(device)); - assertTrue(adapter.load()); + assertTrue(adapter.load().wasSuccessful()); final int someInterruptMask = 0x1; assertThrows(IllegalArgumentException.class, () -> @@ -201,7 +201,7 @@ public final class VMDeviceTests { }); adapter.addDevices(Collections.singleton(device)); - assertTrue(adapter.load()); + assertTrue(adapter.load().wasSuccessful()); final int claimedInterruptMask = 1 << deviceData.interrupt; deviceData.context.getInterruptController().raiseInterrupts(claimedInterruptMask); @@ -246,7 +246,7 @@ public final class VMDeviceTests { }); adapter.addDevices(Collections.singleton(device)); - assertTrue(adapter.load()); + assertTrue(adapter.load().wasSuccessful()); assertTrue(deviceData.context.getMemoryMap().getMemoryRange(deviceData.device).isPresent()); } @@ -268,7 +268,7 @@ public final class VMDeviceTests { }); adapter.addDevices(Collections.singleton(device)); - assertTrue(adapter.load()); + assertTrue(adapter.load().wasSuccessful()); assertTrue(deviceData.context.getMemoryMap().getMemoryRange(deviceData.device).isPresent());