From 61dfc05ae0a17a163d76d41ff4192a54e80c864a Mon Sep 17 00:00:00 2001 From: yueh Date: Tue, 19 May 2015 16:07:02 +0200 Subject: [PATCH] Added a simple ETA to crafting jobs --- .../gui/implementations/GuiCraftingCPU.java | 154 +++++++++--------- .../implementations/ContainerCraftingCPU.java | 25 ++- .../appeng/core/localization/GuiText.java | 2 +- .../implementations/CraftingCPUCluster.java | 69 +++++++- .../appliedenergistics2/lang/en_US.lang | 2 + 5 files changed, 168 insertions(+), 84 deletions(-) diff --git a/src/main/java/appeng/client/gui/implementations/GuiCraftingCPU.java b/src/main/java/appeng/client/gui/implementations/GuiCraftingCPU.java index c0a325ff..d3888cc5 100644 --- a/src/main/java/appeng/client/gui/implementations/GuiCraftingCPU.java +++ b/src/main/java/appeng/client/gui/implementations/GuiCraftingCPU.java @@ -24,9 +24,11 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.concurrent.TimeUnit; import com.google.common.base.Joiner; +import org.apache.commons.lang3.time.DurationFormatUtils; import org.lwjgl.opengl.GL11; import net.minecraft.client.gui.GuiButton; @@ -50,20 +52,45 @@ import appeng.core.localization.GuiText; import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.packets.PacketValueConfig; import appeng.util.Platform; +import appeng.util.ReadableNumberConverter; public class GuiCraftingCPU extends AEBaseGui implements ISortSource { + private final static int GUI_HEIGHT = 184; + private final static int GUI_WIDTH = 238; - final int rows = 6; + private final static int DISPLAYED_ROWS = 6; - IItemList storage = AEApi.instance().storage().createItemList(); - IItemList active = AEApi.instance().storage().createItemList(); - IItemList pending = AEApi.instance().storage().createItemList(); + private final static int TEXT_COLOR = 0x404040; + private final static int BACKGROUND_ALPHA = 0x5A000000; - List visual = new ArrayList(); - GuiButton cancel; - int tooltip = -1; + private final static int SECTION_LENGTH = 67; + + private final static int SCROLLBAR_TOP = 19; + private final static int SCROLLBAR_LEFT = 218; + private final static int SCROLLBAR_HEIGHT = 137; + + private final static int CANCEL_LEFT_OFFSET = 163; + private final static int CANCEL_TOP_OFFSET = 25; + private final static int CANCEL_HEIGHT = 20; + private final static int CANCEL_WIDTH = 50; + + private final static int ETA_TOP_OFFSET = 165; + private final static int ETA_LEFT_OFFSET = 8; + + private final static int ITEMSTACK_LEFT_OFFSET = 9; + private final static int ITEMSTACK_TOP_OFFSET = 22; + + private final ContainerCraftingCPU craftingCpu; + + private IItemList storage = AEApi.instance().storage().createItemList(); + private IItemList active = AEApi.instance().storage().createItemList(); + private IItemList pending = AEApi.instance().storage().createItemList(); + + private List visual = new ArrayList(); + private GuiButton cancel; + private int tooltip = -1; public GuiCraftingCPU( InventoryPlayer inventoryPlayer, Object te ) { @@ -73,8 +100,9 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource protected GuiCraftingCPU( ContainerCraftingCPU container ) { super( container ); - this.ySize = 184; - this.xSize = 238; + this.craftingCpu = container; + this.ySize = GUI_HEIGHT; + this.xSize = GUI_WIDTH; this.myScrollBar = new GuiScrollbar(); } @@ -109,7 +137,7 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource { super.initGui(); this.setScrollBar(); - this.cancel = new GuiButton( 0, this.guiLeft + 163, this.guiTop + this.ySize - 25, 50, 20, GuiText.Cancel.getLocal() ); + this.cancel = new GuiButton( 0, this.guiLeft + CANCEL_LEFT_OFFSET, this.guiTop + this.ySize - CANCEL_TOP_OFFSET, CANCEL_WIDTH, CANCEL_HEIGHT, GuiText.Cancel.getLocal() ); this.buttonList.add( this.cancel ); } @@ -117,8 +145,8 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource { int size = this.visual.size(); - this.myScrollBar.setTop( 19 ).setLeft( 218 ).setHeight( 137 ); - this.myScrollBar.setRange( 0, ( size + 2 ) / 3 - this.rows, 1 ); + this.myScrollBar.setTop( SCROLLBAR_TOP ).setLeft( SCROLLBAR_LEFT ).setHeight( SCROLLBAR_HEIGHT ); + this.myScrollBar.setRange( 0, ( size + 2 ) / 3 - DISPLAYED_ROWS, 1 ); } @Override @@ -129,9 +157,9 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource int x = 0; int y = 0; - int gx = ( this.width - this.xSize ) / 2; - int gy = ( this.height - this.ySize ) / 2; - int offY = 23; + final int gx = ( this.width - this.xSize ) / 2; + final int gy = ( this.height - this.ySize ) / 2; + final int offY = 23; this.tooltip = -1; @@ -164,16 +192,22 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource @Override public void drawFG( int offsetX, int offsetY, int mouseX, int mouseY ) { - this.fontRendererObj.drawString( this.getGuiDisplayName( GuiText.CraftingStatus.getLocal() ), 8, 7, 4210752 ); + ReadableNumberConverter converter = ReadableNumberConverter.INSTANCE; - int sectionLength = 67; + this.fontRendererObj.drawString( this.getGuiDisplayName( GuiText.CraftingStatus.getLocal() ), 8, 7, TEXT_COLOR ); + + if( this.craftingCpu.eta > 0 ) + { + final String etaText = this.getGuiDisplayName( GuiText.ETA.getLocal() ); + final long etaInMilliseconds = TimeUnit.MILLISECONDS.convert( this.craftingCpu.eta, TimeUnit.NANOSECONDS ); + final String etaTimeText = DurationFormatUtils.formatDuration( etaInMilliseconds, this.getGuiDisplayName( GuiText.ETAFormat.getLocal() ) ); + this.fontRendererObj.drawString( String.format( etaText, etaTimeText ), ETA_LEFT_OFFSET, ETA_TOP_OFFSET, TEXT_COLOR ); + } int x = 0; int y = 0; - int xo = 9; - int yo = 22; - int viewStart = this.myScrollBar.getCurrentScroll() * 3; - int viewEnd = viewStart + 3 * 6; + final int viewStart = this.myScrollBar.getCurrentScroll() * 3; + final int viewEnd = viewStart + 3 * 6; String dspToolTip = ""; List lineList = new LinkedList(); @@ -190,9 +224,9 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource GL11.glPushMatrix(); GL11.glScaled( 0.5, 0.5, 0.5 ); - IAEItemStack stored = this.storage.findPrecise( refStack ); - IAEItemStack activeStack = this.active.findPrecise( refStack ); - IAEItemStack pendingStack = this.pending.findPrecise( refStack ); + final IAEItemStack stored = this.storage.findPrecise( refStack ); + final IAEItemStack activeStack = this.active.findPrecise( refStack ); + final IAEItemStack pendingStack = this.pending.findPrecise( refStack ); int lines = 0; boolean active = false; @@ -215,10 +249,10 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource if( AEConfig.instance.useColoredCraftingStatus && ( active || scheduled ) ) { - int bgColor = ( active ? AEColor.Green.blackVariant : AEColor.Yellow.blackVariant ) | 0x5A000000; - int startX = ( x * ( 1 + sectionLength ) + xo ) * 2; - int startY = ( ( y * offY + yo ) - 3 ) * 2; - drawRect( startX, startY, startX + ( sectionLength * 2 ), startY + ( offY * 2 ) - 2, bgColor ); + int bgColor = ( active ? AEColor.Green.blackVariant : AEColor.Yellow.blackVariant ) | BACKGROUND_ALPHA; + int startX = ( x * ( 1 + SECTION_LENGTH ) + ITEMSTACK_LEFT_OFFSET ) * 2; + int startY = ( ( y * offY + ITEMSTACK_TOP_OFFSET ) - 3 ) * 2; + drawRect( startX, startY, startX + ( SECTION_LENGTH * 2 ), startY + ( offY * 2 ) - 2, bgColor ); } int negY = ( ( lines - 1 ) * 5 ) / 2; @@ -226,19 +260,9 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource if( stored != null && stored.getStackSize() > 0 ) { - String str = Long.toString( stored.getStackSize() ); - if( stored.getStackSize() >= 10000 ) - { - str = Long.toString( stored.getStackSize() / 1000 ) + 'k'; - } - if( stored.getStackSize() >= 10000000 ) - { - str = Long.toString( stored.getStackSize() / 1000000 ) + 'm'; - } - - str = GuiText.Stored.getLocal() + ": " + str; + final String str = GuiText.Stored.getLocal() + ": " + converter.toWideReadableForm( stored.getStackSize() ); int w = 4 + this.fontRendererObj.getStringWidth( str ); - this.fontRendererObj.drawString( str, (int) ( ( x * ( 1 + sectionLength ) + xo + sectionLength - 19 - ( w * 0.5 ) ) * 2 ), ( y * offY + yo + 6 - negY + downY ) * 2, 4210752 ); + this.fontRendererObj.drawString( str, (int) ( ( x * ( 1 + SECTION_LENGTH ) + ITEMSTACK_LEFT_OFFSET + SECTION_LENGTH - 19 - ( w * 0.5 ) ) * 2 ), ( y * offY + ITEMSTACK_TOP_OFFSET + 6 - negY + downY ) * 2, TEXT_COLOR ); if( this.tooltip == z - viewStart ) { @@ -250,19 +274,10 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource if( activeStack != null && activeStack.getStackSize() > 0 ) { - String str = Long.toString( activeStack.getStackSize() ); - if( activeStack.getStackSize() >= 10000 ) - { - str = Long.toString( activeStack.getStackSize() / 1000 ) + 'k'; - } - if( activeStack.getStackSize() >= 10000000 ) - { - str = Long.toString( activeStack.getStackSize() / 1000000 ) + 'm'; - } + final String str = GuiText.Crafting.getLocal() + ": " + converter.toWideReadableForm( activeStack.getStackSize() ); + final int w = 4 + this.fontRendererObj.getStringWidth( str ); - str = GuiText.Crafting.getLocal() + ": " + str; - int w = 4 + this.fontRendererObj.getStringWidth( str ); - this.fontRendererObj.drawString( str, (int) ( ( x * ( 1 + sectionLength ) + xo + sectionLength - 19 - ( w * 0.5 ) ) * 2 ), ( y * offY + yo + 6 - negY + downY ) * 2, 4210752 ); + this.fontRendererObj.drawString( str, (int) ( ( x * ( 1 + SECTION_LENGTH ) + ITEMSTACK_LEFT_OFFSET + SECTION_LENGTH - 19 - ( w * 0.5 ) ) * 2 ), ( y * offY + ITEMSTACK_TOP_OFFSET + 6 - negY + downY ) * 2, TEXT_COLOR ); if( this.tooltip == z - viewStart ) { @@ -274,19 +289,10 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource if( pendingStack != null && pendingStack.getStackSize() > 0 ) { - String str = Long.toString( pendingStack.getStackSize() ); - if( pendingStack.getStackSize() >= 10000 ) - { - str = Long.toString( pendingStack.getStackSize() / 1000 ) + 'k'; - } - if( pendingStack.getStackSize() >= 10000000 ) - { - str = Long.toString( pendingStack.getStackSize() / 1000000 ) + 'm'; - } + final String str = GuiText.Scheduled.getLocal() + ": " + converter.toWideReadableForm( pendingStack.getStackSize() ); + final int w = 4 + this.fontRendererObj.getStringWidth( str ); - str = GuiText.Scheduled.getLocal() + ": " + str; - int w = 4 + this.fontRendererObj.getStringWidth( str ); - this.fontRendererObj.drawString( str, (int) ( ( x * ( 1 + sectionLength ) + xo + sectionLength - 19 - ( w * 0.5 ) ) * 2 ), ( y * offY + yo + 6 - negY + downY ) * 2, 4210752 ); + this.fontRendererObj.drawString( str, (int) ( ( x * ( 1 + SECTION_LENGTH ) + ITEMSTACK_LEFT_OFFSET + SECTION_LENGTH - 19 - ( w * 0.5 ) ) * 2 ), ( y * offY + ITEMSTACK_TOP_OFFSET + 6 - negY + downY ) * 2, TEXT_COLOR ); if( this.tooltip == z - viewStart ) { @@ -295,8 +301,8 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource } GL11.glPopMatrix(); - int posX = x * ( 1 + sectionLength ) + xo + sectionLength - 19; - int posY = y * offY + yo; + int posX = x * ( 1 + SECTION_LENGTH ) + ITEMSTACK_LEFT_OFFSET + SECTION_LENGTH - 19; + int posY = y * offY + ITEMSTACK_TOP_OFFSET; ItemStack is = refStack.copy().getItemStack(); @@ -309,8 +315,8 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource dspToolTip = dspToolTip + '\n' + Joiner.on( "\n" ).join( lineList ); } - toolPosX = x * ( 1 + sectionLength ) + xo + sectionLength - 8; - toolPosY = y * offY + yo; + toolPosX = x * ( 1 + SECTION_LENGTH ) + ITEMSTACK_LEFT_OFFSET + SECTION_LENGTH - 8; + toolPosY = y * offY + ITEMSTACK_TOP_OFFSET; } this.drawItem( posX, posY, is ); @@ -412,9 +418,9 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource private long getTotal( IAEItemStack is ) { - IAEItemStack a = this.storage.findPrecise( is ); - IAEItemStack b = this.active.findPrecise( is ); - IAEItemStack c = this.pending.findPrecise( is ); + final IAEItemStack a = this.storage.findPrecise( is ); + final IAEItemStack b = this.active.findPrecise( is ); + final IAEItemStack c = this.pending.findPrecise( is ); long total = 0; @@ -438,7 +444,8 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource private void deleteVisualStack( IAEItemStack l ) { - Iterator i = this.visual.iterator(); + final Iterator i = this.visual.iterator(); + while( i.hasNext() ) { IAEItemStack o = i.next(); @@ -460,8 +467,9 @@ public class GuiCraftingCPU extends AEBaseGui implements ISortSource } } - IAEItemStack stack = l.copy(); + final IAEItemStack stack = l.copy(); this.visual.add( stack ); + return stack; } diff --git a/src/main/java/appeng/container/implementations/ContainerCraftingCPU.java b/src/main/java/appeng/container/implementations/ContainerCraftingCPU.java index 8b69a1e5..f6fed9d3 100644 --- a/src/main/java/appeng/container/implementations/ContainerCraftingCPU.java +++ b/src/main/java/appeng/container/implementations/ContainerCraftingCPU.java @@ -39,6 +39,7 @@ import appeng.api.storage.IMEMonitorHandlerReceiver; import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IItemList; import appeng.container.AEBaseContainer; +import appeng.container.guisync.GuiSync; import appeng.core.AELog; import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.packets.PacketMEInventoryUpdate; @@ -59,6 +60,9 @@ public class ContainerCraftingCPU extends AEBaseContainer implements IMEMonitorH String cpuName = null; int delay = 40; + @GuiSync( 0 ) + public long eta = -1; + public ContainerCraftingCPU( InventoryPlayer ip, Object te ) { super( ip, te ); @@ -126,14 +130,11 @@ public class ContainerCraftingCPU extends AEBaseContainer implements IMEMonitorH if( c instanceof CraftingCPUCluster ) { this.cpuName = c.getName(); - this.monitor = (CraftingCPUCluster) c; - if( this.monitor != null ) - { - this.list.resetStatus(); - this.monitor.getListOfItem( this.list, CraftingItemList.ALL ); - this.monitor.addListener( this, null ); - } + this.list.resetStatus(); + this.monitor.getListOfItem( this.list, CraftingItemList.ALL ); + this.monitor.addListener( this, null ); + this.eta = 0; } else { @@ -148,6 +149,7 @@ public class ContainerCraftingCPU extends AEBaseContainer implements IMEMonitorH { this.monitor.cancel(); } + this.eta = -1; } @Override @@ -178,6 +180,15 @@ public class ContainerCraftingCPU extends AEBaseContainer implements IMEMonitorH { try { + if( this.eta >= 0 ) + { + final long elapsedTime = this.monitor.getElapsedTime(); + final double remainingItems = this.monitor.getRemainingItemCount(); + final double startItems = this.monitor.getStartItemCount(); + final long eta = (long) ( elapsedTime / Math.max( 1d, ( startItems - remainingItems ) ) * remainingItems ); + this.eta = eta; + } + PacketMEInventoryUpdate a = new PacketMEInventoryUpdate( (byte) 0 ); PacketMEInventoryUpdate b = new PacketMEInventoryUpdate( (byte) 1 ); PacketMEInventoryUpdate c = new PacketMEInventoryUpdate( (byte) 2 ); diff --git a/src/main/java/appeng/core/localization/GuiText.java b/src/main/java/appeng/core/localization/GuiText.java index c8884e4f..b686938e 100644 --- a/src/main/java/appeng/core/localization/GuiText.java +++ b/src/main/java/appeng/core/localization/GuiText.java @@ -59,7 +59,7 @@ public enum GuiText NoSecondOutput, Stores, Next, SelectAmount, Lumen, Empty, - ConfirmCrafting, Stored, Crafting, Scheduled, CraftingStatus, Cancel, + ConfirmCrafting, Stored, Crafting, Scheduled, CraftingStatus, Cancel, ETA, ETAFormat, FromStorage, ToCraft, CraftingPlan, CalculatingWait, Start, Bytes, diff --git a/src/main/java/appeng/me/cluster/implementations/CraftingCPUCluster.java b/src/main/java/appeng/me/cluster/implementations/CraftingCPUCluster.java index 1dba6c8c..4c1cf708 100644 --- a/src/main/java/appeng/me/cluster/implementations/CraftingCPUCluster.java +++ b/src/main/java/appeng/me/cluster/implementations/CraftingCPUCluster.java @@ -109,6 +109,11 @@ public class CraftingCPUCluster implements IAECluster, ICraftingCPU private int remainingOperations; private boolean somethingChanged; + private long lastTime; + private long elapsedTime; + private long startItemCount; + private long remainingItemCount; + public CraftingCPUCluster( WorldCoord min, WorldCoord max ) { this.min = min; @@ -272,11 +277,13 @@ public class CraftingCPUCluster implements IAECluster, ICraftingCPU if( is != null && is.getStackSize() > 0 ) { this.waiting = false; + this.postChange( (IAEItemStack) input, src ); if( is.getStackSize() >= input.getStackSize() ) { is.decStackSize( input.getStackSize() ); + this.updateElapsedTime( (IAEItemStack) input ); this.markDirty(); this.postCraftingStatusChange( is ); @@ -406,6 +413,10 @@ public class CraftingCPUCluster implements IAECluster, ICraftingCPU } AELog.crafting( "marking job as complete" ); + this.remainingItemCount = 0; + this.startItemCount = 0; + this.lastTime = 0; + this.elapsedTime = 0; this.isComplete = true; } @@ -838,6 +849,8 @@ public class CraftingCPUCluster implements IAECluster, ICraftingCPU this.myLastLink = new CraftingLink( this.generateLinkData( craftID, requestingMachine == null, false ), this ); + this.prepareElapsedTime(); + if( requestingMachine == null ) { return this.myLastLink; @@ -848,9 +861,8 @@ public class CraftingCPUCluster implements IAECluster, ICraftingCPU this.submitLink( this.myLastLink ); this.submitLink( whatLink ); - IItemList list; - this.getListOfItem( list = AEApi.instance().storage().createItemList(), CraftingItemList.ALL ); - + IItemList list = AEApi.instance().storage().createItemList(); + this.getListOfItem( list, CraftingItemList.ALL ); for( IAEItemStack ge : list ) { this.postChange( ge, this.machineSrc ); @@ -1097,6 +1109,10 @@ public class CraftingCPUCluster implements IAECluster, ICraftingCPU data.setTag( "tasks", list ); data.setTag( "waitingFor", this.writeList( this.waitingFor ) ); + + data.setLong( "elapsedTime", this.getElapsedTime() ); + data.setLong( "startItemCount", this.getStartItemCount() ); + data.setLong( "remainingItemCount", this.getRemainingItemCount() ); } private NBTTagCompound writeItem( IAEItemStack finalOutput2 ) @@ -1180,6 +1196,11 @@ public class CraftingCPUCluster implements IAECluster, ICraftingCPU { this.postCraftingStatusChange( is.copy() ); } + + this.lastTime = System.nanoTime(); + this.elapsedTime = data.getLong( "elapsedTime" ); + this.startItemCount = data.getLong( "startItemCount" ); + this.remainingItemCount = data.getLong( "remainingItemCount" ); } public void updateName() @@ -1242,6 +1263,48 @@ public class CraftingCPUCluster implements IAECluster, ICraftingCPU } } + private void prepareElapsedTime() + { + this.lastTime = System.nanoTime(); + this.elapsedTime = 0; + int itemCount = 0; + + IItemList list = AEApi.instance().storage().createItemList(); + this.getListOfItem( list, CraftingItemList.ACTIVE ); + this.getListOfItem( list, CraftingItemList.PENDING ); + + for( IAEItemStack ge : list ) + { + itemCount += ge.getStackSize(); + } + + this.startItemCount = itemCount; + this.remainingItemCount = itemCount; + } + + private void updateElapsedTime( IAEItemStack is ) + { + final long nextStartTime = System.nanoTime(); + this.elapsedTime = this.getElapsedTime() + nextStartTime - lastTime; + this.lastTime = nextStartTime; + this.remainingItemCount = this.getRemainingItemCount() - is.getStackSize(); + } + + public long getElapsedTime() + { + return elapsedTime; + } + + public long getRemainingItemCount() + { + return remainingItemCount; + } + + public long getStartItemCount() + { + return startItemCount; + } + static class TaskProgress { diff --git a/src/main/resources/assets/appliedenergistics2/lang/en_US.lang b/src/main/resources/assets/appliedenergistics2/lang/en_US.lang index e3e6f7fc..6dd6f068 100644 --- a/src/main/resources/assets/appliedenergistics2/lang/en_US.lang +++ b/src/main/resources/assets/appliedenergistics2/lang/en_US.lang @@ -184,6 +184,8 @@ gui.appliedenergistics2.Lumen=Lumen gui.appliedenergistics2.Empty=Empty gui.appliedenergistics2.Stored=Stored gui.appliedenergistics2.Cancel=Cancel +gui.appliedenergistics2.ETA=ETA: %s +gui.appliedenergistics2.ETAFormat=HH:mm:ss gui.appliedenergistics2.Crafting=Crafting gui.appliedenergistics2.Scheduled=Scheduled gui.appliedenergistics2.CraftingStatus=Crafting Status