Merge pull request #1269 from thatsIch/b-1256-number-converter
Fixes #1256: Using new size logic to determine the abbreviation for a stack size
This commit is contained in:
@@ -30,12 +30,21 @@ import net.minecraft.item.ItemStack;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.util.ISlimReadableNumberConverter;
|
||||
import appeng.util.IWideReadableNumberConverter;
|
||||
import appeng.util.ReadableNumberConverter;
|
||||
|
||||
|
||||
/**
|
||||
* @author AlgorithmX2
|
||||
* @author thatsIch
|
||||
* @version rv2
|
||||
* @since rv0
|
||||
*/
|
||||
public class AppEngRenderItem extends RenderItem
|
||||
{
|
||||
private static final ReadableNumberConverter NUMBER_CONVERTER = ReadableNumberConverter.INSTANCE;
|
||||
private static final ISlimReadableNumberConverter SLIM_CONVERTER = ReadableNumberConverter.INSTANCE;
|
||||
private static final IWideReadableNumberConverter WIDE_CONVERTER = ReadableNumberConverter.INSTANCE;
|
||||
|
||||
public IAEItemStack aeStack;
|
||||
|
||||
@@ -125,11 +134,11 @@ public class AppEngRenderItem extends RenderItem
|
||||
{
|
||||
if( AEConfig.instance.useTerminalUseLargeFont() )
|
||||
{
|
||||
return NUMBER_CONVERTER.toShortHumanReadableForm( originalSize );
|
||||
return SLIM_CONVERTER.toSlimReadableForm( originalSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
return NUMBER_CONVERTER.toLongHumanReadableForm( originalSize );
|
||||
return WIDE_CONVERTER.toWideReadableForm( originalSize );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,13 +37,20 @@ import appeng.client.ClientHelper;
|
||||
import appeng.core.AELog;
|
||||
import appeng.tile.AEBaseTile;
|
||||
import appeng.tile.crafting.TileCraftingMonitorTile;
|
||||
import appeng.util.IWideReadableNumberConverter;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.ReadableNumberConverter;
|
||||
|
||||
|
||||
/**
|
||||
* @author AlgorithmX2
|
||||
* @author thatsIch
|
||||
* @version rv2
|
||||
* @since rv1
|
||||
*/
|
||||
public class RenderBlockCraftingCPUMonitor extends RenderBlockCraftingCPU
|
||||
{
|
||||
private static final ReadableNumberConverter NUMBER_CONVERTER = ReadableNumberConverter.INSTANCE;
|
||||
private static final IWideReadableNumberConverter NUMBER_CONVERTER = ReadableNumberConverter.INSTANCE;
|
||||
|
||||
public RenderBlockCraftingCPUMonitor()
|
||||
{
|
||||
@@ -174,7 +181,7 @@ public class RenderBlockCraftingCPUMonitor extends RenderBlockCraftingCPU
|
||||
GL11.glScalef( 1.0f / 62.0f, 1.0f / 62.0f, 1.0f / 62.0f );
|
||||
|
||||
final long stackSize = ais.getStackSize();
|
||||
final String renderedStackSize = NUMBER_CONVERTER.toHumanReadableForm( stackSize );
|
||||
final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm( stackSize );
|
||||
|
||||
FontRenderer fr = Minecraft.getMinecraft().fontRenderer;
|
||||
int width = fr.getStringWidth( renderedStackSize );
|
||||
|
||||
@@ -59,14 +59,21 @@ import appeng.core.AELog;
|
||||
import appeng.core.localization.PlayerMessages;
|
||||
import appeng.helpers.Reflected;
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.util.IWideReadableNumberConverter;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.ReadableNumberConverter;
|
||||
import appeng.util.item.AEItemStack;
|
||||
|
||||
|
||||
/**
|
||||
* @author AlgorithmX2
|
||||
* @author thatsIch
|
||||
* @version rv2
|
||||
* @since rv0
|
||||
*/
|
||||
public class PartStorageMonitor extends PartMonitor implements IPartStorageMonitor, IStackWatcherHost
|
||||
{
|
||||
private static final ReadableNumberConverter NUMBER_CONVERTER = ReadableNumberConverter.INSTANCE;
|
||||
private static final IWideReadableNumberConverter NUMBER_CONVERTER = ReadableNumberConverter.INSTANCE;
|
||||
IAEItemStack configuredItem;
|
||||
boolean isLocked;
|
||||
IStackWatcher myWatcher;
|
||||
@@ -339,7 +346,7 @@ public class PartStorageMonitor extends PartMonitor implements IPartStorageMonit
|
||||
GL11.glScalef( 1.0f / 62.0f, 1.0f / 62.0f, 1.0f / 62.0f );
|
||||
|
||||
final long stackSize = ais.getStackSize();
|
||||
final String renderedStackSize = NUMBER_CONVERTER.toHumanReadableForm( stackSize );
|
||||
final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm( stackSize );
|
||||
|
||||
FontRenderer fr = Minecraft.getMinecraft().fontRenderer;
|
||||
int width = fr.getStringWidth( renderedStackSize );
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package appeng.util;
|
||||
|
||||
|
||||
import javax.annotation.Nonnegative;
|
||||
|
||||
|
||||
/**
|
||||
* Limits a number converter to a char width of at max 3 characters.
|
||||
* This is generally used for players, who activated the large font extension.
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv2
|
||||
* @since rv2
|
||||
*/
|
||||
public interface ISlimReadableNumberConverter
|
||||
{
|
||||
/**
|
||||
* Converts a number into a human readable form. It will not round the number, but down it.
|
||||
* Will try to cut the number down 1 decimal later, but rarely because of the 3 width limitation.
|
||||
* Can only handle non negative numbers
|
||||
*
|
||||
* Example:
|
||||
* 10000L -> 10K
|
||||
* 9999L -> 9K, not 9.9K cause 4 width
|
||||
*
|
||||
* @param number to be converted number
|
||||
*
|
||||
* @return String in SI format cut down as far as possible
|
||||
*/
|
||||
String toSlimReadableForm( @Nonnegative long number );
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package appeng.util;
|
||||
|
||||
|
||||
import javax.annotation.Nonnegative;
|
||||
|
||||
|
||||
/**
|
||||
* Limits a number converter to a char width of at max 4 characters
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv2
|
||||
* @since rv2
|
||||
*/
|
||||
public interface IWideReadableNumberConverter
|
||||
{
|
||||
/**
|
||||
* Converts a number into a human readable form. It will not round the number, but down it.
|
||||
* Will try to cut the number down 1 decimal later if width can be below 4.
|
||||
* Can only handle non negative numbers
|
||||
*
|
||||
* Example:
|
||||
* 10000L -> 10K
|
||||
* 9999L -> 9999
|
||||
*
|
||||
* @param number to be converted number
|
||||
*
|
||||
* @return String in SI format cut down as far as possible
|
||||
*/
|
||||
String toWideReadableForm( @Nonnegative long number );
|
||||
}
|
||||
@@ -1,6 +1,12 @@
|
||||
package appeng.util;
|
||||
|
||||
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.Format;
|
||||
|
||||
|
||||
/**
|
||||
* Converter class to convert a large number into a SI system.
|
||||
*
|
||||
@@ -8,7 +14,7 @@ package appeng.util;
|
||||
* @version rv2
|
||||
* @since rv2
|
||||
*/
|
||||
public enum ReadableNumberConverter
|
||||
public enum ReadableNumberConverter implements ISlimReadableNumberConverter, IWideReadableNumberConverter
|
||||
{
|
||||
INSTANCE;
|
||||
|
||||
@@ -17,125 +23,82 @@ public enum ReadableNumberConverter
|
||||
*/
|
||||
private static final int DIVISION_BASE = 1000;
|
||||
|
||||
/**
|
||||
* for lg(1000) = 3, just saves some calculation
|
||||
*/
|
||||
private static final double LOG_DIVISION_BASE = Math.log( DIVISION_BASE );
|
||||
|
||||
/**
|
||||
* String representation of the sorted postfixes
|
||||
*/
|
||||
private static final char[] ENCODED_POSTFIXES = "KMGTPE".toCharArray();
|
||||
|
||||
/**
|
||||
* if a result would be higher than this threshold,
|
||||
* it is pushed into the next bigger group,
|
||||
* so the display string is shorter
|
||||
*/
|
||||
private static final int SHORT_THRESHOLD = 100;
|
||||
private final Format format;
|
||||
|
||||
/**
|
||||
* Converts a number into a human readable form. It will not round the number, but floor it.
|
||||
*
|
||||
* Example: 15555L -> 15.5K
|
||||
*
|
||||
* @param number to be converted number
|
||||
*
|
||||
* @return String in SI format cut down as far as possible
|
||||
* Initializes the specific decimal format with special format for negative and positive numbers
|
||||
*/
|
||||
public String toHumanReadableForm( long number )
|
||||
ReadableNumberConverter()
|
||||
{
|
||||
final String sign = this.getSign( number );
|
||||
final long absNumber = Math.abs( number );
|
||||
final DecimalFormatSymbols symbols = new DecimalFormatSymbols();
|
||||
symbols.setDecimalSeparator( '.' );
|
||||
final DecimalFormat format = new DecimalFormat( ".#;0.#" );
|
||||
format.setDecimalFormatSymbols( symbols );
|
||||
format.setRoundingMode( RoundingMode.DOWN );
|
||||
|
||||
if( absNumber < DIVISION_BASE )
|
||||
return Long.toString( number );
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
final int exp = (int) ( Math.log( absNumber ) / LOG_DIVISION_BASE );
|
||||
final char postFix = ENCODED_POSTFIXES[exp - 1];
|
||||
final int result = (int) ( absNumber / Math.pow( DIVISION_BASE, exp ) );
|
||||
|
||||
return String.format( "%s%d%s", sign, result, postFix );
|
||||
@Override
|
||||
public String toSlimReadableForm( long number )
|
||||
{
|
||||
return this.toReadableFormRestrictedByWidth( number, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets character representation of the sign of a number
|
||||
* restricts a string representation of a number to a specific width
|
||||
*
|
||||
* @param number maybe signed number
|
||||
* @param number to be formatted number
|
||||
* @param width width limitation of the resulting number
|
||||
*
|
||||
* @return '-' if the number is signed, else an empty character
|
||||
* @return formatted number restricted by the width limitation
|
||||
*/
|
||||
private String getSign( long number )
|
||||
private String toReadableFormRestrictedByWidth( long number, int width )
|
||||
{
|
||||
if( number < 0 )
|
||||
assert number >= 0;
|
||||
|
||||
// handles low numbers more efficiently since no format is needed
|
||||
final String numberString = Long.toString( number );
|
||||
int numberSize = numberString.length();
|
||||
if( numberSize <= width )
|
||||
return numberString;
|
||||
|
||||
long base = number;
|
||||
double last = base * 1000;
|
||||
int exponent = -1;
|
||||
String postFix = "";
|
||||
|
||||
while( numberSize > width )
|
||||
{
|
||||
return "-";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
last = base;
|
||||
base /= DIVISION_BASE;
|
||||
|
||||
exponent++;
|
||||
|
||||
// adds +1 due to the postfix
|
||||
numberSize = Long.toString( base ).length() + 1;
|
||||
postFix = String.valueOf( ENCODED_POSTFIXES[exponent] );
|
||||
}
|
||||
|
||||
final String withPrecision = this.format.format( last / DIVISION_BASE ) + postFix;
|
||||
final String withoutPrecision = Long.toString( base ) + postFix;
|
||||
|
||||
final String slimResult = ( withPrecision.length() <= width ) ? withPrecision : withoutPrecision;
|
||||
|
||||
// post condition
|
||||
assert slimResult.length() <= width;
|
||||
|
||||
return slimResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a number into a human readable form. It will not round the number, but floor it.
|
||||
* Will try to cut the number down 1 decimal earlier. This will limit the String size to 3 chars.
|
||||
*
|
||||
* Example: 900L -> 0.9K
|
||||
*
|
||||
* @param number to be converted number
|
||||
*
|
||||
* @return String in SI format cut down as far as possible
|
||||
*/
|
||||
public String toShortHumanReadableForm( long number )
|
||||
@Override
|
||||
public String toWideReadableForm( final long number )
|
||||
{
|
||||
final String sign = this.getSign( number );
|
||||
final long absNumber = Math.abs( number );
|
||||
|
||||
if( absNumber < DIVISION_BASE )
|
||||
return Long.toString( number );
|
||||
|
||||
final int exp = (int) ( Math.log( absNumber ) / LOG_DIVISION_BASE );
|
||||
final int result = (int) ( absNumber / Math.pow( DIVISION_BASE, exp ) );
|
||||
if( result >= SHORT_THRESHOLD )
|
||||
{
|
||||
final int shortResult = result / SHORT_THRESHOLD;
|
||||
final char postFix = ENCODED_POSTFIXES[exp];
|
||||
|
||||
return String.format( "%s.%d%s", sign, shortResult, postFix );
|
||||
}
|
||||
else
|
||||
{
|
||||
final char postFix = ENCODED_POSTFIXES[exp - 1];
|
||||
|
||||
return String.format( "%s%d%s", sign, result, postFix );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a number into a human readable form. It will not round the number, but floor it.
|
||||
* Will try to cut the number down 1 decimal later.
|
||||
*
|
||||
* Example:
|
||||
* 10000L -> 10K
|
||||
* 9999L -> 9999
|
||||
*
|
||||
* @param number to be converted number
|
||||
*
|
||||
* @return String in SI format cut down as far as possible
|
||||
*/
|
||||
public String toLongHumanReadableForm( long number )
|
||||
{
|
||||
final String sign = this.getSign( number );
|
||||
final long absNumber = Math.abs( number );
|
||||
|
||||
if( absNumber < 10 * DIVISION_BASE )
|
||||
return Long.toString( number );
|
||||
|
||||
final int exp = (int) ( Math.log( absNumber / 10 ) / LOG_DIVISION_BASE );
|
||||
final int result = (int) ( absNumber / Math.pow( DIVISION_BASE, exp ) );
|
||||
final char postFix = ENCODED_POSTFIXES[exp - 1];
|
||||
|
||||
return String.format( "%s%d%s", sign, result, postFix );
|
||||
return this.toReadableFormRestrictedByWidth( number, 4 );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user