Significantly reduce performance loss when using Item Laser Relays and/or ESDs

Closes #279
This commit is contained in:
Ellpeck 2016-10-29 12:00:00 +02:00
parent 336158ee89
commit 7a69273865
12 changed files with 89 additions and 54 deletions

View file

@ -14,6 +14,7 @@ import io.netty.util.internal.ConcurrentSet;
public class Network{ public class Network{
public int changeAmount;
public final ConcurrentSet<IConnectionPair> connections = new ConcurrentSet<IConnectionPair>(); public final ConcurrentSet<IConnectionPair> connections = new ConcurrentSet<IConnectionPair>();
@Override @Override

View file

@ -160,8 +160,8 @@ public abstract class BlockContainerBase extends BlockContainer implements ItemB
TileEntity tile = world.getTileEntity(pos); TileEntity tile = world.getTileEntity(pos);
if(tile instanceof TileEntityBase){ if(tile instanceof TileEntityBase){
TileEntityBase base = (TileEntityBase)tile; TileEntityBase base = (TileEntityBase)tile;
if(base.shouldSaveHandlersAround()){ if(base.shouldSaveDataOnChangeOrWorldStart()){
base.saveAllHandlersAround(); base.saveDataOnChangeOrWorldStart();
} }
} }
} }

View file

@ -54,6 +54,8 @@ public final class LaserRelayConnectionHandler implements ILaserRelayConnectionH
for(IConnectionPair secondPair : secondNetwork.connections){ for(IConnectionPair secondPair : secondNetwork.connections){
firstNetwork.connections.add(secondPair); firstNetwork.connections.add(secondPair);
} }
firstNetwork.changeAmount++;
WorldData.getDataForWorld(world).laserRelayNetworks.remove(secondNetwork); WorldData.getDataForWorld(world).laserRelayNetworks.remove(secondNetwork);
//System.out.println("Merged Two Networks!"); //System.out.println("Merged Two Networks!");
} }
@ -140,6 +142,7 @@ public final class LaserRelayConnectionHandler implements ILaserRelayConnectionH
firstNetwork = new Network(); firstNetwork = new Network();
WorldData.getDataForWorld(world).laserRelayNetworks.add(firstNetwork); WorldData.getDataForWorld(world).laserRelayNetworks.add(firstNetwork);
firstNetwork.connections.add(new ConnectionPair(firstRelay, secondRelay, type, suppressConnectionRender)); firstNetwork.connections.add(new ConnectionPair(firstRelay, secondRelay, type, suppressConnectionRender));
firstNetwork.changeAmount++;
} }
//The same Network //The same Network
else if(firstNetwork == secondNetwork){ else if(firstNetwork == secondNetwork){
@ -149,14 +152,17 @@ public final class LaserRelayConnectionHandler implements ILaserRelayConnectionH
else if(firstNetwork != null && secondNetwork != null){ else if(firstNetwork != null && secondNetwork != null){
mergeNetworks(firstNetwork, secondNetwork, world); mergeNetworks(firstNetwork, secondNetwork, world);
firstNetwork.connections.add(new ConnectionPair(firstRelay, secondRelay, type, suppressConnectionRender)); firstNetwork.connections.add(new ConnectionPair(firstRelay, secondRelay, type, suppressConnectionRender));
firstNetwork.changeAmount++;
} }
//Only first network exists //Only first network exists
else if(firstNetwork != null){ else if(firstNetwork != null){
firstNetwork.connections.add(new ConnectionPair(firstRelay, secondRelay, type, suppressConnectionRender)); firstNetwork.connections.add(new ConnectionPair(firstRelay, secondRelay, type, suppressConnectionRender));
firstNetwork.changeAmount++;
} }
//Only second network exists //Only second network exists
else{ else{
secondNetwork.connections.add(new ConnectionPair(firstRelay, secondRelay, type, suppressConnectionRender)); secondNetwork.connections.add(new ConnectionPair(firstRelay, secondRelay, type, suppressConnectionRender));
secondNetwork.changeAmount++;
} }
//System.out.println("Connected "+firstRelay.toString()+" to "+secondRelay.toString()); //System.out.println("Connected "+firstRelay.toString()+" to "+secondRelay.toString());
//System.out.println(firstNetwork == null ? secondNetwork.toString() : firstNetwork.toString()); //System.out.println(firstNetwork == null ? secondNetwork.toString() : firstNetwork.toString());

View file

@ -43,7 +43,7 @@ public abstract class TileEntityBase extends TileEntity implements ITickable{
protected int ticksElapsed; protected int ticksElapsed;
protected TileEntity[] tilesAround = new TileEntity[6]; protected TileEntity[] tilesAround = new TileEntity[6];
protected boolean hasCheckedHandlersAround; protected boolean hasSavedDataOnChangeOrWorldStart;
public TileEntityBase(String name){ public TileEntityBase(String name){
this.name = name; this.name = name;
@ -274,23 +274,23 @@ public abstract class TileEntityBase extends TileEntity implements ITickable{
} }
} }
if(!this.hasCheckedHandlersAround){ if(!this.hasSavedDataOnChangeOrWorldStart){
if(this.shouldSaveHandlersAround()){ if(this.shouldSaveDataOnChangeOrWorldStart()){
this.saveAllHandlersAround(); this.saveDataOnChangeOrWorldStart();
} }
this.hasCheckedHandlersAround = true; this.hasSavedDataOnChangeOrWorldStart = true;
} }
} }
} }
public void saveAllHandlersAround(){ public void saveDataOnChangeOrWorldStart(){
for(EnumFacing side : EnumFacing.values()){ for(EnumFacing side : EnumFacing.values()){
this.tilesAround[side.ordinal()] = this.worldObj.getTileEntity(this.pos.offset(side)); this.tilesAround[side.ordinal()] = this.worldObj.getTileEntity(this.pos.offset(side));
} }
} }
public boolean shouldSaveHandlersAround(){ public boolean shouldSaveDataOnChangeOrWorldStart(){
return this instanceof ISharingEnergyProvider || this instanceof ISharingFluidHandler; return this instanceof ISharingEnergyProvider || this instanceof ISharingFluidHandler;
} }

