From 032a77dac00ca4ec98a7af3f16d7f99191727d60 Mon Sep 17 00:00:00 2001 From: Richard Hendricks Date: Wed, 30 May 2018 01:09:15 -0500 Subject: Branch to add in better debug output from GT cpu load. ns instead of ms. --- .../api/metatileentity/BaseMetaPipeEntity.java | 18 ++++++++++++------ .../api/metatileentity/BaseMetaTileEntity.java | 18 ++++++++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) (limited to 'src/main/java/gregtech') diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java index a761afd5cb..0d06c4ec03 100644 --- a/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java +++ b/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java @@ -183,7 +183,7 @@ public class BaseMetaPipeEntity extends BaseTileEntity implements IGregTechTileE mMetaTileEntity.setBaseMetaTileEntity(this); } - long tTime = System.currentTimeMillis(); + long tTime = System.nanoTime(); int tCode = 0; try { for (tCode = 0; hasValidMetaTileEntity() && tCode >= 0; ) { @@ -298,11 +298,11 @@ public class BaseMetaPipeEntity extends BaseTileEntity implements IGregTechTileE } if (isServerSide() && hasValidMetaTileEntity()) { - tTime = System.currentTimeMillis() - tTime; + tTime = System.nanoTime() - tTime; if (mTimeStatistics.length > 0) mTimeStatistics[mTimeStatisticsIndex = (mTimeStatisticsIndex + 1) % mTimeStatistics.length] = (int) tTime; - if (tTime > 0 && tTime > GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING && mTickTimer > 1000 && getMetaTileEntity().doTickProfilingMessageDuringThisTick() && mLagWarningCount++ < 10) - FMLLog.warning("WARNING: Possible Lag Source at [%s,%s,%s] in Dimension %s with %s ms caused by an instance of %s", xCoord, yCoord, zCoord, worldObj.provider.dimensionId, tTime, getMetaTileEntity().getClass()); + if (tTime > 0 && tTime > (GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING*1000000) && mTickTimer > 1000 && getMetaTileEntity().doTickProfilingMessageDuringThisTick() && mLagWarningCount++ < 10) + FMLLog.warning("WARNING: Possible Lag Source at [%s,%s,%s] in Dimension %s with %s ns caused by an instance of %s", xCoord, yCoord, zCoord, worldObj.provider.dimensionId, tTime, getMetaTileEntity().getClass()); } mWorkUpdate = mInventoryChanged = false; @@ -395,8 +395,14 @@ public class BaseMetaPipeEntity extends BaseTileEntity implements IGregTechTileE if (aLogLevel > 1) { if (mTimeStatistics.length > 0) { double tAverageTime = 0; - for (int tTime : mTimeStatistics) tAverageTime += tTime; - tList.add("Average CPU-load of ~" + (tAverageTime / mTimeStatistics.length) + "ms since " + mTimeStatistics.length + " ticks."); + double tWorstTime = 0; + for (int tTime : mTimeStatistics) { + tAverageTime += tTime; + if (tTime > tWorstTime) { + tWorstTime = tTime; + } + } + tList.add("Average CPU-load of ~" + (tAverageTime / mTimeStatistics.length) + "ns since " + mTimeStatistics.length + " ticks with worst time of " + tWorstTime + "ns."); } if (mLagWarningCount > 0) { tList.add("Caused " + (mLagWarningCount >= 10 ? "more than 10" : mLagWarningCount) + " Lag Spike Warnings (anything taking longer than " + GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING + "ms) on the Server."); diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java index d44ada526f..609a35bfae 100644 --- a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java @@ -277,7 +277,7 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE } mRunningThroughTick = true; - long tTime = System.currentTimeMillis(); + long tTime = System.nanoTime(); int tCode = 0; boolean aSideServer = isServerSide(); boolean aSideClient = isClientSide(); @@ -573,11 +573,11 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE } if (aSideServer && hasValidMetaTileEntity()) { - tTime = System.currentTimeMillis() - tTime; + tTime = System.nanoTime() - tTime; if (mTimeStatistics.length > 0) mTimeStatistics[mTimeStatisticsIndex = (mTimeStatisticsIndex + 1) % mTimeStatistics.length] = (int) tTime; - if (tTime > 0 && tTime > GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING && mTickTimer > 1000 && getMetaTileEntity().doTickProfilingMessageDuringThisTick() && mLagWarningCount++ < 10) - System.out.println("WARNING: Possible Lag Source at [" + xCoord + ", " + yCoord + ", " + zCoord + "] in Dimension " + worldObj.provider.dimensionId + " with " + tTime + "ms caused by an instance of " + getMetaTileEntity().getClass()); + if (tTime > 0 && tTime > (GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING*1000000) && mTickTimer > 1000 && getMetaTileEntity().doTickProfilingMessageDuringThisTick() && mLagWarningCount++ < 10) + System.out.println("WARNING: Possible Lag Source at [" + xCoord + ", " + yCoord + ", " + zCoord + "] in Dimension " + worldObj.provider.dimensionId + " with " + tTime + "ns caused by an instance of " + getMetaTileEntity().getClass()); } mWorkUpdate = mInventoryChanged = mRunningThroughTick = false; @@ -706,8 +706,14 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE if (aLogLevel > 1) { if (mTimeStatistics.length > 0) { double tAverageTime = 0; - for (int tTime : mTimeStatistics) tAverageTime += tTime; - tList.add("Average CPU-load of ~" + (tAverageTime / mTimeStatistics.length) + "ms since " + mTimeStatistics.length + " ticks."); + double tWorstTime = 0; + for (int tTime : mTimeStatistics) { + tAverageTime += tTime; + if (tTime > tWorstTime) { + tWorstTime = tTime; + } + } + tList.add("Average CPU-load of ~" + (tAverageTime / mTimeStatistics.length) + "ns since " + mTimeStatistics.length + " ticks with worst time of " + tWorstTime + "ns."); } if (mLagWarningCount > 0) { tList.add("Caused " + (mLagWarningCount >= 10 ? "more than 10" : mLagWarningCount) + " Lag Spike Warnings (anything taking longer than " + GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING + "ms) on the Server."); -- cgit From 715cd53f69a7940996c7c7c9e99539fa023d4615 Mon Sep 17 00:00:00 2001 From: Richard Hendricks Date: Wed, 30 May 2018 02:05:45 -0500 Subject: Some fixes. Only update if inventory actually changes. Sort inventory first, then bubble out nulls after. --- .../automation/GT_MetaTileEntity_ChestBuffer.java | 28 +++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'src/main/java/gregtech') diff --git a/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java b/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java index 7385bb31b1..2450b392d2 100644 --- a/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java +++ b/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java @@ -49,19 +49,41 @@ public class GT_MetaTileEntity_ChestBuffer } protected void moveItems(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) { - fillStacksIntoFirstSlots(); + if(aBaseMetaTileEntity.hasInventoryBeenModified()) + { + fillStacksIntoFirstSlots(); + } super.moveItems(aBaseMetaTileEntity, aTimer); - fillStacksIntoFirstSlots(); + if(mSuccess == 50) { + fillStacksIntoFirstSlots(); + } } protected void fillStacksIntoFirstSlots() { for (int i = 0; i < this.mInventory.length - 1; i++) { for (int j = i + 1; j < this.mInventory.length - 1; j++) { - if ((this.mInventory[j] != null) && ((this.mInventory[i] == null) || (GT_Utility.areStacksEqual(this.mInventory[i], this.mInventory[j])))) { +// if ((this.mInventory[j] != null) && ((this.mInventory[i] == null) || (GT_Utility.areStacksEqual(this.mInventory[i], this.mInventory[j])))) { + if ((this.mInventory[j] != null) && ((GT_Utility.areStacksEqual(this.mInventory[i], this.mInventory[j])))) { GT_Utility.moveStackFromSlotAToSlotB(getBaseMetaTileEntity(), getBaseMetaTileEntity(), j, i, (byte) 64, (byte) 1, (byte) 64, (byte) 1); } } } + // Find first non-null item from the tail + int lastValid; + for( lastValid = this.mInventory.length-1; lastValid >0; lastValid-- ) { + if(this.mInventory[lastValid] == null) { + continue; + } + break; + } + // Go back to the start of the array, swapping any nulls with the last valid item and move last valid item down 1 + for (int i = lastValid; i >= 0; i-- ) { + if(this.mInventory[i] == null) { + //Swap the current null with the last valid item + GT_Utility.moveStackFromSlotAToSlotB(getBaseMetaTileEntity(), getBaseMetaTileEntity(), lastValid, i, (byte) 64, (byte) 1, (byte) 64, (byte) 1); + lastValid --; + } + } } public Object getServerGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { -- cgit From accc2b96dbd87edcc887734593937ad8d4fe7129 Mon Sep 17 00:00:00 2001 From: Richard Hendricks Date: Thu, 31 May 2018 02:56:58 -0500 Subject: Tune how often to actually push so that it is every-other-tick if teh receiving side can accept it. Only resort the list if the inventory has been modified before the push, and if the push was successful. Use java's built in sort to keep the list sorted. Nulls get squeezed out as part of the sort algorithm. --- .../automation/GT_MetaTileEntity_ChestBuffer.java | 271 +++++++++++++-------- 1 file changed, 175 insertions(+), 96 deletions(-) (limited to 'src/main/java/gregtech') diff --git a/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java b/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java index 2450b392d2..99a360ad11 100644 --- a/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java +++ b/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java @@ -1,96 +1,175 @@ -package gregtech.common.tileentities.automation; - -import gregtech.api.enums.Textures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Buffer; -import gregtech.api.objects.GT_RenderedTexture; -import gregtech.api.util.GT_Utility; -import gregtech.common.gui.GT_Container_ChestBuffer; -import gregtech.common.gui.GT_GUIContainer_ChestBuffer; -import net.minecraft.entity.player.InventoryPlayer; - -public class GT_MetaTileEntity_ChestBuffer - extends GT_MetaTileEntity_Buffer { - public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier) { - super(aID, aName, aNameRegional, aTier, 28, new String[]{ - "Buffers up to 27 Item Stacks", - "Use Screwdriver to regulate output stack size", - "Consumes 3EU per moved Item"}); - } - - public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String aDescription) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); - } - - public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String[] aDescription) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); - } - - public GT_MetaTileEntity_ChestBuffer(String aName, int aTier, int aInvSlotCount, String aDescription, ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_ChestBuffer(String aName, int aTier, int aInvSlotCount, String[] aDescription, ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_ChestBuffer(this.mName, this.mTier, this.mInventory.length, this.mDescriptionArray, this.mTextures); - } - - public ITexture getOverlayIcon() { - return new GT_RenderedTexture(Textures.BlockIcons.AUTOMATION_CHESTBUFFER); - } - - public boolean isValidSlot(int aIndex) { - return aIndex < this.mInventory.length - 1; - } - - protected void moveItems(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) { - if(aBaseMetaTileEntity.hasInventoryBeenModified()) - { - fillStacksIntoFirstSlots(); - } - super.moveItems(aBaseMetaTileEntity, aTimer); - if(mSuccess == 50) { - fillStacksIntoFirstSlots(); - } - } - - protected void fillStacksIntoFirstSlots() { - for (int i = 0; i < this.mInventory.length - 1; i++) { - for (int j = i + 1; j < this.mInventory.length - 1; j++) { -// if ((this.mInventory[j] != null) && ((this.mInventory[i] == null) || (GT_Utility.areStacksEqual(this.mInventory[i], this.mInventory[j])))) { - if ((this.mInventory[j] != null) && ((GT_Utility.areStacksEqual(this.mInventory[i], this.mInventory[j])))) { - GT_Utility.moveStackFromSlotAToSlotB(getBaseMetaTileEntity(), getBaseMetaTileEntity(), j, i, (byte) 64, (byte) 1, (byte) 64, (byte) 1); - } - } - } - // Find first non-null item from the tail - int lastValid; - for( lastValid = this.mInventory.length-1; lastValid >0; lastValid-- ) { - if(this.mInventory[lastValid] == null) { - continue; - } - break; - } - // Go back to the start of the array, swapping any nulls with the last valid item and move last valid item down 1 - for (int i = lastValid; i >= 0; i-- ) { - if(this.mInventory[i] == null) { - //Swap the current null with the last valid item - GT_Utility.moveStackFromSlotAToSlotB(getBaseMetaTileEntity(), getBaseMetaTileEntity(), lastValid, i, (byte) 64, (byte) 1, (byte) 64, (byte) 1); - lastValid --; - } - } - } - - public Object getServerGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { - return new GT_Container_ChestBuffer(aPlayerInventory, aBaseMetaTileEntity); - } - - public Object getClientGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { - return new GT_GUIContainer_ChestBuffer(aPlayerInventory, aBaseMetaTileEntity); - } -} +package gregtech.common.tileentities.automation; + +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Buffer; +import gregtech.api.objects.GT_RenderedTexture; +import gregtech.api.util.GT_Utility; +import gregtech.common.gui.GT_Container_ChestBuffer; +import gregtech.common.gui.GT_GUIContainer_ChestBuffer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; + +import java.util.Arrays; +import java.util.Comparator; + +public class GT_MetaTileEntity_ChestBuffer + extends GT_MetaTileEntity_Buffer { + public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier) { + super(aID, aName, aNameRegional, aTier, 28, new String[]{ + "Buffers up to 27 Item Stacks", + "Use Screwdriver to regulate output stack size", + "Consumes 3EU per moved Item"}); + } + + public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String aDescription) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); + } + + public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String[] aDescription) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); + } + + public GT_MetaTileEntity_ChestBuffer(String aName, int aTier, int aInvSlotCount, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + public GT_MetaTileEntity_ChestBuffer(String aName, int aTier, int aInvSlotCount, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new GT_MetaTileEntity_ChestBuffer(this.mName, this.mTier, this.mInventory.length, this.mDescriptionArray, this.mTextures); + } + + public ITexture getOverlayIcon() { + return new GT_RenderedTexture(Textures.BlockIcons.AUTOMATION_CHESTBUFFER); + } + + public boolean isValidSlot(int aIndex) { + return aIndex < this.mInventory.length - 1; + } + + protected void moveItems(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) { + if(aBaseMetaTileEntity.hasInventoryBeenModified()) { + fillStacksIntoFirstSlots(); + } + // mSuccess will be negative if the call is caused by the %200 aTimer. Otherwise it will be positive, and only every other tick is a push attempted. + if ( (mSuccess <= 0 ) || (( mSuccess > 0 ) && ( (mSuccess % 2) == 0 )) ){ + super.moveItems(aBaseMetaTileEntity, aTimer); + } + // mSuccesss is set to 50 on a successful move + if(mSuccess == 50) { + fillStacksIntoFirstSlots(); + } + if(mSuccess < 0) { + mSuccess = 0; + } + } + +// Implementation using Java built in sort algorithm +// Uses terribad string comparison to sort against. Would be better if we did something else? + protected void sortStacks() { + Arrays.sort(this.mInventory, new Comparator() { + @Override + // Taken from https://gist.github.com/Choonster/876acc3217229e172e46 + public int compare(ItemStack o1, ItemStack o2) { + if ( o2 == null ) + return -1; + if( o1 == null ) + return 1; + Item item1 = o1.getItem(); + Item item2 = o2.getItem(); + + // If item1 is a block and item2 isn't, sort item1 before item2 + if (((item1 instanceof ItemBlock)) && (!(item2 instanceof ItemBlock))) { + return -1; + } + + // If item2 is a block and item1 isn't, sort item1 after item2 + if (((item2 instanceof ItemBlock)) && (!(item1 instanceof ItemBlock))) { + return 1; + } + + String displayName1 = o1.getDisplayName(); + String displayName2 = o2.getDisplayName(); + + int result = displayName1.compareToIgnoreCase(displayName2); + //System.out.println("sorter: " + displayName1 + " " + displayName2 + " " + result); + return result; + } + }); + } + +// Implementation of insertion sort +// Worst case time of a 2.8ms +/* + public int compare(ItemStack o1, ItemStack o2) { + if ( o2 == null ) + return -1; + if( o1 == null ) + return 1; + Item item1 = o1.getItem(); + Item item2 = o2.getItem(); + + // If item1 is a block and item2 isn't, sort item1 before item2 + if (((item1 instanceof ItemBlock)) && (!(item2 instanceof ItemBlock))) { + return -1; + } + + // If item2 is a block and item1 isn't, sort item1 after item2 + if (((item2 instanceof ItemBlock)) && (!(item1 instanceof ItemBlock))) { + return 1; + } + + String displayName1 = o1.getDisplayName(); + String displayName2 = o2.getDisplayName(); + + int result = displayName1.compareToIgnoreCase(displayName2); + //System.out.println("sorter: " + displayName1 + " " + displayName2 + " " + result); + return result; + } + + protected void sortStacks() { + int i = 1, j; + while( i < this.mInventory.length ){ + j = i; + while( (j > 0) && ( compare(this.mInventory[j-1], this.mInventory[j]) == -1) ) { + GT_Utility.moveStackFromSlotAToSlotB(getBaseMetaTileEntity(), getBaseMetaTileEntity(), j, j-1, (byte) 64, (byte) 1, (byte) 64, (byte) 1); + j--; + } + i++; + } + } +*/ + + protected void fillStacksIntoFirstSlots() { + sortStacks(); + // Merge small stacks together + for (int i = 0; i < this.mInventory.length-1;) { + //System.out.println( (this.mInventory[i] == null) ? "Slot empty " + i : "Slot " + i + " holds " + this.mInventory[i].getDisplayName()); + for (int j = i + 1; j < this.mInventory.length; j++) { + if ((this.mInventory[j] != null) && ((GT_Utility.areStacksEqual(this.mInventory[i], this.mInventory[j])))) { + GT_Utility.moveStackFromSlotAToSlotB(getBaseMetaTileEntity(), getBaseMetaTileEntity(), j, i, (byte) 64, (byte) 1, (byte) 64, (byte) 1); + //System.out.println( "Moving slot " + j + " into slot " + i ); + } + else { + i=j; + break; // No more matching items for this i, do next i + } + } + } + } + + public Object getServerGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { + return new GT_Container_ChestBuffer(aPlayerInventory, aBaseMetaTileEntity); + } + + public Object getClientGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { + return new GT_GUIContainer_ChestBuffer(aPlayerInventory, aBaseMetaTileEntity); + } +} -- cgit From fe08b96bd94a487a2e26654b1812691a91bd3407 Mon Sep 17 00:00:00 2001 From: Richard Hendricks Date: Sat, 2 Jun 2018 03:05:39 -0500 Subject: For the first 6 ticks after pushing, always push. Then goto every 5 ticks. Should work OK for any machine. For higher output performance, use larger output stack size. Uses item ID numbers instead of strings to sort, much faster. Resolves https://github.com/GTNewHorizons/NewHorizons/issues/3006 --- .../api/metatileentity/BaseMetaTileEntity.java | 4 +- .../automation/GT_MetaTileEntity_ChestBuffer.java | 333 ++++++++++----------- 2 files changed, 161 insertions(+), 176 deletions(-) (limited to 'src/main/java/gregtech') diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java index 609a35bfae..95f3416a00 100644 --- a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java @@ -712,8 +712,10 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE if (tTime > tWorstTime) { tWorstTime = tTime; } + // Uncomment this line to print out tick-by-tick times. + //tList.add("tTime " + tTime); } - tList.add("Average CPU-load of ~" + (tAverageTime / mTimeStatistics.length) + "ns since " + mTimeStatistics.length + " ticks with worst time of " + tWorstTime + "ns."); + tList.add("Average CPU-load of ~" + (tAverageTime / mTimeStatistics.length) + "ns over " + mTimeStatistics.length + " ticks with worst time of " + tWorstTime + "ns."); } if (mLagWarningCount > 0) { tList.add("Caused " + (mLagWarningCount >= 10 ? "more than 10" : mLagWarningCount) + " Lag Spike Warnings (anything taking longer than " + GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING + "ms) on the Server."); diff --git a/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java b/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java index 99a360ad11..e73631cd93 100644 --- a/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java +++ b/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java @@ -1,175 +1,158 @@ -package gregtech.common.tileentities.automation; - -import gregtech.api.enums.Textures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Buffer; -import gregtech.api.objects.GT_RenderedTexture; -import gregtech.api.util.GT_Utility; -import gregtech.common.gui.GT_Container_ChestBuffer; -import gregtech.common.gui.GT_GUIContainer_ChestBuffer; -import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; - -import java.util.Arrays; -import java.util.Comparator; - -public class GT_MetaTileEntity_ChestBuffer - extends GT_MetaTileEntity_Buffer { - public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier) { - super(aID, aName, aNameRegional, aTier, 28, new String[]{ - "Buffers up to 27 Item Stacks", - "Use Screwdriver to regulate output stack size", - "Consumes 3EU per moved Item"}); - } - - public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String aDescription) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); - } - - public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String[] aDescription) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); - } - - public GT_MetaTileEntity_ChestBuffer(String aName, int aTier, int aInvSlotCount, String aDescription, ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_ChestBuffer(String aName, int aTier, int aInvSlotCount, String[] aDescription, ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_ChestBuffer(this.mName, this.mTier, this.mInventory.length, this.mDescriptionArray, this.mTextures); - } - - public ITexture getOverlayIcon() { - return new GT_RenderedTexture(Textures.BlockIcons.AUTOMATION_CHESTBUFFER); - } - - public boolean isValidSlot(int aIndex) { - return aIndex < this.mInventory.length - 1; - } - - protected void moveItems(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) { - if(aBaseMetaTileEntity.hasInventoryBeenModified()) { - fillStacksIntoFirstSlots(); - } - // mSuccess will be negative if the call is caused by the %200 aTimer. Otherwise it will be positive, and only every other tick is a push attempted. - if ( (mSuccess <= 0 ) || (( mSuccess > 0 ) && ( (mSuccess % 2) == 0 )) ){ - super.moveItems(aBaseMetaTileEntity, aTimer); - } - // mSuccesss is set to 50 on a successful move - if(mSuccess == 50) { - fillStacksIntoFirstSlots(); - } - if(mSuccess < 0) { - mSuccess = 0; - } - } - -// Implementation using Java built in sort algorithm -// Uses terribad string comparison to sort against. Would be better if we did something else? - protected void sortStacks() { - Arrays.sort(this.mInventory, new Comparator() { - @Override - // Taken from https://gist.github.com/Choonster/876acc3217229e172e46 - public int compare(ItemStack o1, ItemStack o2) { - if ( o2 == null ) - return -1; - if( o1 == null ) - return 1; - Item item1 = o1.getItem(); - Item item2 = o2.getItem(); - - // If item1 is a block and item2 isn't, sort item1 before item2 - if (((item1 instanceof ItemBlock)) && (!(item2 instanceof ItemBlock))) { - return -1; - } - - // If item2 is a block and item1 isn't, sort item1 after item2 - if (((item2 instanceof ItemBlock)) && (!(item1 instanceof ItemBlock))) { - return 1; - } - - String displayName1 = o1.getDisplayName(); - String displayName2 = o2.getDisplayName(); - - int result = displayName1.compareToIgnoreCase(displayName2); - //System.out.println("sorter: " + displayName1 + " " + displayName2 + " " + result); - return result; - } - }); - } - -// Implementation of insertion sort -// Worst case time of a 2.8ms -/* - public int compare(ItemStack o1, ItemStack o2) { - if ( o2 == null ) - return -1; - if( o1 == null ) - return 1; - Item item1 = o1.getItem(); - Item item2 = o2.getItem(); - - // If item1 is a block and item2 isn't, sort item1 before item2 - if (((item1 instanceof ItemBlock)) && (!(item2 instanceof ItemBlock))) { - return -1; - } - - // If item2 is a block and item1 isn't, sort item1 after item2 - if (((item2 instanceof ItemBlock)) && (!(item1 instanceof ItemBlock))) { - return 1; - } - - String displayName1 = o1.getDisplayName(); - String displayName2 = o2.getDisplayName(); - - int result = displayName1.compareToIgnoreCase(displayName2); - //System.out.println("sorter: " + displayName1 + " " + displayName2 + " " + result); - return result; - } - - protected void sortStacks() { - int i = 1, j; - while( i < this.mInventory.length ){ - j = i; - while( (j > 0) && ( compare(this.mInventory[j-1], this.mInventory[j]) == -1) ) { - GT_Utility.moveStackFromSlotAToSlotB(getBaseMetaTileEntity(), getBaseMetaTileEntity(), j, j-1, (byte) 64, (byte) 1, (byte) 64, (byte) 1); - j--; - } - i++; - } - } -*/ - - protected void fillStacksIntoFirstSlots() { - sortStacks(); - // Merge small stacks together - for (int i = 0; i < this.mInventory.length-1;) { - //System.out.println( (this.mInventory[i] == null) ? "Slot empty " + i : "Slot " + i + " holds " + this.mInventory[i].getDisplayName()); - for (int j = i + 1; j < this.mInventory.length; j++) { - if ((this.mInventory[j] != null) && ((GT_Utility.areStacksEqual(this.mInventory[i], this.mInventory[j])))) { - GT_Utility.moveStackFromSlotAToSlotB(getBaseMetaTileEntity(), getBaseMetaTileEntity(), j, i, (byte) 64, (byte) 1, (byte) 64, (byte) 1); - //System.out.println( "Moving slot " + j + " into slot " + i ); - } - else { - i=j; - break; // No more matching items for this i, do next i - } - } - } - } - - public Object getServerGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { - return new GT_Container_ChestBuffer(aPlayerInventory, aBaseMetaTileEntity); - } - - public Object getClientGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { - return new GT_GUIContainer_ChestBuffer(aPlayerInventory, aBaseMetaTileEntity); - } -} +package gregtech.common.tileentities.automation; + +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Buffer; +import gregtech.api.objects.GT_RenderedTexture; +import gregtech.api.util.GT_Utility; +import gregtech.common.gui.GT_Container_ChestBuffer; +import gregtech.common.gui.GT_GUIContainer_ChestBuffer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; + +import java.util.Arrays; +import java.util.Comparator; + +public class GT_MetaTileEntity_ChestBuffer + extends GT_MetaTileEntity_Buffer { + public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier) { + super(aID, aName, aNameRegional, aTier, 28, new String[]{ + "Buffers up to 27 Item Stacks", + "Use Screwdriver to regulate output stack size", + "Consumes 3EU per moved Item"}); + } + + public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String aDescription) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); + } + + public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String[] aDescription) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); + } + + public GT_MetaTileEntity_ChestBuffer(String aName, int aTier, int aInvSlotCount, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + public GT_MetaTileEntity_ChestBuffer(String aName, int aTier, int aInvSlotCount, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new GT_MetaTileEntity_ChestBuffer(this.mName, this.mTier, this.mInventory.length, this.mDescriptionArray, this.mTextures); + } + + public ITexture getOverlayIcon() { + return new GT_RenderedTexture(Textures.BlockIcons.AUTOMATION_CHESTBUFFER); + } + + public boolean isValidSlot(int aIndex) { + return aIndex < this.mInventory.length - 1; + } + + protected void moveItems(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) { + if(aBaseMetaTileEntity.hasInventoryBeenModified()) { + fillStacksIntoFirstSlots(); + } + // mSuccess will be negative if the call is caused by the %200 aTimer, always try to push. Otherwise it will be positive. + // For the first 6 ticks after a successful move (49->44), push every tick. Then go to every 5 ticks. + if ( (mSuccess <= 0 ) || (mSuccess > 43) || ((mSuccess % 5) == 0 )){ + super.moveItems(aBaseMetaTileEntity, aTimer); + } + // mSuccesss is set to 50 on a successful move + if(mSuccess == 50) { + fillStacksIntoFirstSlots(); + } + if(mSuccess < 0) { + mSuccess = 0; + } + } + +// Implementation using Java built in sort algorithm +// Uses terribad string comparison to sort against. Would be better if we did something else? + protected void sortStacks() { + Arrays.sort(this.mInventory, new Comparator() { + @Override + // Taken from https://gist.github.com/Choonster/876acc3217229e172e46 + public int compare(ItemStack o1, ItemStack o2) { + if( o2 == null ) + return -1; + if( o1 == null ) + return 1; + Item item1 = o1.getItem(); + Item item2 = o2.getItem(); + + // If item1 is a block and item2 isn't, sort item1 before item2 + if (((item1 instanceof ItemBlock)) && (!(item2 instanceof ItemBlock))) { + return -1; + } + + // If item2 is a block and item1 isn't, sort item1 after item2 + if (((item2 instanceof ItemBlock)) && (!(item1 instanceof ItemBlock))) { + return 1; + } + + // If the items are blocks, use the string comparison + if ((item1 instanceof ItemBlock)) { // only need to check one since we did the check above + String displayName1 = o1.getDisplayName(); + String displayName2 = o2.getDisplayName(); + int result = displayName1.compareToIgnoreCase(displayName2); + //System.out.println("sorter: " + displayName1 + " " + displayName2 + " " + result); + return result; + } else + { + // Not a block. Use the ID and damage to compare them. + int id1 = Item.getIdFromItem( item1 ); + int id2 = Item.getIdFromItem( item2 ); + if ( id1 < id2 ) { + return -1; + } + if ( id1 > id2 ) { + return 1; + } + // id1 must equal id2, get their damage and compare + id1 = o1.getItemDamage(); + id2 = o2.getItemDamage(); + + if ( id1 < id2 ) { + return -1; + } + if ( id1 > id2 ) { + return 1; + } + return 0; + } + } + }); + } + + protected void fillStacksIntoFirstSlots() { + sortStacks(); + // Merge small stacks together + for (int i = 0; i < this.mInventory.length-1;) { + //System.out.println( (this.mInventory[i] == null) ? "Slot empty " + i : "Slot " + i + " holds " + this.mInventory[i].getDisplayName()); + for (int j = i + 1; j < this.mInventory.length; j++) { + if ((this.mInventory[j] != null) && ((GT_Utility.areStacksEqual(this.mInventory[i], this.mInventory[j])))) { + GT_Utility.moveStackFromSlotAToSlotB(getBaseMetaTileEntity(), getBaseMetaTileEntity(), j, i, (byte) 64, (byte) 1, (byte) 64, (byte) 1); + //System.out.println( "Moving slot " + j + " into slot " + i ); + } + else { + i=j; + break; // No more matching items for this i, do next i + } + } + } + } + + public Object getServerGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { + return new GT_Container_ChestBuffer(aPlayerInventory, aBaseMetaTileEntity); + } + + public Object getClientGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { + return new GT_GUIContainer_ChestBuffer(aPlayerInventory, aBaseMetaTileEntity); + } +} -- cgit