More graph fixes.

This commit is contained in:
raoulvdberge
2018-11-07 02:32:19 +01:00
parent 643ae63c87
commit d7b1953218
24 changed files with 151 additions and 73 deletions

View File

@@ -3,6 +3,7 @@ package com.raoulvdberge.refinedstorage.api.network;
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
import com.raoulvdberge.refinedstorage.api.util.Action; import com.raoulvdberge.refinedstorage.api.util.Action;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.Collection; import java.util.Collection;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -14,11 +15,11 @@ public interface INetworkNodeGraph {
/** /**
* Rebuilds the network graph. * Rebuilds the network graph.
* *
* @deprecated Use {@link #invalidate(Action, BlockPos)} - needed to support simulating the calculation of network connections * @deprecated Use {@link #invalidate(Action, World, BlockPos)} - needed to support simulating the calculation of network connections
*/ */
@Deprecated @Deprecated
default void rebuild() { default void rebuild() {
invalidate(Action.PERFORM, getNetworkForBCReasons().getPosition()); invalidate(Action.PERFORM, getNetworkForBCReasons().world(), getNetworkForBCReasons().getPosition());
} }
/** /**
@@ -32,9 +33,10 @@ public interface INetworkNodeGraph {
* Rebuilds the network graph. * Rebuilds the network graph.
* *
* @param action whether to perform or simulate * @param action whether to perform or simulate
* @param world the origin world
* @param origin the origin, usually the network position * @param origin the origin, usually the network position
*/ */
void invalidate(Action action, BlockPos origin); void invalidate(Action action, World world, BlockPos origin);
/** /**
* Runs an action on the network. * Runs an action on the network.
@@ -61,6 +63,11 @@ public interface INetworkNodeGraph {
*/ */
Collection<INetworkNode> all(); Collection<INetworkNode> all();
/**
* @param listener the listener
*/
void addListener(INetworkNodeGraphListener listener);
/** /**
* Disconnects and notifies all connected nodes. * Disconnects and notifies all connected nodes.
*/ */

View File

@@ -0,0 +1,11 @@
package com.raoulvdberge.refinedstorage.api.network;
/**
* A listener for the node graph.
*/
public interface INetworkNodeGraphListener {
/**
* Called when the graph changes.
*/
void onChanged();
}

View File

@@ -1,5 +1,6 @@
package com.raoulvdberge.refinedstorage.api.network; package com.raoulvdberge.refinedstorage.api.network;
import com.raoulvdberge.refinedstorage.api.util.Action;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
@@ -7,13 +8,36 @@ import net.minecraft.world.World;
import javax.annotation.Nullable; import javax.annotation.Nullable;
/** /**
* Allows the network nodes to implement more optimal or non-regular discovery of neighbor nodes. * Allows the network nodes to implement more optimal or non-regular discovery of other (neighboring) nodes.
*/ */
public interface INetworkNodeVisitor { public interface INetworkNodeVisitor {
/**
* Called by the network node graph when a {@link Operator} has requested this node to be visited.
*
* @param operator the operator
*/
void visit(Operator operator); void visit(Operator operator);
@FunctionalInterface /**
* An operator is passed to the {@link #visit(Operator)} method to allow the network node visitor to add positions of nodes to scan.
*/
interface Operator { interface Operator {
/**
* Calling this method in {@link #visit(Operator)} will make the network graph scan the given world and position.
* If there is another {@link INetworkNodeVisitor} at that position, it will call that visitor.
* If there is no {@link INetworkNodeVisitor} at that position, it will use a default implementation which scans neighbors.
*
* @param world the world
* @param pos the position
* @param side the side
*/
void apply(World world, BlockPos pos, @Nullable EnumFacing side); void apply(World world, BlockPos pos, @Nullable EnumFacing side);
/**
* Returns whether the network graph is scanning in simulation mode.
*
* @return the action
*/
Action getAction();
} }
} }

View File

@@ -292,7 +292,7 @@ public class API implements IRSAPI {
INetworkNode node = nodeProxy.getNode(); INetworkNode node = nodeProxy.getNode();
if (node.getNetwork() != null) { if (node.getNetwork() != null) {
node.getNetwork().getNodeGraph().invalidate(Action.PERFORM, node.getNetwork().getPosition()); node.getNetwork().getNodeGraph().invalidate(Action.PERFORM, node.getNetwork().world(), node.getNetwork().getPosition());
return; return;
} }

View File

@@ -3,13 +3,13 @@ package com.raoulvdberge.refinedstorage.apiimpl.network;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.raoulvdberge.refinedstorage.api.network.INetwork; import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.api.network.INetworkNodeGraph; import com.raoulvdberge.refinedstorage.api.network.INetworkNodeGraph;
import com.raoulvdberge.refinedstorage.api.network.INetworkNodeGraphListener;
import com.raoulvdberge.refinedstorage.api.network.INetworkNodeVisitor; import com.raoulvdberge.refinedstorage.api.network.INetworkNodeVisitor;
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy;
import com.raoulvdberge.refinedstorage.api.util.Action; 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.apiimpl.util.OneSixMigrationHelper;
import com.raoulvdberge.refinedstorage.tile.TileController; import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.inventory.InventoryHelper; import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@@ -26,42 +26,35 @@ import java.util.function.Consumer;
import static com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy.NETWORK_NODE_PROXY_CAPABILITY; import static com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy.NETWORK_NODE_PROXY_CAPABILITY;
public class NetworkNodeGraph implements INetworkNodeGraph { public class NetworkNodeGraph implements INetworkNodeGraph {
private TileController controller; private INetwork network;
private Set<INetworkNode> nodes = Sets.newConcurrentHashSet(); private Set<INetworkNode> nodes = Sets.newConcurrentHashSet();
private List<INetworkNodeGraphListener> listeners = new LinkedList<>();
private Set<Consumer<INetwork>> actions = new HashSet<>(); private Set<Consumer<INetwork>> actions = new HashSet<>();
private boolean invalidating = false; private boolean invalidating = false;
public NetworkNodeGraph(TileController controller) { public NetworkNodeGraph(INetwork network) {
this.controller = controller; this.network = network;
} }
@Override @Override
public void invalidate(Action action, BlockPos origin) { public void invalidate(Action action, World world, BlockPos origin) {
this.invalidating = true; this.invalidating = true;
Operator operator = new Operator(action); Operator operator = new Operator(action);
World controllerWorld = controller.getWorld(); TileEntity tile = world.getTileEntity(origin);
if (tile != null && tile.hasCapability(CapabilityNetworkNodeProxy.NETWORK_NODE_PROXY_CAPABILITY, null)) {
INetworkNodeProxy proxy = tile.getCapability(CapabilityNetworkNodeProxy.NETWORK_NODE_PROXY_CAPABILITY, null);
for (EnumFacing facing : EnumFacing.VALUES) { if (proxy != null) {
BlockPos pos = origin.offset(facing); INetworkNode node = proxy.getNode();
// Little hack to support not conducting through covers (if the cover is right next to the controller). if (node instanceof INetworkNodeVisitor) {
TileEntity tile = controllerWorld.getTileEntity(pos); ((INetworkNodeVisitor) node).visit(operator);
if (tile != null && tile.hasCapability(NETWORK_NODE_PROXY_CAPABILITY, facing.getOpposite())) {
INetworkNodeProxy otherNodeProxy = NETWORK_NODE_PROXY_CAPABILITY.cast(tile.getCapability(NETWORK_NODE_PROXY_CAPABILITY, facing.getOpposite()));
INetworkNode otherNode = otherNodeProxy.getNode();
if (otherNode instanceof ICoverable && ((ICoverable) otherNode).getCoverManager().hasCover(facing.getOpposite())) {
continue;
} }
} }
// End little hack.
operator.apply(controllerWorld, pos, facing.getOpposite());
} }
Visitor currentVisitor; Visitor currentVisitor;
@@ -73,29 +66,30 @@ public class NetworkNodeGraph implements INetworkNodeGraph {
if (action == Action.PERFORM) { if (action == Action.PERFORM) {
for (INetworkNode node : operator.newNodes) { for (INetworkNode node : operator.newNodes) {
node.onConnected(controller); node.onConnected(network);
} }
for (INetworkNode node : operator.previousNodes) { for (INetworkNode node : operator.previousNodes) {
node.onDisconnected(controller); node.onDisconnected(network);
} }
actions.forEach(h -> h.accept(controller)); actions.forEach(h -> h.accept(network));
actions.clear(); actions.clear();
if (!operator.newNodes.isEmpty() || !operator.previousNodes.isEmpty()) { if (!operator.newNodes.isEmpty() || !operator.previousNodes.isEmpty()) {
controller.getDataManager().sendParameterToWatchers(TileController.NODES); listeners.forEach(INetworkNodeGraphListener::onChanged);
} }
} }
invalidating = false; this.invalidating = false;
} }
@Override @Override
@SuppressWarnings("deprecation")
public INetwork getNetworkForBCReasons() { public INetwork getNetworkForBCReasons() {
OneSixMigrationHelper.removalHook(); OneSixMigrationHelper.removalHook();
return controller; return network;
} }
@Override @Override
@@ -103,7 +97,7 @@ public class NetworkNodeGraph implements INetworkNodeGraph {
if (invalidating) { if (invalidating) {
actions.add(handler); actions.add(handler);
} else { } else {
handler.accept(controller); handler.accept(network);
} }
} }
@@ -112,20 +106,25 @@ public class NetworkNodeGraph implements INetworkNodeGraph {
return nodes; return nodes;
} }
@Override
public void addListener(INetworkNodeGraphListener listener) {
listeners.add(listener);
}
@Override @Override
public void disconnectAll() { public void disconnectAll() {
nodes.forEach(n -> n.onDisconnected(controller)); nodes.forEach(n -> n.onDisconnected(network));
nodes.clear(); nodes.clear();
controller.getDataManager().sendParameterToWatchers(TileController.NODES); listeners.forEach(INetworkNodeGraphListener::onChanged);
} }
protected World getWorld() { protected World getWorld() {
return controller.getWorld(); return network.world();
} }
private void dropConflictingBlock(World world, BlockPos pos) { private void dropConflictingBlock(World world, BlockPos pos) {
if (!controller.getPos().equals(pos)) { if (!network.getPosition().equals(pos)) {
IBlockState state = world.getBlockState(pos); IBlockState state = world.getBlockState(pos);
NonNullList<ItemStack> drops = NonNullList.create(); NonNullList<ItemStack> drops = NonNullList.create();
@@ -162,7 +161,7 @@ public class NetworkNodeGraph implements INetworkNodeGraph {
INetworkNode otherNode = otherNodeProxy.getNode(); INetworkNode otherNode = otherNodeProxy.getNode();
// This will work for regular nodes and for controllers too since controllers are internally a INetworkNode (and return themselves in INetworkNode#getNetwork). // 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) { if (otherNode.getNetwork() != null && otherNode.getNetwork() != network) {
if (action == Action.PERFORM) { if (action == Action.PERFORM) {
dropConflictingBlock(world, tile.getPos()); dropConflictingBlock(world, tile.getPos());
} }
@@ -184,6 +183,11 @@ public class NetworkNodeGraph implements INetworkNodeGraph {
} }
} }
} }
@Override
public Action getAction() {
return action;
}
} }
private class Visitor implements INetworkNodeVisitor { private class Visitor implements INetworkNodeVisitor {

View File

@@ -40,7 +40,13 @@ public abstract class NetworkNode implements INetworkNode, INetworkNodeVisitor {
private EnumFacing direction = EnumFacing.NORTH; private EnumFacing direction = EnumFacing.NORTH;
private boolean throttlingDisabled; // Disable throttling for the first tick.
// This is to make sure couldUpdate is going to be correctly set.
// If we place 2 blocks next to each other, and disconnect the first one really fast,
// the second one would not realize it has been disconnected because couldUpdate == canUpdate.
// It would however still have the connected state, due to the initial block update packet.
// The couldUpdate/canUpdate system is separate from that.
private boolean throttlingDisabled = true;
private boolean couldUpdate; private boolean couldUpdate;
private int ticksSinceUpdateChanged; private int ticksSinceUpdateChanged;
@@ -125,7 +131,7 @@ public abstract class NetworkNode implements INetworkNode, INetworkNodeVisitor {
public void update() { public void update() {
++ticks; ++ticks;
boolean canUpdate = getNetwork() != null && canUpdate(); boolean canUpdate = canUpdate();
if (couldUpdate != canUpdate) { if (couldUpdate != canUpdate) {
++ticksSinceUpdateChanged; ++ticksSinceUpdateChanged;
@@ -143,7 +149,7 @@ public abstract class NetworkNode implements INetworkNode, INetworkNodeVisitor {
onConnectedStateChange(network, canUpdate); onConnectedStateChange(network, canUpdate);
if (shouldRebuildGraphOnChange()) { if (shouldRebuildGraphOnChange()) {
network.getNodeGraph().invalidate(Action.PERFORM, network.getPosition()); network.getNodeGraph().invalidate(Action.PERFORM, network.world(), network.getPosition());
} }
} }
} }

View File

@@ -84,7 +84,7 @@ public class NetworkNodeConstructor extends NetworkNode implements IComparable,
public void update() { public void update() {
super.update(); super.update();
if (network != null && canUpdate() && ticks % upgrades.getSpeed(BASE_SPEED, 4) == 0) { if (canUpdate() && ticks % upgrades.getSpeed(BASE_SPEED, 4) == 0) {
if (type == IType.ITEMS && !itemFilters.getStackInSlot(0).isEmpty()) { if (type == IType.ITEMS && !itemFilters.getStackInSlot(0).isEmpty()) {
ItemStack item = itemFilters.getStackInSlot(0); ItemStack item = itemFilters.getStackInSlot(0);

View File

@@ -90,7 +90,7 @@ public class NetworkNodeDestructor extends NetworkNode implements IComparable, I
public void update() { public void update() {
super.update(); super.update();
if (network != null && canUpdate() && ticks % upgrades.getSpeed(BASE_SPEED, 4) == 0) { if (canUpdate() && ticks % upgrades.getSpeed(BASE_SPEED, 4) == 0) {
BlockPos front = pos.offset(getDirection()); BlockPos front = pos.offset(getDirection());
if (pickupItem && type == IType.ITEMS) { if (pickupItem && type == IType.ITEMS) {

View File

@@ -68,7 +68,7 @@ public class NetworkNodeDetector extends NetworkNode implements IComparable, ITy
WorldUtils.updateBlock(world, pos); WorldUtils.updateBlock(world, pos);
} }
if (network != null && canUpdate() && ticks % SPEED == 0) { if (canUpdate() && ticks % SPEED == 0) {
if (type == IType.ITEMS) { if (type == IType.ITEMS) {
ItemStack slot = itemFilters.getStackInSlot(0); ItemStack slot = itemFilters.getStackInSlot(0);

View File

@@ -63,7 +63,7 @@ public class NetworkNodeExporter extends NetworkNode implements IComparable, ITy
public void update() { public void update() {
super.update(); super.update();
if (network != null && canUpdate() && ticks % upgrades.getSpeed() == 0) { if (canUpdate() && ticks % upgrades.getSpeed() == 0) {
if (type == IType.ITEMS) { if (type == IType.ITEMS) {
IItemHandler handler = WorldUtils.getItemHandler(getFacingTile(), getDirection().getOpposite()); IItemHandler handler = WorldUtils.getItemHandler(getFacingTile(), getDirection().getOpposite());

View File

@@ -71,7 +71,7 @@ public class NetworkNodeFluidInterface extends NetworkNode {
public void update() { public void update() {
super.update(); super.update();
if (network != null && canUpdate()) { if (canUpdate()) {
ItemStack container = in.getStackInSlot(0); ItemStack container = in.getStackInSlot(0);
if (!container.isEmpty()) { if (!container.isEmpty()) {

View File

@@ -68,7 +68,7 @@ public class NetworkNodeImporter extends NetworkNode implements IComparable, IFi
public void update() { public void update() {
super.update(); super.update();
if (network == null || !canUpdate()) { if (!canUpdate()) {
return; return;
} }

View File

@@ -53,7 +53,7 @@ public class NetworkNodeInterface extends NetworkNode implements IComparable {
public void update() { public void update() {
super.update(); super.update();
if (network == null || !canUpdate()) { if (!canUpdate()) {
return; return;
} }

View File

@@ -29,7 +29,7 @@ public class NetworkNodeNetworkTransmitter extends NetworkNode {
super.onContentsChanged(slot); super.onContentsChanged(slot);
if (network != null) { if (network != null) {
network.getNodeGraph().invalidate(Action.PERFORM, network.getPosition()); network.getNodeGraph().invalidate(Action.PERFORM, network.world(), network.getPosition());
} }
} }
}; };
@@ -49,7 +49,7 @@ public class NetworkNodeNetworkTransmitter extends NetworkNode {
} }
if (network != null) { if (network != null) {
network.getNodeGraph().invalidate(Action.PERFORM, network.getPosition()); network.getNodeGraph().invalidate(Action.PERFORM, network.world(), network.getPosition());
} }
} }
}; };

View File

@@ -81,7 +81,7 @@ public class CoverManager {
node.markDirty(); node.markDirty();
if (node.getNetwork() != null) { if (node.getNetwork() != null) {
node.getNetwork().getNodeGraph().invalidate(Action.PERFORM, node.getNetwork().getPosition()); node.getNetwork().getNodeGraph().invalidate(Action.PERFORM, node.getNetwork().world(), node.getNetwork().getPosition());
} }
return true; return true;

View File

@@ -135,7 +135,7 @@ public class NetworkNodeDiskManipulator extends NetworkNode implements IComparab
public void update() { public void update() {
super.update(); super.update();
if (network == null || !canUpdate() || ticks % upgrades.getSpeed() != 0) { if (!canUpdate() || ticks % upgrades.getSpeed() != 0) {
return; return;
} }

View File

@@ -53,7 +53,7 @@ public abstract class BlockNode extends BlockNodeProxy {
manager.markForSaving(); manager.markForSaving();
if (node != null && node.getNetwork() != null) { if (node != null && node.getNetwork() != null) {
node.getNetwork().getNodeGraph().invalidate(Action.PERFORM, node.getNetwork().getPosition()); node.getNetwork().getNodeGraph().invalidate(Action.PERFORM, node.getNetwork().world(), node.getNetwork().getPosition());
} }
} }

View File

@@ -123,16 +123,4 @@ public abstract class TileBase extends TileEntity {
world.markChunkDirty(pos, this); world.markChunkDirty(pos, this);
} }
} }
@Override
public boolean equals(Object o) {
return o instanceof TileBase && ((TileBase) o).getPos().equals(pos) && ((TileBase) o).world.provider.getDimension() == world.provider.getDimension();
}
@Override
public int hashCode() {
int result = pos.hashCode();
result = 31 * result + world.provider.getDimension();
return result;
}
} }

View File

@@ -7,6 +7,7 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingManager;
import com.raoulvdberge.refinedstorage.api.energy.IEnergy; import com.raoulvdberge.refinedstorage.api.energy.IEnergy;
import com.raoulvdberge.refinedstorage.api.network.INetwork; import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.api.network.INetworkNodeGraph; import com.raoulvdberge.refinedstorage.api.network.INetworkNodeGraph;
import com.raoulvdberge.refinedstorage.api.network.INetworkNodeVisitor;
import com.raoulvdberge.refinedstorage.api.network.grid.handler.IFluidGridHandler; import com.raoulvdberge.refinedstorage.api.network.grid.handler.IFluidGridHandler;
import com.raoulvdberge.refinedstorage.api.network.grid.handler.IItemGridHandler; import com.raoulvdberge.refinedstorage.api.network.grid.handler.IItemGridHandler;
import com.raoulvdberge.refinedstorage.api.network.item.INetworkItemHandler; import com.raoulvdberge.refinedstorage.api.network.item.INetworkItemHandler;
@@ -21,12 +22,14 @@ import com.raoulvdberge.refinedstorage.api.storage.IStorageCache;
import com.raoulvdberge.refinedstorage.api.storage.IStorageTracker; import com.raoulvdberge.refinedstorage.api.storage.IStorageTracker;
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IStorageExternal; import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IStorageExternal;
import com.raoulvdberge.refinedstorage.api.util.Action; import com.raoulvdberge.refinedstorage.api.util.Action;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.CraftingManager; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.CraftingManager;
import com.raoulvdberge.refinedstorage.apiimpl.energy.Energy; import com.raoulvdberge.refinedstorage.apiimpl.energy.Energy;
import com.raoulvdberge.refinedstorage.apiimpl.network.NetworkNodeGraph; import com.raoulvdberge.refinedstorage.apiimpl.network.NetworkNodeGraph;
import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.FluidGridHandler; import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.FluidGridHandler;
import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.ItemGridHandler; import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.ItemGridHandler;
import com.raoulvdberge.refinedstorage.apiimpl.network.item.NetworkItemHandler; import com.raoulvdberge.refinedstorage.apiimpl.network.item.NetworkItemHandler;
import com.raoulvdberge.refinedstorage.apiimpl.network.node.ICoverable;
import com.raoulvdberge.refinedstorage.apiimpl.network.readerwriter.ReaderWriterManager; import com.raoulvdberge.refinedstorage.apiimpl.network.readerwriter.ReaderWriterManager;
import com.raoulvdberge.refinedstorage.apiimpl.network.security.SecurityManager; import com.raoulvdberge.refinedstorage.apiimpl.network.security.SecurityManager;
import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheFluid; import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheFluid;
@@ -49,6 +52,7 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataSerializers; import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable; import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@@ -66,7 +70,9 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.function.Predicate; import java.util.function.Predicate;
public class TileController extends TileBase implements ITickable, INetwork, IRedstoneConfigurable, INetworkNode, INetworkNodeProxy<TileController> { import static com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy.NETWORK_NODE_PROXY_CAPABILITY;
public class TileController extends TileBase implements ITickable, INetwork, IRedstoneConfigurable, INetworkNode, INetworkNodeProxy<TileController>, INetworkNodeVisitor {
private static final Comparator<ClientNode> CLIENT_NODE_COMPARATOR = (left, right) -> { private static final Comparator<ClientNode> CLIENT_NODE_COMPARATOR = (left, right) -> {
if (left.getEnergyUsage() == right.getEnergyUsage()) { if (left.getEnergyUsage() == right.getEnergyUsage()) {
return 0; return 0;
@@ -164,6 +170,8 @@ public class TileController extends TileBase implements ITickable, INetwork, IRe
markDirty(); markDirty();
} }
}); });
nodeGraph.addListener(() -> dataManager.sendParameterToWatchers(TileController.NODES));
} }
@Override @Override
@@ -231,7 +239,7 @@ public class TileController extends TileBase implements ITickable, INetwork, IRe
couldRun = canRun; couldRun = canRun;
throttlingDisabled = false; throttlingDisabled = false;
nodeGraph.invalidate(Action.PERFORM, pos); nodeGraph.invalidate(Action.PERFORM, world, pos);
securityManager.invalidate(); securityManager.invalidate();
} }
} else { } else {
@@ -682,4 +690,34 @@ public class TileController extends TileBase implements ITickable, INetwork, IRe
public TileController getNode() { public TileController getNode() {
return this; return this;
} }
@Override
public void visit(Operator operator) {
for (EnumFacing facing : EnumFacing.VALUES) {
BlockPos pos = this.pos.offset(facing);
TileEntity tile = world.getTileEntity(pos);
if (tile != null && tile.hasCapability(NETWORK_NODE_PROXY_CAPABILITY, facing.getOpposite())) {
INetworkNodeProxy otherNodeProxy = NETWORK_NODE_PROXY_CAPABILITY.cast(tile.getCapability(NETWORK_NODE_PROXY_CAPABILITY, facing.getOpposite()));
INetworkNode otherNode = otherNodeProxy.getNode();
if (otherNode instanceof ICoverable && ((ICoverable) otherNode).getCoverManager().hasCover(facing.getOpposite())) {
continue;
}
}
operator.apply(world, pos, facing.getOpposite());
}
}
@Override
public boolean equals(Object o) {
return API.instance().isNetworkNodeEqual(this, o);
}
@Override
public int hashCode() {
return API.instance().getNetworkNodeHashCode(this);
}
} }

View File

@@ -86,7 +86,7 @@ public class TileDiskDrive extends TileNode<NetworkNodeDiskDrive> {
public NBTTagCompound writeUpdate(NBTTagCompound tag) { public NBTTagCompound writeUpdate(NBTTagCompound tag) {
super.writeUpdate(tag); super.writeUpdate(tag);
writeDiskState(tag, 8, getNode().getNetwork() != null && getNode().canUpdate(), getNode().getItemDisks(), getNode().getFluidDisks()); writeDiskState(tag, 8, getNode().canUpdate(), getNode().getItemDisks(), getNode().getFluidDisks());
return tag; return tag;
} }

View File

@@ -40,7 +40,7 @@ public class TileDiskManipulator extends TileNode<NetworkNodeDiskManipulator> {
public NBTTagCompound writeUpdate(NBTTagCompound tag) { public NBTTagCompound writeUpdate(NBTTagCompound tag) {
super.writeUpdate(tag); super.writeUpdate(tag);
TileDiskDrive.writeDiskState(tag, 6, getNode().getNetwork() != null && getNode().canUpdate(), getNode().getItemDisks(), getNode().getFluidDisks()); TileDiskDrive.writeDiskState(tag, 6, getNode().canUpdate(), getNode().getItemDisks(), getNode().getFluidDisks());
return tag; return tag;
} }

View File

@@ -54,7 +54,7 @@ public abstract class TileNode<N extends NetworkNode> extends TileBase implement
tag.setTag(NBT_COVERS, ((ICoverable) getNode()).getCoverManager().writeToNbt()); tag.setTag(NBT_COVERS, ((ICoverable) getNode()).getCoverManager().writeToNbt());
} }
tag.setBoolean(NBT_ACTIVE, getNode().getNetwork() != null && getNode().canUpdate()); tag.setBoolean(NBT_ACTIVE, getNode().canUpdate());
return tag; return tag;
} }

View File

@@ -73,7 +73,7 @@ public class TileReader extends TileNode<NetworkNodeReader> {
} }
} }
if (reader.getNetwork() == null || !reader.canUpdate()) { if (!reader.canUpdate()) {
return (T) dummyCap; return (T) dummyCap;
} }

View File

@@ -61,7 +61,7 @@ public class TileWriter extends TileNode<NetworkNodeWriter> {
} }
} }
if (writer.getNetwork() == null || !writer.canUpdate()) { if (!writer.canUpdate()) {
return (T) dummyCap; return (T) dummyCap;
} }