View file

@ -116,7 +116,7 @@ public class TileEntityDistributorItem extends TileEntityInventoryBase{
} }
@Override @Override
public void saveAllHandlersAround(){ public void saveDataOnChangeOrWorldStart(){
this.handlersAround.clear(); this.handlersAround.clear();
for(EnumFacing side : EnumFacing.values()){ for(EnumFacing side : EnumFacing.values()){
@ -152,7 +152,7 @@ public class TileEntityDistributorItem extends TileEntityInventoryBase{
} }
@Override @Override
public boolean shouldSaveHandlersAround(){ public boolean shouldSaveDataOnChangeOrWorldStart(){
return true; return true;
} }

View file

@ -101,7 +101,7 @@ public class TileEntityFishingNet extends TileEntityBase{
} }
@Override @Override
public boolean shouldSaveHandlersAround(){ public boolean shouldSaveDataOnChangeOrWorldStart(){
return true; return true;
} }
} }

View file

@ -233,7 +233,7 @@ public class TileEntityFluidCollector extends TileEntityBase implements ISharing
@Override @Override
public boolean doesShareFluid(){ public boolean doesShareFluid(){
return true; return !this.isPlacer;
} }
@Override @Override

View file

@ -91,6 +91,10 @@ public class TileEntityInputter extends TileEntityInventoryBase implements IButt
} }
} }
} }
if(this.placeToPull instanceof TileEntityItemViewer){
break;
}
} }
return false; return false;
} }
@ -108,6 +112,10 @@ public class TileEntityInputter extends TileEntityInventoryBase implements IButt
} }
} }
} }
if(this.placeToPut instanceof TileEntityItemViewer){
break;
}
} }
} }
return false; return false;
@ -312,7 +320,7 @@ public class TileEntityInputter extends TileEntityInventoryBase implements IButt
} }
@Override @Override
public boolean shouldSaveHandlersAround(){ public boolean shouldSaveDataOnChangeOrWorldStart(){
return true; return true;
} }
@ -320,7 +328,7 @@ public class TileEntityInputter extends TileEntityInventoryBase implements IButt
* Sets all of the relevant variables * Sets all of the relevant variables
*/ */
@Override @Override
public void saveAllHandlersAround(){ public void saveDataOnChangeOrWorldStart(){
if(this.sideToPull != -1){ if(this.sideToPull != -1){
EnumFacing side = WorldUtil.getDirectionBySidesInOrder(this.sideToPull); EnumFacing side = WorldUtil.getDirectionBySidesInOrder(this.sideToPull);
this.placeToPull = this.worldObj.getTileEntity(this.pos.offset(side)); this.placeToPull = this.worldObj.getTileEntity(this.pos.offset(side));
@ -403,7 +411,7 @@ public class TileEntityInputter extends TileEntityInventoryBase implements IButt
} }
this.markDirty(); this.markDirty();
this.saveAllHandlersAround(); this.saveDataOnChangeOrWorldStart();
} }
@Override @Override

