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 int changeAmount;
public final ConcurrentSet<IConnectionPair> connections = new ConcurrentSet<IConnectionPair>();
@Override

View file

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

View file

@ -54,6 +54,8 @@ public final class LaserRelayConnectionHandler implements ILaserRelayConnectionH
for(IConnectionPair secondPair : secondNetwork.connections){
firstNetwork.connections.add(secondPair);
}
firstNetwork.changeAmount++;
WorldData.getDataForWorld(world).laserRelayNetworks.remove(secondNetwork);
//System.out.println("Merged Two Networks!");
}
@ -140,6 +142,7 @@ public final class LaserRelayConnectionHandler implements ILaserRelayConnectionH
firstNetwork = new Network();
WorldData.getDataForWorld(world).laserRelayNetworks.add(firstNetwork);
firstNetwork.connections.add(new ConnectionPair(firstRelay, secondRelay, type, suppressConnectionRender));
firstNetwork.changeAmount++;
}
//The same Network
else if(firstNetwork == secondNetwork){
@ -149,14 +152,17 @@ public final class LaserRelayConnectionHandler implements ILaserRelayConnectionH
else if(firstNetwork != null && secondNetwork != null){
mergeNetworks(firstNetwork, secondNetwork, world);
firstNetwork.connections.add(new ConnectionPair(firstRelay, secondRelay, type, suppressConnectionRender));
firstNetwork.changeAmount++;
}
//Only first network exists
else if(firstNetwork != null){
firstNetwork.connections.add(new ConnectionPair(firstRelay, secondRelay, type, suppressConnectionRender));
firstNetwork.changeAmount++;
}
//Only second network exists
else{
secondNetwork.connections.add(new ConnectionPair(firstRelay, secondRelay, type, suppressConnectionRender));
secondNetwork.changeAmount++;
}
//System.out.println("Connected "+firstRelay.toString()+" to "+secondRelay.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 TileEntity[] tilesAround = new TileEntity[6];
protected boolean hasCheckedHandlersAround;
protected boolean hasSavedDataOnChangeOrWorldStart;
public TileEntityBase(String name){
this.name = name;
@ -274,23 +274,23 @@ public abstract class TileEntityBase extends TileEntity implements ITickable{
}
}
if(!this.hasCheckedHandlersAround){
if(this.shouldSaveHandlersAround()){
this.saveAllHandlersAround();
if(!this.hasSavedDataOnChangeOrWorldStart){
if(this.shouldSaveDataOnChangeOrWorldStart()){
this.saveDataOnChangeOrWorldStart();
}
this.hasCheckedHandlersAround = true;
this.hasSavedDataOnChangeOrWorldStart = true;
}
}
}
public void saveAllHandlersAround(){
public void saveDataOnChangeOrWorldStart(){
for(EnumFacing side : EnumFacing.values()){
this.tilesAround[side.ordinal()] = this.worldObj.getTileEntity(this.pos.offset(side));
}
}
public boolean shouldSaveHandlersAround(){
public boolean shouldSaveDataOnChangeOrWorldStart(){
return this instanceof ISharingEnergyProvider || this instanceof ISharingFluidHandler;
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -74,12 +74,12 @@ public class TileEntityLaserRelayEnergy extends TileEntityLaserRelay implements
}
@Override
public boolean shouldSaveHandlersAround(){
public boolean shouldSaveDataOnChangeOrWorldStart(){
return true;
}
@Override
public void saveAllHandlersAround(){
public void saveDataOnChangeOrWorldStart(){
this.receiversAround.clear();
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){

View file

@ -37,12 +37,12 @@ public class TileEntityLaserRelayFluids extends TileEntityLaserRelay implements
}
@Override
public boolean shouldSaveHandlersAround(){
public boolean shouldSaveDataOnChangeOrWorldStart(){
return true;
}
@Override
public void saveAllHandlersAround(){
public void saveDataOnChangeOrWorldStart(){
this.receiversAround.clear();
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

View file

@ -10,6 +10,7 @@
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.LaserType;
import de.ellpeck.actuallyadditions.api.laser.Network;
@ -44,12 +45,12 @@ public class TileEntityLaserRelayItem extends TileEntityLaserRelay{
}
@Override
public boolean shouldSaveHandlersAround(){
public boolean shouldSaveDataOnChangeOrWorldStart(){
return true;
}
@Override
public void saveAllHandlersAround(){
public void saveDataOnChangeOrWorldStart(){
this.handlersAround.clear();
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
List<BlockPos> alreadyChecked = new ArrayList<BlockPos>();
List<GenericItemHandlerInfo> handlers = new ArrayList<GenericItemHandlerInfo>();
for(IConnectionPair pair : network.connections){
for(BlockPos relay : pair.getPositions()){
if(relay != null && !alreadyChecked.contains(relay)){
@ -88,11 +93,10 @@ public class TileEntityLaserRelayItem extends TileEntityLaserRelay{
}
}
handlers.add(info);
storeList.add(info);
}
}
}
}
return handlers;
}
}