Add the ability to simulate in the node graph.
This commit is contained in:
@@ -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<INetwork> 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<INetwork> handler);
|
||||
void runActionWhenPossible(Consumer<INetwork> handler);
|
||||
|
||||
/**
|
||||
* @return a collection of all connected nodes
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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<INetworkNode> nodes = Sets.newConcurrentHashSet();
|
||||
private Set<Consumer<INetwork>> postRebuildHandlers = new HashSet<>();
|
||||
private boolean rebuilding = false;
|
||||
|
||||
private Set<Consumer<INetwork>> 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<INetwork> handler) {
|
||||
if (rebuilding) {
|
||||
postRebuildHandlers.add(handler);
|
||||
public INetwork getNetworkForBCReasons() {
|
||||
OneSixMigrationHelper.removalHook();
|
||||
|
||||
return controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runActionWhenPossible(Consumer<INetwork> handler) {
|
||||
if (invalidating) {
|
||||
actions.add(handler);
|
||||
} else {
|
||||
handler.accept(controller);
|
||||
}
|
||||
@@ -134,8 +147,14 @@ public class NetworkNodeGraph implements INetworkNodeGraph {
|
||||
|
||||
private Queue<Visitor> 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;
|
||||
}
|
||||
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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 {
|
||||
|
Reference in New Issue
Block a user