View file

@ -20,14 +20,16 @@ import net.minecraft.util.math.BlockPos;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.SidedInvWrapper; import net.minecraftforge.items.wrapper.SidedInvWrapper;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.List;
public class TileEntityItemViewer extends TileEntityInventoryBase{ public class TileEntityItemViewer extends TileEntityInventoryBase{
public TileEntityLaserRelayItem connectedRelay; public TileEntityLaserRelayItem connectedRelay;
private final List<GenericItemHandlerInfo> genericInfos = new ArrayList<GenericItemHandlerInfo>();
private final Map<Integer, SpecificItemHandlerInfo> specificInfos = new HashMap<Integer, SpecificItemHandlerInfo>();
private int lastNetworkChangeAmount = -1;
public TileEntityItemViewer(){ public TileEntityItemViewer(){
super(0, "itemViewer"); super(0, "itemViewer");
} }
@ -71,45 +73,49 @@ public class TileEntityItemViewer extends TileEntityInventoryBase{
} }
private List<GenericItemHandlerInfo> getItemHandlerInfos(){ private List<GenericItemHandlerInfo> getItemHandlerInfos(){
TileEntityLaserRelayItem relay = this.connectedRelay; this.queryAndSaveData();
if(relay != null){ return this.genericInfos;
Network network = ActuallyAdditionsAPI.connectionHandler.getNetworkFor(relay.getPos(), this.worldObj);
if(network != null){
return relay.getItemHandlersInNetwork(network);
}
}
return null;
} }
private SpecificItemHandlerInfo getSwitchedIndexHandler(int i){ private void queryAndSaveData(){
List<GenericItemHandlerInfo> infos = this.getItemHandlerInfos(); if(this.connectedRelay != null){
if(infos != null && !infos.isEmpty()){ Network network = ActuallyAdditionsAPI.connectionHandler.getNetworkFor(this.connectedRelay.getPos(), this.worldObj);
Collections.sort(infos); if(network != null && this.lastNetworkChangeAmount != network.changeAmount){
int currentI = 0; this.genericInfos.clear();
if(!infos.isEmpty()){ this.specificInfos.clear();
for(GenericItemHandlerInfo info : infos){
for(IItemHandler handler : info.handlers){ this.connectedRelay.getItemHandlersInNetwork(network, this.genericInfos);
int slotAmount = handler.getSlots(); if(!this.genericInfos.isEmpty()){
if(currentI+slotAmount > i){ Collections.sort(this.genericInfos);
return new SpecificItemHandlerInfo(handler, i-currentI, info.relayInQuestion);
} int slotsQueried = 0;
else{ for(GenericItemHandlerInfo info : this.genericInfos){
currentI += slotAmount; for(IItemHandler handler : info.handlers){
for(int i = 0; i < handler.getSlots(); i++){
this.specificInfos.put(slotsQueried, new SpecificItemHandlerInfo(handler, i, info.relayInQuestion));
slotsQueried++;
}
} }
} }
} }
this.lastNetworkChangeAmount = network.changeAmount;
} }
} }
return null; }
private SpecificItemHandlerInfo getSwitchedIndexHandler(int i){
this.queryAndSaveData();
return this.specificInfos.get(i);
} }
@Override @Override
public boolean shouldSaveHandlersAround(){ public boolean shouldSaveDataOnChangeOrWorldStart(){
return true; return true;
} }
@Override @Override
public void saveAllHandlersAround(){ public void saveDataOnChangeOrWorldStart(){
TileEntityLaserRelayItem tileFound = null; TileEntityLaserRelayItem tileFound = null;
if(this.worldObj != null){ //Why is that even possible..? if(this.worldObj != null){ //Why is that even possible..?
for(int i = 0; i <= 5; i++){ for(int i = 0; i <= 5; i++){

View file

@ -74,12 +74,12 @@ public class TileEntityLaserRelayEnergy extends TileEntityLaserRelay implements
} }
@Override @Override
public boolean shouldSaveHandlersAround(){ public boolean shouldSaveDataOnChangeOrWorldStart(){
return true; return true;
} }
@Override @Override
public void saveAllHandlersAround(){ public void saveDataOnChangeOrWorldStart(){
this.receiversAround.clear(); this.receiversAround.clear();
for(EnumFacing side : EnumFacing.values()){ for(EnumFacing side : EnumFacing.values()){
@ -91,6 +91,11 @@ public class TileEntityLaserRelayEnergy extends TileEntityLaserRelay implements
} }
} }
} }
Network network = ActuallyAdditionsAPI.connectionHandler.getNetworkFor(this.getPos(), this.getWorld());
if(network != null){
network.changeAmount++;
}
} }
private int transferEnergyToReceiverInNeed(EnumFacing from, Network network, int maxTransfer, boolean simulate){ private int transferEnergyToReceiverInNeed(EnumFacing from, Network network, int maxTransfer, boolean simulate){

View file

@ -37,12 +37,12 @@ public class TileEntityLaserRelayFluids extends TileEntityLaserRelay implements
} }
@Override @Override
public boolean shouldSaveHandlersAround(){ public boolean shouldSaveDataOnChangeOrWorldStart(){
return true; return true;
} }
@Override @Override
public void saveAllHandlersAround(){ public void saveDataOnChangeOrWorldStart(){
this.receiversAround.clear(); this.receiversAround.clear();
for(EnumFacing side : EnumFacing.values()){ for(EnumFacing side : EnumFacing.values()){
@ -54,6 +54,11 @@ public class TileEntityLaserRelayFluids extends TileEntityLaserRelay implements
} }
} }
} }
Network network = ActuallyAdditionsAPI.connectionHandler.getNetworkFor(this.getPos(), this.getWorld());
if(network != null){
network.changeAmount++;
}
} }
@Override @Override

