Make VM lifecycle events allow being used to sync up device state pre/post resume.
This commit is contained in:
@@ -1,6 +1,29 @@
|
||||
package li.cil.oc2.api.bus.device.vm;
|
||||
|
||||
public enum VMDeviceLifecycleEventType {
|
||||
/**
|
||||
* Fired exactly once, when the VM first starts running.
|
||||
* <p>
|
||||
* Fired after all devices reported success from {@link VMDevice#load(VMContext)}.
|
||||
* <p>
|
||||
* If a running VM is restored from a saved state, this event will not be fired. It is
|
||||
* intended for initializing the VM state on boot, e.g. by loading initial executable
|
||||
* code into memory.
|
||||
* <p>
|
||||
* <em>This is invoked from the worker thread running the VM.</em>
|
||||
*/
|
||||
INITIALIZING,
|
||||
|
||||
/**
|
||||
* Fired when the VM is paused, typically before state is persisted.
|
||||
* <p>
|
||||
* Allows devices that offer interaction to external code-flow to suspend
|
||||
* such interactions until {@link #RESUMED_RUNNING} is fired. This is required
|
||||
* if such interactions may modify VM state, to prevent corrupting data being
|
||||
* serialized asynchronously.
|
||||
*/
|
||||
PAUSING,
|
||||
|
||||
/**
|
||||
* Fired when the VM resumes running.
|
||||
* <p>
|
||||
@@ -13,17 +36,16 @@ public enum VMDeviceLifecycleEventType {
|
||||
RESUME_RUNNING,
|
||||
|
||||
/**
|
||||
* Fired exactly once, when the VM first starts running.
|
||||
* Fired when the VM resumed running.
|
||||
* <p>
|
||||
* Fired after all devices reported success from {@link VMDevice#load(VMContext)}.
|
||||
* Fired after {@link #RESUME_RUNNING} has been fired and handled by all devices.
|
||||
* <p>
|
||||
* If a running VM is restored from a saved state, this event will not be fired. It is
|
||||
* intended for initializing the VM state on boot, e.g. by loading initial executable
|
||||
* code into memory.
|
||||
* Allows device initialization that relies on all other devices having fully loaded.
|
||||
* <p>
|
||||
* <em>This is invoked from the worker thread running the VM.</em>
|
||||
* Typically this is used in combination with {@link #PAUSING}, to re-enable external
|
||||
* interactions after VM state is guaranteed to be safe to modify again.
|
||||
*/
|
||||
INITIALIZE,
|
||||
RESUMED_RUNNING,
|
||||
|
||||
/**
|
||||
* Fired when the device is disposed, either because the VM is disposed or the source
|
||||
|
||||
@@ -64,7 +64,7 @@ public final class ByteBufferFlashMemoryVMDevice extends IdentityProxy<ItemStack
|
||||
@Override
|
||||
public void handleLifecycleEvent(final VMDeviceLifecycleEventType event) {
|
||||
switch (event) {
|
||||
case INITIALIZE:
|
||||
case INITIALIZING:
|
||||
// TODO Have start address passed with event?
|
||||
copyDataToMemory(0x80000000L);
|
||||
break;
|
||||
|
||||
@@ -30,7 +30,7 @@ public final class FirmwareFlashMemoryVMDevice extends IdentityProxy<ItemStack>
|
||||
@Override
|
||||
public void handleLifecycleEvent(final VMDeviceLifecycleEventType event) {
|
||||
switch (event) {
|
||||
case INITIALIZE:
|
||||
case INITIALIZING:
|
||||
// TODO Have start address passed with event?
|
||||
firmware.run(memoryMap, 0x80000000L);
|
||||
break;
|
||||
|
||||
@@ -407,18 +407,19 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
|
||||
|
||||
joinVirtualMachine();
|
||||
|
||||
tag.put(TERMINAL_TAG_NAME, NBTSerialization.serialize(terminal));
|
||||
|
||||
tag.put(BUS_ELEMENT_TAG_NAME, NBTSerialization.serialize(busElement));
|
||||
tag.put(VIRTUAL_MACHINE_TAG_NAME, NBTSerialization.serialize(virtualMachine));
|
||||
|
||||
if (runner != null) {
|
||||
tag.put(RUNNER_TAG_NAME, NBTSerialization.serialize(runner));
|
||||
virtualMachine.vmAdapter.fireLifecycleEvent(VMDeviceLifecycleEventType.PAUSING);
|
||||
runner.scheduleResumeEvent(); // Allow synchronizing to async device saves.
|
||||
} else {
|
||||
NBTUtils.putEnum(tag, RUN_STATE_TAG_NAME, runState);
|
||||
}
|
||||
|
||||
tag.put(TERMINAL_TAG_NAME, NBTSerialization.serialize(terminal));
|
||||
|
||||
tag.put(BUS_ELEMENT_TAG_NAME, NBTSerialization.serialize(busElement));
|
||||
tag.put(VIRTUAL_MACHINE_TAG_NAME, NBTSerialization.serialize(virtualMachine));
|
||||
|
||||
final CompoundNBT items = new CompoundNBT();
|
||||
items.put(MEMORY_TAG_NAME, memoryItemHandler.serializeNBT());
|
||||
items.put(HARD_DRIVE_TAG_NAME, hardDriveItemHandler.serializeNBT());
|
||||
@@ -739,12 +740,13 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
|
||||
protected void handleBeforeRun() {
|
||||
if (!firedInitializationEvent) {
|
||||
firedInitializationEvent = true;
|
||||
virtualMachine.vmAdapter.fireLifecycleEvent(VMDeviceLifecycleEventType.INITIALIZE);
|
||||
virtualMachine.vmAdapter.fireLifecycleEvent(VMDeviceLifecycleEventType.INITIALIZING);
|
||||
}
|
||||
|
||||
if (!firedResumeEvent) {
|
||||
firedResumeEvent = true;
|
||||
virtualMachine.vmAdapter.fireLifecycleEvent(VMDeviceLifecycleEventType.RESUME_RUNNING);
|
||||
virtualMachine.vmAdapter.fireLifecycleEvent(VMDeviceLifecycleEventType.RESUMED_RUNNING);
|
||||
}
|
||||
|
||||
int value;
|
||||
|
||||
Reference in New Issue
Block a user