diff --git a/src/main/java/refinedstorage/api/network/INetworkMaster.java b/src/main/java/refinedstorage/api/network/INetworkMaster.java index 32d5ac2b7..a2fd83879 100755 --- a/src/main/java/refinedstorage/api/network/INetworkMaster.java +++ b/src/main/java/refinedstorage/api/network/INetworkMaster.java @@ -43,14 +43,9 @@ public interface INetworkMaster { List getNodes(); /** - * @param node The node to add + * @param nodes The nodes to set */ - void addNode(@Nonnull INetworkNode node); - - /** - * @param node The node to remove - */ - void removeNode(@Nonnull INetworkNode node); + void setNodes(List nodes); /** * @return The {@link IGridHandler} for this network diff --git a/src/main/java/refinedstorage/api/network/INetworkNode.java b/src/main/java/refinedstorage/api/network/INetworkNode.java index b1e3f7301..d3c2bcd79 100755 --- a/src/main/java/refinedstorage/api/network/INetworkNode.java +++ b/src/main/java/refinedstorage/api/network/INetworkNode.java @@ -28,26 +28,32 @@ public interface INetworkNode { BlockPos getPosition(); /** - * Called when the neighbor of this node is changed. Typically used to check if there is still a connection to the network. + * Called when this node is placed in the world. * * @param world The world */ - void refreshConnection(World world); + void onPlaced(World world); /** - * Called when a connection is found to the network - * - * @param world The world - * @param network The network we're trying to connect to - */ - void connect(World world, INetworkMaster network); - - /** - * Called when a connection is lost to the network + * Called when this node is removed from the world. * * @param world The world */ - void disconnect(World world); + void onBreak(World world); + + /** + * Called when this node is connected to a network. + * + * @param network The network + */ + void onConnected(INetworkMaster network); + + /** + * Called when this node is disconnected from a network. + */ + void onDisconnected(); + + void onConnectionChange(INetworkMaster network, boolean state); /** * @return If we are connected diff --git a/src/main/java/refinedstorage/block/BlockController.java b/src/main/java/refinedstorage/block/BlockController.java index 51614cb64..2b6058896 100755 --- a/src/main/java/refinedstorage/block/BlockController.java +++ b/src/main/java/refinedstorage/block/BlockController.java @@ -105,7 +105,7 @@ public class BlockController extends BlockBase { @Override public void breakBlock(World world, BlockPos pos, IBlockState state) { if (!world.isRemote) { - ((TileController) world.getTileEntity(pos)).disconnectNodes(); + ((TileController) world.getTileEntity(pos)).onBreak(); } super.breakBlock(world, pos, state); diff --git a/src/main/java/refinedstorage/block/BlockNode.java b/src/main/java/refinedstorage/block/BlockNode.java index f38e53107..03fb032b9 100755 --- a/src/main/java/refinedstorage/block/BlockNode.java +++ b/src/main/java/refinedstorage/block/BlockNode.java @@ -1,6 +1,5 @@ package refinedstorage.block; -import net.minecraft.block.Block; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.state.BlockStateContainer; @@ -43,7 +42,7 @@ public abstract class BlockNode extends BlockBase { super.onBlockPlacedBy(world, pos, state, player, stack); if (!world.isRemote) { - ((TileNode) world.getTileEntity(pos)).refreshConnection(world); + ((TileNode) world.getTileEntity(pos)).onPlaced(world); } } @@ -53,19 +52,10 @@ public abstract class BlockNode extends BlockBase { TileNode node = (TileNode) world.getTileEntity(pos); if (node.isConnected()) { - node.disconnect(world); + node.onBreak(world); } } super.breakBlock(world, pos, state); } - - @Override - public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block) { - super.neighborChanged(state, world, pos, block); - - if (!world.isRemote) { - ((TileNode) world.getTileEntity(pos)).refreshConnection(world); - } - } } diff --git a/src/main/java/refinedstorage/tile/IConnectionHandler.java b/src/main/java/refinedstorage/tile/IConnectionHandler.java deleted file mode 100755 index ef4e359f2..000000000 --- a/src/main/java/refinedstorage/tile/IConnectionHandler.java +++ /dev/null @@ -1,9 +0,0 @@ -package refinedstorage.tile; - -import refinedstorage.api.network.INetworkMaster; - -public interface IConnectionHandler { - void onConnected(INetworkMaster network); - - void onDisconnected(INetworkMaster network); -} diff --git a/src/main/java/refinedstorage/tile/TileCrafter.java b/src/main/java/refinedstorage/tile/TileCrafter.java index bdebf3134..84925ae67 100755 --- a/src/main/java/refinedstorage/tile/TileCrafter.java +++ b/src/main/java/refinedstorage/tile/TileCrafter.java @@ -4,7 +4,6 @@ import net.minecraft.inventory.Container; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; -import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; @@ -22,7 +21,7 @@ import refinedstorage.inventory.IItemValidator; import refinedstorage.item.ItemPattern; import refinedstorage.item.ItemUpgrade; -public class TileCrafter extends TileNode implements ICraftingPatternContainer, IConnectionHandler { +public class TileCrafter extends TileNode implements ICraftingPatternContainer { private BasicItemHandler patterns = new BasicItemHandler(9, this, new IItemValidator() { @Override public boolean valid(ItemStack stack) { @@ -64,14 +63,16 @@ public class TileCrafter extends TileNode implements ICraftingPatternContainer, } @Override - public void disconnect(World world) { - for (ICraftingTask task : network.getCraftingTasks()) { - if (task.getPattern().getContainer(world) == this) { - network.cancelCraftingTask(task); + public void onConnectionChange(INetworkMaster network, boolean state) { + if (!state) { + for (ICraftingTask task : network.getCraftingTasks()) { + if (task.getPattern().getContainer(worldObj) == this) { + network.cancelCraftingTask(task); + } } } - super.disconnect(world); + network.rebuildPatterns(); } @Override @@ -128,14 +129,4 @@ public class TileCrafter extends TileNode implements ICraftingPatternContainer, public boolean hasCapability(Capability capability, EnumFacing facing) { return (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY && facing != getDirection()) || super.hasCapability(capability, facing); } - - @Override - public void onConnected(INetworkMaster network) { - network.rebuildPatterns(); - } - - @Override - public void onDisconnected(INetworkMaster network) { - network.rebuildPatterns(); - } } diff --git a/src/main/java/refinedstorage/tile/TileDetector.java b/src/main/java/refinedstorage/tile/TileDetector.java index 22826eb5a..7c6dd9bc6 100755 --- a/src/main/java/refinedstorage/tile/TileDetector.java +++ b/src/main/java/refinedstorage/tile/TileDetector.java @@ -4,11 +4,11 @@ import io.netty.buffer.ByteBuf; import net.minecraft.inventory.Container; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; import net.minecraftforge.items.IItemHandler; import refinedstorage.RefinedStorage; import refinedstorage.RefinedStorageBlocks; import refinedstorage.RefinedStorageUtils; +import refinedstorage.api.network.INetworkMaster; import refinedstorage.container.ContainerDetector; import refinedstorage.inventory.BasicItemHandler; import refinedstorage.tile.config.ICompareConfig; @@ -34,13 +34,6 @@ public class TileDetector extends TileNode implements ICompareConfig { private boolean powered = false; - @Override - public void disconnect(World world) { - powered = false; - - super.disconnect(world); - } - @Override public int getEnergyUsage() { return RefinedStorage.INSTANCE.detectorUsage; @@ -89,6 +82,15 @@ public class TileDetector extends TileNode implements ICompareConfig { } } + @Override + public void onConnectionChange(INetworkMaster network, boolean state) { + super.onConnectionChange(network, state); + + if (!state) { + powered = false; + } + } + public boolean isPowered() { return powered; } diff --git a/src/main/java/refinedstorage/tile/TileDiskDrive.java b/src/main/java/refinedstorage/tile/TileDiskDrive.java index 0a93d3172..39fda929b 100755 --- a/src/main/java/refinedstorage/tile/TileDiskDrive.java +++ b/src/main/java/refinedstorage/tile/TileDiskDrive.java @@ -26,7 +26,7 @@ import refinedstorage.tile.config.*; import java.util.List; -public class TileDiskDrive extends TileNode implements IStorageProvider, IStorageGui, ICompareConfig, IModeConfig, IConnectionHandler { +public class TileDiskDrive extends TileNode implements IStorageProvider, IStorageGui, ICompareConfig, IModeConfig { public class Storage extends NBTStorage { public Storage(ItemStack disk) { super(disk.getTagCompound(), EnumStorageType.getById(disk.getItemDamage()).getCapacity(), TileDiskDrive.this); @@ -104,14 +104,21 @@ public class TileDiskDrive extends TileNode implements IStorageProvider, IStorag } @Override - public void disconnect(World world) { - super.disconnect(world); + public void onConnectionChange(INetworkMaster network, boolean state) { + super.onConnectionChange(network, state); + network.getStorage().rebuild(); + } + + @Override + public void onBreak(World world) { for (Storage storage : this.storages) { if (storage != null) { storage.writeToNBT(); } } + + super.onBreak(world); } @Override @@ -309,14 +316,4 @@ public class TileDiskDrive extends TileNode implements IStorageProvider, IStorag public boolean hasCapability(Capability capability, EnumFacing facing) { return capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing); } - - @Override - public void onConnected(INetworkMaster network) { - network.getStorage().rebuild(); - } - - @Override - public void onDisconnected(INetworkMaster network) { - network.getStorage().rebuild(); - } } diff --git a/src/main/java/refinedstorage/tile/TileNode.java b/src/main/java/refinedstorage/tile/TileNode.java index 99f9c8fea..001a06fea 100755 --- a/src/main/java/refinedstorage/tile/TileNode.java +++ b/src/main/java/refinedstorage/tile/TileNode.java @@ -13,10 +13,8 @@ import refinedstorage.api.network.INetworkMaster; import refinedstorage.api.network.INetworkNode; import refinedstorage.tile.config.IRedstoneModeConfig; import refinedstorage.tile.config.RedstoneMode; -import refinedstorage.tile.controller.TileController; -import java.util.HashSet; -import java.util.Set; +import java.util.*; public abstract class TileNode extends TileBase implements INetworkNode, ISynchronizedContainer, IRedstoneModeConfig { private static final String NBT_CONNECTED = "Connected"; @@ -45,21 +43,10 @@ public abstract class TileNode extends TileBase implements INetworkNode, ISynchr @Override public void update() { if (!worldObj.isRemote) { - if (ticks == 0) { - refreshConnection(worldObj); - } else { - // @TODO: Fix updating twice on block placement - if (update != canUpdate()) { - if (network != null && this instanceof IConnectionHandler) { - if (canUpdate()) { - ((IConnectionHandler) this).onConnected(network); - } else { - ((IConnectionHandler) this).onDisconnected(network); - } - } + if (update != canUpdate() && network != null) { + update = canUpdate(); - update = canUpdate(); - } + onConnectionChange(network, update); } if (isActive()) { @@ -77,80 +64,147 @@ public abstract class TileNode extends TileBase implements INetworkNode, ISynchr } @Override - public void connect(World world, INetworkMaster network) { - if (network.canRun()) { - this.network = network; - this.connected = true; + public void onPlaced(World world) { + List nodes = new ArrayList(); + Set nodesPos = new HashSet(); - this.network.addNode(this); + Queue positions = new ArrayDeque(); + Set checked = new HashSet(); - world.notifyNeighborsOfStateChange(pos, getBlockType()); + nodes.add(this); + positions.add(pos); - if (canSendConnectivityUpdate()) { - RefinedStorageUtils.updateBlock(world, pos); - } - } - } + INetworkMaster master = null; - @Override - public void disconnect(World world) { - this.connected = false; + BlockPos currentPos; - if (this.network != null) { - this.network.removeNode(this); - this.network = null; - } + while ((currentPos = positions.poll()) != null) { + TileEntity tile = world.getTileEntity(currentPos); - world.notifyNeighborsOfStateChange(pos, getBlockType()); - - if (canSendConnectivityUpdate()) { - RefinedStorageUtils.updateBlock(world, pos); - } - } - - @Override - public void refreshConnection(World world) { - TileController controller = searchController(world, pos, new HashSet()); - - if (network == null) { - if (controller != null) { - connect(world, controller); - } - } else { - if (controller == null) { - disconnect(world); - } - } - } - - private TileController searchController(World world, BlockPos current, Set visits) { - long pos = current.toLong(); - - if (visits.contains(pos)) { - return null; - } - - visits.add(pos); - - TileEntity tile = world.getTileEntity(current); - - if (tile instanceof TileController) { - return (TileController) tile; - } else if (tile instanceof TileNode) { - if (visits.size() > 1 && tile instanceof TileRelay && !((TileRelay) tile).canUpdate()) { - return null; + if (tile instanceof INetworkMaster) { + master = (INetworkMaster) tile; + continue; } - for (EnumFacing dir : EnumFacing.VALUES) { - TileController controller = searchController(world, current.offset(dir), visits); + if (tile == null || !tile.hasCapability(RefinedStorageCapabilities.NETWORK_NODE_CAPABILITY, null)) { + continue; + } - if (controller != null) { - return controller; + INetworkNode node = tile.getCapability(RefinedStorageCapabilities.NETWORK_NODE_CAPABILITY, null); + + nodes.add(node); + nodesPos.add(node.getPosition()); + + for (EnumFacing sideOnCurrent : EnumFacing.VALUES) { + BlockPos sidePos = currentPos.offset(sideOnCurrent); + + if (checked.add(sidePos)) { + positions.add(sidePos); } } } - return null; + if (master != null) { + for (INetworkNode newNode : nodes) { + boolean isNew = false; + + for (INetworkNode oldNode : master.getNodes()) { + if (oldNode.getPosition().equals(newNode.getPosition())) { + isNew = true; + break; + } + } + + if (!isNew) { + newNode.onConnected(master); + } + } + + master.setNodes(nodes); + } + } + + @Override + public void onBreak(World world) { + List nodes = new ArrayList(); + Set nodesPos = new HashSet(); + + Queue positions = new ArrayDeque(); + Set checked = new HashSet(); + + checked.add(pos); + + for (EnumFacing side : EnumFacing.VALUES) { + BlockPos sidePos = pos.offset(side); + + if (!checked.add(sidePos)) { + continue; + } + + positions.add(sidePos); + + BlockPos currentPos; + + while ((currentPos = positions.poll()) != null) { + TileEntity tile = world.getTileEntity(currentPos); + + if (tile == null || !tile.hasCapability(RefinedStorageCapabilities.NETWORK_NODE_CAPABILITY, null)) { + continue; + } + + INetworkNode node = tile.getCapability(RefinedStorageCapabilities.NETWORK_NODE_CAPABILITY, null); + + nodes.add(node); + nodesPos.add(currentPos); + + for (EnumFacing sideOfCurrent : EnumFacing.VALUES) { + BlockPos sideOfCurrentPos = currentPos.offset(sideOfCurrent); + + if (checked.add(sideOfCurrentPos)) { + positions.add(sideOfCurrentPos); + } + } + } + } + + List oldNodes = network.getNodes(); + + network.setNodes(nodes); + + for (INetworkNode oldNode : oldNodes) { + if (!nodesPos.contains(oldNode.getPosition())) { + oldNode.onDisconnected(); + } + } + } + + @Override + public void onConnected(INetworkMaster network) { + onConnectionChange(network, true); + + this.connected = true; + this.network = network; + + if (canSendConnectivityUpdate()) { + RefinedStorageUtils.updateBlock(worldObj, pos); + } + } + + @Override + public void onDisconnected() { + onConnectionChange(network, false); + + this.connected = false; + this.network = null; + + if (canSendConnectivityUpdate()) { + RefinedStorageUtils.updateBlock(worldObj, pos); + } + } + + @Override + public void onConnectionChange(INetworkMaster network, boolean state) { + // NO OP } @Override diff --git a/src/main/java/refinedstorage/tile/TileSolderer.java b/src/main/java/refinedstorage/tile/TileSolderer.java index c1851c464..8f354d898 100755 --- a/src/main/java/refinedstorage/tile/TileSolderer.java +++ b/src/main/java/refinedstorage/tile/TileSolderer.java @@ -4,7 +4,6 @@ import io.netty.buffer.ByteBuf; import net.minecraft.inventory.Container; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; -import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; @@ -13,6 +12,7 @@ import refinedstorage.RefinedStorage; import refinedstorage.RefinedStorageItems; import refinedstorage.RefinedStorageUtils; import refinedstorage.api.RefinedStorageAPI; +import refinedstorage.api.network.INetworkMaster; import refinedstorage.api.solderer.ISoldererRecipe; import refinedstorage.container.ContainerSolderer; import refinedstorage.inventory.BasicItemHandler; @@ -92,10 +92,12 @@ public class TileSolderer extends TileNode { } @Override - public void disconnect(World world) { - stop(); + public void onConnectionChange(INetworkMaster network, boolean state) { + super.onConnectionChange(network, state); - super.disconnect(world); + if (!state) { + stop(); + } } public void stop() { diff --git a/src/main/java/refinedstorage/tile/TileStorage.java b/src/main/java/refinedstorage/tile/TileStorage.java index f08ce5fda..94d8bb707 100755 --- a/src/main/java/refinedstorage/tile/TileStorage.java +++ b/src/main/java/refinedstorage/tile/TileStorage.java @@ -23,7 +23,7 @@ import refinedstorage.tile.config.*; import java.util.List; -public class TileStorage extends TileNode implements IStorageProvider, IStorageGui, ICompareConfig, IModeConfig, IConnectionHandler { +public class TileStorage extends TileNode implements IStorageProvider, IStorageGui, ICompareConfig, IModeConfig { class Storage extends NBTStorage { public Storage() { super(TileStorage.this.getStorageTag(), TileStorage.this.getCapacity(), TileStorage.this); @@ -82,12 +82,19 @@ public class TileStorage extends TileNode implements IStorageProvider, IStorageG } @Override - public void disconnect(World world) { - super.disconnect(world); + public void onConnectionChange(INetworkMaster network, boolean state) { + super.onConnectionChange(network, state); + network.getStorage().rebuild(); + } + + @Override + public void onBreak(World world) { if (storage != null) { storage.writeToNBT(); } + + super.onBreak(world); } @Override @@ -258,14 +265,4 @@ public class TileStorage extends TileNode implements IStorageProvider, IStorageG public int getCapacity() { return getType().getCapacity(); } - - @Override - public void onConnected(INetworkMaster network) { - network.getStorage().rebuild(); - } - - @Override - public void onDisconnected(INetworkMaster network) { - network.getStorage().rebuild(); - } } diff --git a/src/main/java/refinedstorage/tile/controller/TileController.java b/src/main/java/refinedstorage/tile/controller/TileController.java index 0bd2040e4..4b19d4035 100755 --- a/src/main/java/refinedstorage/tile/controller/TileController.java +++ b/src/main/java/refinedstorage/tile/controller/TileController.java @@ -44,7 +44,6 @@ import refinedstorage.container.ContainerGrid; import refinedstorage.item.ItemPattern; import refinedstorage.network.MessageGridDelta; import refinedstorage.network.MessageGridUpdate; -import refinedstorage.tile.IConnectionHandler; import refinedstorage.tile.ISynchronizedContainer; import refinedstorage.tile.TileBase; import refinedstorage.tile.TileCrafter; @@ -91,8 +90,6 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR }; private List nodes = new ArrayList(); - private List nodesToAdd = new ArrayList(); - private List nodesToRemove = new ArrayList(); private List patterns = new ArrayList(); @@ -144,26 +141,6 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR IC2Energy.update(); } - for (INetworkNode node : nodesToAdd) { - nodes.add(node); - - if (node instanceof IConnectionHandler) { - ((IConnectionHandler) node).onConnected(this); - } - } - - nodesToAdd.clear(); - - for (INetworkNode node : nodesToRemove) { - nodes.remove(node); - - if (node instanceof IConnectionHandler) { - ((IConnectionHandler) node).onDisconnected(this); - } - } - - nodesToRemove.clear(); - if (canRun()) { Collections.sort(storage.getStorages(), sizeComparator); Collections.sort(storage.getStorages(), priorityComparator); @@ -212,10 +189,6 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR energy.setEnergyStored(energy.getMaxEnergyStored()); } - if (!canRun() && !nodes.isEmpty()) { - disconnectNodes(); - } - if (couldRun != canRun()) { couldRun = canRun(); @@ -238,6 +211,12 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR super.update(); } + public void onBreak() { + for (INetworkNode node : nodes) { + node.onDisconnected(); + } + } + @Override public void invalidate() { super.invalidate(); @@ -252,28 +231,15 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR return nodes; } + @Override + public void setNodes(List nodes) { + this.nodes = nodes; + } + public List getClientNodes() { return clientNodes; } - @Override - public void addNode(INetworkNode node) { - nodesToAdd.add(node); - } - - @Override - public void removeNode(INetworkNode node) { - nodesToRemove.add(node); - } - - public void disconnectNodes() { - for (INetworkNode node : getNodes()) { - node.disconnect(worldObj); - } - - nodes.clear(); - } - @Override public IGridHandler getGridHandler() { return gridHandler; diff --git a/src/main/java/refinedstorage/tile/externalstorage/TileExternalStorage.java b/src/main/java/refinedstorage/tile/externalstorage/TileExternalStorage.java index 57b2b29dc..4fc5a2c31 100755 --- a/src/main/java/refinedstorage/tile/externalstorage/TileExternalStorage.java +++ b/src/main/java/refinedstorage/tile/externalstorage/TileExternalStorage.java @@ -16,7 +16,6 @@ import refinedstorage.api.storage.IStorageProvider; import refinedstorage.container.ContainerStorage; import refinedstorage.inventory.BasicItemHandler; import refinedstorage.network.MessagePriorityUpdate; -import refinedstorage.tile.IConnectionHandler; import refinedstorage.tile.IStorageGui; import refinedstorage.tile.TileNode; import refinedstorage.tile.config.ICompareConfig; @@ -27,7 +26,7 @@ import refinedstorage.tile.config.ModeConstants; import java.util.ArrayList; import java.util.List; -public class TileExternalStorage extends TileNode implements IStorageProvider, IStorageGui, ICompareConfig, IModeConfig, IConnectionHandler { +public class TileExternalStorage extends TileNode implements IStorageProvider, IStorageGui, ICompareConfig, IModeConfig { private static final String NBT_PRIORITY = "Priority"; private static final String NBT_COMPARE = "Compare"; private static final String NBT_MODE = "Mode"; @@ -53,6 +52,13 @@ public class TileExternalStorage extends TileNode implements IStorageProvider, I public void updateNode() { } + @Override + public void onConnectionChange(INetworkMaster network, boolean state) { + super.onConnectionChange(network, state); + + network.getStorage().rebuild(); + } + @Override public void update() { super.update(); @@ -249,14 +255,4 @@ public class TileExternalStorage extends TileNode implements IStorageProvider, I public IItemHandler getFilters() { return filters; } - - @Override - public void onConnected(INetworkMaster network) { - network.getStorage().rebuild(); - } - - @Override - public void onDisconnected(INetworkMaster network) { - network.getStorage().rebuild(); - } }