View file

@ -10,6 +10,7 @@
package de.ellpeck.actuallyadditions.mod.tile; package de.ellpeck.actuallyadditions.mod.tile;
import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI;
import de.ellpeck.actuallyadditions.api.laser.IConnectionPair; import de.ellpeck.actuallyadditions.api.laser.IConnectionPair;
import de.ellpeck.actuallyadditions.api.laser.LaserType; import de.ellpeck.actuallyadditions.api.laser.LaserType;
import de.ellpeck.actuallyadditions.api.laser.Network; import de.ellpeck.actuallyadditions.api.laser.Network;
@ -44,12 +45,12 @@ public class TileEntityLaserRelayItem extends TileEntityLaserRelay{
} }
@Override @Override
public boolean shouldSaveHandlersAround(){ public boolean shouldSaveDataOnChangeOrWorldStart(){
return true; return true;
} }
@Override @Override
public void saveAllHandlersAround(){ public void saveDataOnChangeOrWorldStart(){
this.handlersAround.clear(); this.handlersAround.clear();
for(int i = 0; i <= 5; i++){ for(int i = 0; i <= 5; i++){
@ -63,13 +64,17 @@ public class TileEntityLaserRelayItem extends TileEntityLaserRelay{
} }
} }
} }
Network network = ActuallyAdditionsAPI.connectionHandler.getNetworkFor(this.getPos(), this.getWorld());
if(network != null){
network.changeAmount++;
}
} }
public List<GenericItemHandlerInfo> getItemHandlersInNetwork(Network network){ public void getItemHandlersInNetwork(Network network, List<GenericItemHandlerInfo> storeList){
//Keeps track of all the Laser Relays and Item Handlers that have been checked already to make nothing run multiple times //Keeps track of all the Laser Relays and Item Handlers that have been checked already to make nothing run multiple times
List<BlockPos> alreadyChecked = new ArrayList<BlockPos>(); List<BlockPos> alreadyChecked = new ArrayList<BlockPos>();
List<GenericItemHandlerInfo> handlers = new ArrayList<GenericItemHandlerInfo>();
for(IConnectionPair pair : network.connections){ for(IConnectionPair pair : network.connections){
for(BlockPos relay : pair.getPositions()){ for(BlockPos relay : pair.getPositions()){
if(relay != null && !alreadyChecked.contains(relay)){ if(relay != null && !alreadyChecked.contains(relay)){
@ -88,11 +93,10 @@ public class TileEntityLaserRelayItem extends TileEntityLaserRelay{
} }
} }
handlers.add(info); storeList.add(info);
} }
} }
} }
} }
return handlers;
} }
} }