Use better algorithm for nodes. Still very buggy. Thanks to Player.

This commit is contained in:
Raoul Van den Berge
2016-07-05 00:46:05 +02:00
parent fa91d211c1
commit 7949883ad5
13 changed files with 218 additions and 231 deletions

View File

@@ -43,14 +43,9 @@ public interface INetworkMaster {
List<INetworkNode> 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<INetworkNode> nodes);
/**
* @return The {@link IGridHandler} for this network

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
}
}
}

View File

@@ -1,9 +0,0 @@
package refinedstorage.tile;
import refinedstorage.api.network.INetworkMaster;
public interface IConnectionHandler {
void onConnected(INetworkMaster network);
void onDisconnected(INetworkMaster network);
}

View File

@@ -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();
}
}

View File

@@ -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;
}

View File

@@ -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();
}
}

View File

@@ -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<INetworkNode> nodes = new ArrayList<INetworkNode>();
Set<BlockPos> nodesPos = new HashSet<BlockPos>();
this.network.addNode(this);
Queue<BlockPos> positions = new ArrayDeque<BlockPos>();
Set<BlockPos> checked = new HashSet<BlockPos>();
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<Long>());
if (network == null) {
if (controller != null) {
connect(world, controller);
}
} else {
if (controller == null) {
disconnect(world);
}
}
}
private TileController searchController(World world, BlockPos current, Set<Long> 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<INetworkNode> nodes = new ArrayList<INetworkNode>();
Set<BlockPos> nodesPos = new HashSet<BlockPos>();
Queue<BlockPos> positions = new ArrayDeque<BlockPos>();
Set<BlockPos> checked = new HashSet<BlockPos>();
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<INetworkNode> 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

View File

@@ -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() {

View File

@@ -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();
}
}

View File

@@ -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<INetworkNode> nodes = new ArrayList<INetworkNode>();
private List<INetworkNode> nodesToAdd = new ArrayList<INetworkNode>();
private List<INetworkNode> nodesToRemove = new ArrayList<INetworkNode>();
private List<ICraftingPattern> patterns = new ArrayList<ICraftingPattern>();
@@ -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<INetworkNode> nodes) {
this.nodes = nodes;
}
public List<ClientNode> 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;

View File

@@ -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();
}
}