From 643ae63c8763e49b20f41fe575939f93b4dea3aa Mon Sep 17 00:00:00 2001 From: raoulvdberge Date: Mon, 5 Nov 2018 17:13:45 +0100 Subject: [PATCH] Add the ability to simulate in the node graph. --- .../api/network/INetworkNodeGraph.java | 41 +++++++++- .../api/network/INetworkNodeVisitor.java | 4 +- .../refinedstorage/apiimpl/API.java | 7 +- .../apiimpl/network/NetworkNodeGraph.java | 74 ++++++++++++------- .../apiimpl/network/node/NetworkNode.java | 3 +- .../node/NetworkNodeExternalStorage.java | 4 +- .../node/NetworkNodeNetworkTransmitter.java | 5 +- .../network/node/cover/CoverManager.java | 3 +- .../node/diskdrive/NetworkNodeDiskDrive.java | 4 +- .../node/storage/NetworkNodeFluidStorage.java | 2 +- .../node/storage/NetworkNodeStorage.java | 2 +- .../refinedstorage/block/BlockNode.java | 3 +- .../refinedstorage/tile/TileController.java | 2 +- 13 files changed, 107 insertions(+), 47 deletions(-) diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeGraph.java b/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeGraph.java index 96fb69335..18c918c8a 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeGraph.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeGraph.java @@ -1,6 +1,8 @@ package com.raoulvdberge.refinedstorage.api.network; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; +import com.raoulvdberge.refinedstorage.api.util.Action; +import net.minecraft.util.math.BlockPos; import java.util.Collection; import java.util.function.Consumer; @@ -11,15 +13,48 @@ import java.util.function.Consumer; public interface INetworkNodeGraph { /** * Rebuilds the network graph. + * + * @deprecated Use {@link #invalidate(Action, BlockPos)} - needed to support simulating the calculation of network connections */ - void rebuild(); + @Deprecated + default void rebuild() { + invalidate(Action.PERFORM, getNetworkForBCReasons().getPosition()); + } /** - * Adds a runnable that is run after the graph is rebuilt. + * DON'T USE THIS! + * This method exists to support a default {@link #rebuild()} method to maintain backward compatibility. + */ + @Deprecated + INetwork getNetworkForBCReasons(); + + /** + * Rebuilds the network graph. + * + * @param action whether to perform or simulate + * @param origin the origin, usually the network position + */ + void invalidate(Action action, BlockPos origin); + + /** + * Runs an action on the network. + * If the network is rebuilding it's graph, the action will be executed after the graph was built. + * + * @param handler the action to run + * @deprecated Use {@link #runActionWhenPossible(Consumer)} - just a method rename + */ + @Deprecated + default void addPostRebuildHandler(Consumer handler) { + runActionWhenPossible(handler); + } + + /** + * Runs an action on the network. + * If the network is rebuilding it's graph, the action will be executed after the graph was built. * * @param handler the action to run */ - void addPostRebuildHandler(Consumer handler); + void runActionWhenPossible(Consumer handler); /** * @return a collection of all connected nodes diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeVisitor.java b/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeVisitor.java index 3f0b473ab..0e08f1cba 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeVisitor.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeVisitor.java @@ -4,6 +4,8 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import javax.annotation.Nullable; + /** * Allows the network nodes to implement more optimal or non-regular discovery of neighbor nodes. */ @@ -12,6 +14,6 @@ public interface INetworkNodeVisitor { @FunctionalInterface interface Operator { - void apply(World world, BlockPos pos, EnumFacing side); + void apply(World world, BlockPos pos, @Nullable EnumFacing side); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/API.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/API.java index a2e998497..0e421b92f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/API.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/API.java @@ -25,10 +25,7 @@ import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskManager; import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskRegistry; import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskSync; import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IExternalStorageProvider; -import com.raoulvdberge.refinedstorage.api.util.IComparer; -import com.raoulvdberge.refinedstorage.api.util.IOneSixMigrationHelper; -import com.raoulvdberge.refinedstorage.api.util.IQuantityFormatter; -import com.raoulvdberge.refinedstorage.api.util.IStackList; +import com.raoulvdberge.refinedstorage.api.util.*; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.CraftingRequestInfo; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementList; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementRegistry; @@ -295,7 +292,7 @@ public class API implements IRSAPI { INetworkNode node = nodeProxy.getNode(); if (node.getNetwork() != null) { - node.getNetwork().getNodeGraph().rebuild(); + node.getNetwork().getNodeGraph().invalidate(Action.PERFORM, node.getNetwork().getPosition()); return; } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeGraph.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeGraph.java index 0044abd9f..37f04efb3 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeGraph.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeGraph.java @@ -6,7 +6,9 @@ import com.raoulvdberge.refinedstorage.api.network.INetworkNodeGraph; import com.raoulvdberge.refinedstorage.api.network.INetworkNodeVisitor; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy; +import com.raoulvdberge.refinedstorage.api.util.Action; import com.raoulvdberge.refinedstorage.apiimpl.network.node.ICoverable; +import com.raoulvdberge.refinedstorage.apiimpl.util.OneSixMigrationHelper; import com.raoulvdberge.refinedstorage.tile.TileController; import net.minecraft.block.state.IBlockState; import net.minecraft.inventory.InventoryHelper; @@ -17,6 +19,7 @@ import net.minecraft.util.NonNullList; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import javax.annotation.Nullable; import java.util.*; import java.util.function.Consumer; @@ -25,24 +28,25 @@ import static com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodePr public class NetworkNodeGraph implements INetworkNodeGraph { private TileController controller; private Set nodes = Sets.newConcurrentHashSet(); - private Set> postRebuildHandlers = new HashSet<>(); - private boolean rebuilding = false; + + private Set> actions = new HashSet<>(); + + private boolean invalidating = false; public NetworkNodeGraph(TileController controller) { this.controller = controller; } @Override - public void rebuild() { - rebuilding = true; + public void invalidate(Action action, BlockPos origin) { + this.invalidating = true; - Operator operator = new Operator(); + Operator operator = new Operator(action); - BlockPos controllerPos = controller.getPos(); World controllerWorld = controller.getWorld(); for (EnumFacing facing : EnumFacing.VALUES) { - BlockPos pos = controllerPos.offset(facing); + BlockPos pos = origin.offset(facing); // Little hack to support not conducting through covers (if the cover is right next to the controller). TileEntity tile = controllerWorld.getTileEntity(pos); @@ -67,28 +71,37 @@ public class NetworkNodeGraph implements INetworkNodeGraph { this.nodes = operator.foundNodes; - for (INetworkNode node : operator.newNodes) { - node.onConnected(controller); + if (action == Action.PERFORM) { + for (INetworkNode node : operator.newNodes) { + node.onConnected(controller); + } + + for (INetworkNode node : operator.previousNodes) { + node.onDisconnected(controller); + } + + actions.forEach(h -> h.accept(controller)); + actions.clear(); + + if (!operator.newNodes.isEmpty() || !operator.previousNodes.isEmpty()) { + controller.getDataManager().sendParameterToWatchers(TileController.NODES); + } } - for (INetworkNode node : operator.previousNodes) { - node.onDisconnected(controller); - } - - postRebuildHandlers.forEach(h -> h.accept(controller)); - postRebuildHandlers.clear(); - - if (!operator.newNodes.isEmpty() || !operator.previousNodes.isEmpty()) { - controller.getDataManager().sendParameterToWatchers(TileController.NODES); - } - - rebuilding = false; + invalidating = false; } @Override - public void addPostRebuildHandler(Consumer handler) { - if (rebuilding) { - postRebuildHandlers.add(handler); + public INetwork getNetworkForBCReasons() { + OneSixMigrationHelper.removalHook(); + + return controller; + } + + @Override + public void runActionWhenPossible(Consumer handler) { + if (invalidating) { + actions.add(handler); } else { handler.accept(controller); } @@ -134,8 +147,14 @@ public class NetworkNodeGraph implements INetworkNodeGraph { private Queue toCheck = new ArrayDeque<>(); + private Action action; + + public Operator(Action action) { + this.action = action; + } + @Override - public void apply(World world, BlockPos pos, EnumFacing side) { + public void apply(World world, BlockPos pos, @Nullable EnumFacing side) { TileEntity tile = world.getTileEntity(pos); if (tile != null && tile.hasCapability(NETWORK_NODE_PROXY_CAPABILITY, side)) { @@ -144,7 +163,10 @@ public class NetworkNodeGraph implements INetworkNodeGraph { // This will work for regular nodes and for controllers too since controllers are internally a INetworkNode (and return themselves in INetworkNode#getNetwork). if (otherNode.getNetwork() != null && otherNode.getNetwork() != controller) { - dropConflictingBlock(world, tile.getPos()); + if (action == Action.PERFORM) { + dropConflictingBlock(world, tile.getPos()); + } + return; } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNode.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNode.java index b8ae342b0..00075f394 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNode.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNode.java @@ -4,6 +4,7 @@ import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.api.network.INetwork; import com.raoulvdberge.refinedstorage.api.network.INetworkNodeVisitor; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; +import com.raoulvdberge.refinedstorage.api.util.Action; import com.raoulvdberge.refinedstorage.apiimpl.API; import com.raoulvdberge.refinedstorage.apiimpl.util.OneSixMigrationHelper; import com.raoulvdberge.refinedstorage.tile.config.RedstoneMode; @@ -142,7 +143,7 @@ public abstract class NetworkNode implements INetworkNode, INetworkNodeVisitor { onConnectedStateChange(network, canUpdate); if (shouldRebuildGraphOnChange()) { - network.getNodeGraph().rebuild(); + network.getNodeGraph().invalidate(Action.PERFORM, network.getPosition()); } } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeExternalStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeExternalStorage.java index 347c42405..0b1851ca0 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeExternalStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeExternalStorage.java @@ -248,8 +248,8 @@ public class NetworkNodeExternalStorage extends NetworkNode implements IStorageP } } - network.getNodeGraph().addPostRebuildHandler(StorageCacheItem.INVALIDATE); - network.getNodeGraph().addPostRebuildHandler(StorageCacheFluid.INVALIDATE); + network.getNodeGraph().runActionWhenPossible(StorageCacheItem.INVALIDATE); + network.getNodeGraph().runActionWhenPossible(StorageCacheFluid.INVALIDATE); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeNetworkTransmitter.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeNetworkTransmitter.java index 11eca780a..5c565b9b6 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeNetworkTransmitter.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeNetworkTransmitter.java @@ -2,6 +2,7 @@ package com.raoulvdberge.refinedstorage.apiimpl.network.node; import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.RSItems; +import com.raoulvdberge.refinedstorage.api.util.Action; import com.raoulvdberge.refinedstorage.inventory.item.ItemHandlerBase; import com.raoulvdberge.refinedstorage.inventory.item.ItemHandlerUpgrade; import com.raoulvdberge.refinedstorage.inventory.item.validator.ItemValidatorBasic; @@ -28,7 +29,7 @@ public class NetworkNodeNetworkTransmitter extends NetworkNode { super.onContentsChanged(slot); if (network != null) { - network.getNodeGraph().rebuild(); + network.getNodeGraph().invalidate(Action.PERFORM, network.getPosition()); } } }; @@ -48,7 +49,7 @@ public class NetworkNodeNetworkTransmitter extends NetworkNode { } if (network != null) { - network.getNodeGraph().rebuild(); + network.getNodeGraph().invalidate(Action.PERFORM, network.getPosition()); } } }; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/cover/CoverManager.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/cover/CoverManager.java index 4cf567352..dfbe445d1 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/cover/CoverManager.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/cover/CoverManager.java @@ -1,6 +1,7 @@ package com.raoulvdberge.refinedstorage.apiimpl.network.node.cover; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; +import com.raoulvdberge.refinedstorage.api.util.Action; import com.raoulvdberge.refinedstorage.apiimpl.API; import com.raoulvdberge.refinedstorage.apiimpl.network.node.ICoverable; import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNode; @@ -80,7 +81,7 @@ public class CoverManager { node.markDirty(); if (node.getNetwork() != null) { - node.getNetwork().getNodeGraph().rebuild(); + node.getNetwork().getNodeGraph().invalidate(Action.PERFORM, node.getNetwork().getPosition()); } return true; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskdrive/NetworkNodeDiskDrive.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskdrive/NetworkNodeDiskDrive.java index 56bc6a078..69904819b 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskdrive/NetworkNodeDiskDrive.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskdrive/NetworkNodeDiskDrive.java @@ -147,8 +147,8 @@ public class NetworkNodeDiskDrive extends NetworkNode implements IGuiStorage, IS public void onConnectedStateChange(INetwork network, boolean state) { super.onConnectedStateChange(network, state); - network.getNodeGraph().addPostRebuildHandler(StorageCacheItem.INVALIDATE); - network.getNodeGraph().addPostRebuildHandler(StorageCacheFluid.INVALIDATE); + network.getNodeGraph().runActionWhenPossible(StorageCacheItem.INVALIDATE); + network.getNodeGraph().runActionWhenPossible(StorageCacheFluid.INVALIDATE); WorldUtils.updateBlock(world, pos); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/NetworkNodeFluidStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/NetworkNodeFluidStorage.java index 7610ab523..912bc2d88 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/NetworkNodeFluidStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/NetworkNodeFluidStorage.java @@ -69,7 +69,7 @@ public class NetworkNodeFluidStorage extends NetworkNode implements IGuiStorage, public void onConnectedStateChange(INetwork network, boolean state) { super.onConnectedStateChange(network, state); - network.getNodeGraph().addPostRebuildHandler(StorageCacheFluid.INVALIDATE); + network.getNodeGraph().runActionWhenPossible(StorageCacheFluid.INVALIDATE); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/NetworkNodeStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/NetworkNodeStorage.java index 1c8bda4e9..ecf38fc21 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/NetworkNodeStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/NetworkNodeStorage.java @@ -69,7 +69,7 @@ public class NetworkNodeStorage extends NetworkNode implements IGuiStorage, ISto public void onConnectedStateChange(INetwork network, boolean state) { super.onConnectedStateChange(network, state); - network.getNodeGraph().addPostRebuildHandler(StorageCacheItem.INVALIDATE); + network.getNodeGraph().runActionWhenPossible(StorageCacheItem.INVALIDATE); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockNode.java b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockNode.java index 13ee830ce..6ba0b5f7f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockNode.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockNode.java @@ -2,6 +2,7 @@ package com.raoulvdberge.refinedstorage.block; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeManager; +import com.raoulvdberge.refinedstorage.api.util.Action; import com.raoulvdberge.refinedstorage.apiimpl.API; import com.raoulvdberge.refinedstorage.block.info.IBlockInfo; import com.raoulvdberge.refinedstorage.tile.TileNode; @@ -52,7 +53,7 @@ public abstract class BlockNode extends BlockNodeProxy { manager.markForSaving(); if (node != null && node.getNetwork() != null) { - node.getNetwork().getNodeGraph().rebuild(); + node.getNetwork().getNodeGraph().invalidate(Action.PERFORM, node.getNetwork().getPosition()); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileController.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileController.java index 77f2363dc..933e05b6f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileController.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileController.java @@ -231,7 +231,7 @@ public class TileController extends TileBase implements ITickable, INetwork, IRe couldRun = canRun; throttlingDisabled = false; - nodeGraph.rebuild(); + nodeGraph.invalidate(Action.PERFORM, pos); securityManager.invalidate(); } } else {