Allow devices to provide an error message if they failed loading.

This commit is contained in:
Florian Nücke
2020-12-27 01:50:47 +01:00
parent 535e9cef79
commit 15d85b2e66
4 changed files with 43 additions and 23 deletions

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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() {

View File

@@ -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());