Allow devices to provide an error message if they failed loading.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user