Pulled out common tile enity bus controller logic (checking for loaded/unloaded chunks to trigger scan).
This commit is contained in:
@@ -11,6 +11,7 @@ import li.cil.oc2.api.bus.device.vm.VMDevice;
|
||||
import li.cil.oc2.api.bus.device.vm.VMDeviceLifecycleEventType;
|
||||
import li.cil.oc2.common.block.ComputerBlock;
|
||||
import li.cil.oc2.common.bus.AbstractDeviceBusController;
|
||||
import li.cil.oc2.common.bus.TileEntityDeviceBusController;
|
||||
import li.cil.oc2.common.bus.TileEntityDeviceBusElement;
|
||||
import li.cil.oc2.common.bus.device.ItemDeviceInfo;
|
||||
import li.cil.oc2.common.capabilities.Capabilities;
|
||||
@@ -113,14 +114,14 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
|
||||
virtualMachine.vmAdapter.setDefaultAddressProvider(this::getDefaultDeviceAddress);
|
||||
}
|
||||
|
||||
public Terminal getTerminal() {
|
||||
return terminal;
|
||||
}
|
||||
|
||||
public IItemHandler getItemHandler() {
|
||||
return itemHandler;
|
||||
}
|
||||
|
||||
public Terminal getTerminal() {
|
||||
return terminal;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (runState == RunState.RUNNING) {
|
||||
return;
|
||||
@@ -157,7 +158,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
|
||||
}
|
||||
|
||||
public void handleNeighborChanged(final BlockPos pos) {
|
||||
busElement.handleNeighborChanged(pos);
|
||||
busController.scheduleBusScan();
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@@ -198,11 +199,6 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
|
||||
|
||||
@Override
|
||||
protected void collectCapabilities(final CapabilityCollector collector, @Nullable final Direction direction) {
|
||||
if (direction != getBlockState().get(ComputerBlock.HORIZONTAL_FACING)) {
|
||||
collector.offer(Capabilities.DEVICE_BUS_ELEMENT_CAPABILITY, busElement);
|
||||
collector.offer(Capabilities.DEVICE_BUS_CONTROLLER_CAPABILITY, busController);
|
||||
}
|
||||
|
||||
collector.offer(Capabilities.ITEM_HANDLER_CAPABILITY, itemHandler);
|
||||
}
|
||||
|
||||
@@ -241,7 +237,15 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
|
||||
// bus setup and devices to load. So we can keep using it.
|
||||
if (runner == null) {
|
||||
virtualMachine.board.reset();
|
||||
virtualMachine.board.initialize();
|
||||
|
||||
try {
|
||||
virtualMachine.board.initialize();
|
||||
} catch (final Throwable e) {
|
||||
LOGGER.error(e);
|
||||
setRunState(RunState.STOPPED);
|
||||
return;
|
||||
}
|
||||
|
||||
virtualMachine.board.setRunning(true);
|
||||
|
||||
runner = new ComputerVirtualMachineRunner(virtualMachine);
|
||||
@@ -451,9 +455,9 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private final class BusController extends AbstractDeviceBusController {
|
||||
private BusController() {
|
||||
super(busElement);
|
||||
private final class BusController extends TileEntityDeviceBusController {
|
||||
private BusController(final DeviceBusElement root) {
|
||||
super(root, ComputerTileEntity.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
package li.cil.oc2.common.bus;
|
||||
|
||||
import li.cil.oc2.api.bus.BlockDeviceBusElement;
|
||||
import li.cil.oc2.api.bus.DeviceBusElement;
|
||||
import li.cil.oc2.common.util.ServerScheduler;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class TileEntityDeviceBusController extends AbstractDeviceBusController {
|
||||
private final Runnable onBusChunkLoadedStateChanged = this::scheduleBusScan;
|
||||
private final HashSet<ChunkPos> trackedChunks = new HashSet<>();
|
||||
private final TileEntity tileEntity;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public TileEntityDeviceBusController(final DeviceBusElement root, final TileEntity tileEntity) {
|
||||
super(root);
|
||||
this.tileEntity = tileEntity;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
|
||||
removeListeners(trackedChunks);
|
||||
trackedChunks.clear();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected void onAfterBusScan() {
|
||||
final World world = tileEntity.getWorld();
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final HashSet<ChunkPos> newTrackedChunks = new HashSet<>();
|
||||
for (final DeviceBusElement element : getElements()) {
|
||||
if (element instanceof BlockDeviceBusElement) {
|
||||
final BlockPos position = ((BlockDeviceBusElement) element).getPosition();
|
||||
newTrackedChunks.add(new ChunkPos(position));
|
||||
newTrackedChunks.add(new ChunkPos(position.offset(Direction.NORTH)));
|
||||
newTrackedChunks.add(new ChunkPos(position.offset(Direction.EAST)));
|
||||
newTrackedChunks.add(new ChunkPos(position.offset(Direction.SOUTH)));
|
||||
newTrackedChunks.add(new ChunkPos(position.offset(Direction.WEST)));
|
||||
}
|
||||
}
|
||||
|
||||
// Do not track the chunk the controller itself is in -- this is unneeded because
|
||||
// we expect the controller to be disposed if its chunk is unloaded.
|
||||
newTrackedChunks.remove(new ChunkPos(tileEntity.getPos()));
|
||||
|
||||
final HashSet<ChunkPos> removedChunks = new HashSet<>(trackedChunks);
|
||||
removedChunks.removeAll(newTrackedChunks);
|
||||
removeListeners(removedChunks);
|
||||
|
||||
final HashSet<ChunkPos> addedChunks = new HashSet<>(newTrackedChunks);
|
||||
newTrackedChunks.removeAll(trackedChunks);
|
||||
addListeners(world, addedChunks);
|
||||
|
||||
trackedChunks.removeAll(removedChunks);
|
||||
trackedChunks.addAll(newTrackedChunks);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private void addListeners(final World world, final Collection<ChunkPos> chunks) {
|
||||
for (final ChunkPos chunkPos : chunks) {
|
||||
ServerScheduler.scheduleOnLoad(world, chunkPos, onBusChunkLoadedStateChanged);
|
||||
ServerScheduler.scheduleOnUnload(world, chunkPos, onBusChunkLoadedStateChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeListeners(final Collection<ChunkPos> chunks) {
|
||||
final World world = tileEntity.getWorld();
|
||||
for (final ChunkPos chunkPos : chunks) {
|
||||
ServerScheduler.cancelOnLoad(world, chunkPos, onBusChunkLoadedStateChanged);
|
||||
ServerScheduler.cancelOnUnload(world, chunkPos, onBusChunkLoadedStateChanged);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user