Add mount and unmount lifecycle callbacks to RPCDevices.
This commit is contained in:
@@ -44,6 +44,24 @@ public interface RPCDevice extends Device {
|
||||
*/
|
||||
List<RPCMethod> getMethods();
|
||||
|
||||
/**
|
||||
* Called to initialize this device.
|
||||
* <p>
|
||||
* This is called when the connected virtual machine starts, or when the device is added to an already running
|
||||
* virtual machine.
|
||||
*/
|
||||
default void mount() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to dispose this device.
|
||||
* <p>
|
||||
* Called when the connected virtual machine stops, or when the device is removed from a currently running
|
||||
* virtual machine.
|
||||
*/
|
||||
default void unmount() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the device is suspended.
|
||||
* <p>
|
||||
|
||||
@@ -199,10 +199,7 @@ public final class ComputerBlockEntity extends ModBlockEntity implements Termina
|
||||
public void setRemoved() {
|
||||
super.setRemoved();
|
||||
|
||||
// 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.unmount();
|
||||
virtualMachine.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,6 +40,8 @@ public final class RPCDeviceBusAdapter implements Steppable {
|
||||
|
||||
private final ArrayList<RPCDeviceWithIdentifier> devices = new ArrayList<>();
|
||||
private final HashMap<UUID, RPCDeviceList> devicesById = new HashMap<>();
|
||||
private final Set<RPCDevice> unmountedDevices = new HashSet<>();
|
||||
private final Set<RPCDevice> mountedDevices = new HashSet<>();
|
||||
private final Lock pauseLock = new ReentrantLock();
|
||||
private boolean isPaused;
|
||||
|
||||
@@ -69,6 +71,22 @@ public final class RPCDeviceBusAdapter implements Steppable {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public void mount() {
|
||||
for (final RPCDevice device : unmountedDevices) {
|
||||
device.mount();
|
||||
}
|
||||
mountedDevices.addAll(unmountedDevices);
|
||||
unmountedDevices.clear();
|
||||
}
|
||||
|
||||
public void unmount() {
|
||||
for (final RPCDevice device : mountedDevices) {
|
||||
device.unmount();
|
||||
}
|
||||
unmountedDevices.addAll(mountedDevices);
|
||||
mountedDevices.clear();
|
||||
}
|
||||
|
||||
public void suspend() {
|
||||
for (final RPCDeviceWithIdentifier info : devices) {
|
||||
info.device.suspend();
|
||||
@@ -100,6 +118,7 @@ public final class RPCDeviceBusAdapter implements Steppable {
|
||||
|
||||
devices.clear();
|
||||
devicesById.clear();
|
||||
unmountedDevices.clear();
|
||||
|
||||
// How device grouping works:
|
||||
// Each device can have multiple UUIDs due to being attached to multiple bus elements.
|
||||
@@ -144,11 +163,31 @@ public final class RPCDeviceBusAdapter implements Steppable {
|
||||
.add(identifier);
|
||||
});
|
||||
|
||||
final Set<RPCDevice> newDevices = new HashSet<>();
|
||||
identifiersByDevice.forEach((device, identifiers) -> {
|
||||
final UUID identifier = selectIdentifierDeterministically(identifiers);
|
||||
devices.add(new RPCDeviceWithIdentifier(identifier, device));
|
||||
devicesById.put(identifier, device);
|
||||
newDevices.add(device);
|
||||
});
|
||||
|
||||
// Add new devices to list of unmounted devices. List was cleared, so removed devices previously in
|
||||
// list of unmounted devices are already gone.
|
||||
for (final RPCDevice newDevice : newDevices) {
|
||||
if (!mountedDevices.contains(newDevice)) {
|
||||
unmountedDevices.add(newDevice);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove removed devices from list of mounted devices.
|
||||
final Iterator<RPCDevice> mountedDeviceIterator = mountedDevices.iterator();
|
||||
while (mountedDeviceIterator.hasNext()) {
|
||||
final RPCDevice device = mountedDeviceIterator.next();
|
||||
if (!newDevices.contains(device)) {
|
||||
device.unmount();
|
||||
mountedDeviceIterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
|
||||
@@ -35,6 +35,20 @@ public final class RPCDeviceList implements RPCDevice {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mount() {
|
||||
for (final RPCDevice device : devices) {
|
||||
device.mount();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unmount() {
|
||||
for (final RPCDevice device : devices) {
|
||||
device.unmount();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suspend() {
|
||||
for (final RPCDevice device : devices) {
|
||||
|
||||
@@ -348,7 +348,7 @@ public final class Robot extends Entity implements li.cil.oc2.api.capabilities.R
|
||||
virtualMachine.suspend();
|
||||
|
||||
// Full unload to release out-of-nbt persisted runtime-only data such as ram.
|
||||
virtualMachine.state.vmAdapter.unmount();
|
||||
virtualMachine.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -198,6 +198,7 @@ public abstract class AbstractVirtualMachine implements VirtualMachine {
|
||||
|
||||
state.board.reset();
|
||||
state.rpcAdapter.reset();
|
||||
state.rpcAdapter.unmount();
|
||||
state.vmAdapter.unmount();
|
||||
|
||||
runner = null;
|
||||
@@ -337,6 +338,8 @@ public abstract class AbstractVirtualMachine implements VirtualMachine {
|
||||
runner = createRunner();
|
||||
}
|
||||
|
||||
state.rpcAdapter.mount();
|
||||
|
||||
setRunState(VMRunState.RUNNING);
|
||||
|
||||
// Only start running next tick. This gives loaded devices one tick to do async
|
||||
|
||||
Reference in New Issue
Block a user