Add throughput monitor (#674)

Co-authored-by: Martin Robertz <dream-master@gmx.net>
This commit is contained in:
MCTBLandMartin Robertz authored and GitHub committed 2025-02-13 15:43:51 +01:00
1 parent 47dc63c130
commit e0b669a60d
22 files changed
+307 -21

No files matched your search

@@ -102,6 +102,8 @@ public interface IParts {
IItemDefinition storageMonitor();
IItemDefinition throughputMonitor();
IItemDefinition conversionMonitor();
IItemDefinition patternTerminalEx();
@@ -98,5 +98,7 @@ public class Parts {
public AEItemDefinition partStorageMonitor;
public AEItemDefinition partThroughputMonitor;
public AEItemDefinition partConversionMonitor;
}
@@ -57,6 +57,11 @@ public enum CableBusTextures {
PartConversionMonitor_Dark("PartConversionMonitor_Dark"),
PartConversionMonitor_Dark_Locked("PartConversionMonitor_Dark_Locked"),
PartThroughputMonitor_Bright("PartThroughputMonitor_Bright"),
PartThroughputMonitor_Colored("PartThroughputMonitor_Colored"),
PartThroughputMonitor_Dark("PartThroughputMonitor_Dark"),
PartThroughputMonitor_Dark_Locked("PartThroughputMonitor_Dark_Locked"),
PartInterfaceTerm_Bright("PartInterfaceTerm_Bright"),
PartInterfaceTerm_Colored("PartInterfaceTerm_Colored"),
PartInterfaceTerm_Dark("PartInterfaceTerm_Dark"),
@@ -54,6 +54,7 @@ import appeng.client.me.InternalSlotME;
import appeng.client.me.SlotME;
import appeng.container.guisync.GuiSync;
import appeng.container.guisync.SyncData;
import appeng.container.implementations.ContainerCellWorkbench;
import appeng.container.implementations.ContainerUpgradeable;
import appeng.container.slot.AppEngSlot;
import appeng.container.slot.SlotCraftingMatrix;
@@ -72,7 +73,7 @@ import appeng.core.sync.packets.PacketValueConfig;
import appeng.helpers.ICustomNameObject;
import appeng.helpers.InventoryAction;
import appeng.items.materials.ItemMultiMaterial;
import appeng.parts.automation.StackUpgradeInventory;
import appeng.parts.automation.UpgradeInventory;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.inv.AdaptorPlayerHand;
@@ -525,11 +526,15 @@ public abstract class AEBaseContainer extends Container {
}
// For shift click upgrade card logic
if (ItemMultiMaterial.instance.getType(tis) != null && this instanceof ContainerUpgradeable) {
// Check source or target
if (!((d.inventory instanceof StackUpgradeInventory)
|| (clickSlot.inventory instanceof StackUpgradeInventory))) {
continue;
if (ItemMultiMaterial.instance.getType(tis) != null) {
// Check now container is upgradeable or it's subclass
if (ContainerUpgradeable.class.isAssignableFrom(this.getClass())) {
// Check source or target
if (!((d.inventory instanceof UpgradeInventory)
|| (clickSlot.inventory instanceof UpgradeInventory)
|| (d.inventory instanceof ContainerCellWorkbench.Upgrades))) {
continue;
}
}
}
@@ -248,7 +248,7 @@ public class ContainerCellWorkbench extends ContainerUpgradeable {
this.copyMode = copyMode;
}
private class Upgrades implements IInventory {
public class Upgrades implements IInventory {
@Override
public int getSizeInventory() {
@@ -14,8 +14,10 @@ import net.minecraft.nbt.NBTTagCompound;
import appeng.api.networking.crafting.ICraftingCPU;
import appeng.api.storage.data.IAEItemStack;
import appeng.util.IWideReadableNumberConverter;
import appeng.util.ItemSorters;
import appeng.util.Platform;
import appeng.util.ReadableNumberConverter;
import appeng.util.item.AEItemStack;
import io.netty.buffer.ByteBuf;
@@ -24,6 +26,8 @@ import io.netty.buffer.ByteBuf;
*/
public class CraftingCPUStatus implements Comparable<CraftingCPUStatus> {
private static final IWideReadableNumberConverter NUMBER_CONVERTER = ReadableNumberConverter.INSTANCE;
@Nullable
private final ICraftingCPU serverCluster;
@@ -183,7 +187,8 @@ public class CraftingCPUStatus implements Comparable<CraftingCPUStatus> {
}
public String formatShorterCoprocessors() {
return Platform.formatNumberLong(getCoprocessors());
return NUMBER_CONVERTER.toWideReadableForm(getCoprocessors());
// return Platform.formatNumberLong(getCoprocessors());
}
public String formatStorage() {
@@ -361,6 +361,7 @@ public final class Registration {
target.partCraftingTerminal = this.converter.of(source.craftingTerminal());
target.partTerminal = this.converter.of(source.terminal());
target.partStorageMonitor = this.converter.of(source.storageMonitor());
target.partThroughputMonitor = this.converter.of(source.throughputMonitor());
target.partConversionMonitor = this.converter.of(source.conversionMonitor());
}
@@ -68,6 +68,7 @@ public final class ApiParts implements IParts {
private final IItemDefinition terminal;
private final IItemDefinition storageMonitor;
private final IItemDefinition conversionMonitor;
private final IItemDefinition throughputMonitor;
public ApiParts(final DefinitionConstructor constructor, final IPartHelper partHelper) {
final ItemMultiPart itemMultiPart = new ItemMultiPart(partHelper);
@@ -119,6 +120,7 @@ public final class ApiParts implements IParts {
this.terminal = new DamagedItemDefinition(itemMultiPart.createPart(PartType.Terminal));
this.storageMonitor = new DamagedItemDefinition(itemMultiPart.createPart(PartType.StorageMonitor));
this.conversionMonitor = new DamagedItemDefinition(itemMultiPart.createPart(PartType.ConversionMonitor));
this.throughputMonitor = new DamagedItemDefinition(itemMultiPart.createPart(PartType.ThroughputMonitor));
}
@Override
@@ -344,4 +346,9 @@ public final class ApiParts implements IParts {
public IItemDefinition conversionMonitor() {
return this.conversionMonitor;
}
@Override
public IItemDefinition throughputMonitor() {
return this.throughputMonitor;
}
}
@@ -71,6 +71,7 @@ public enum AEFeature {
ExportBus(Constants.CATEGORY_NETWORK_BUSES),
StorageBus(Constants.CATEGORY_NETWORK_BUSES),
PartConversionMonitor(Constants.CATEGORY_NETWORK_BUSES),
PartThroughputMonitor(Constants.CATEGORY_NETWORK_BUSES),
PortableCell(Constants.CATEGORY_PORTABLE_CELL),
@@ -40,7 +40,9 @@ public enum TickRates {
OpenComputersTunnel(1, 5),
PressureTunnel(1, 120);
PressureTunnel(1, 120),
ThroughputMonitor(20, 100);
private int min;
private int max;
@@ -59,6 +59,7 @@ import appeng.parts.reporting.PartPatternTerminalEx;
import appeng.parts.reporting.PartSemiDarkPanel;
import appeng.parts.reporting.PartStorageMonitor;
import appeng.parts.reporting.PartTerminal;
import appeng.parts.reporting.PartThroughputMonitor;
public enum PartType {
@@ -149,6 +150,9 @@ public enum PartType {
StorageMonitor(400, EnumSet.of(AEFeature.StorageMonitor), EnumSet.noneOf(IntegrationType.class),
PartStorageMonitor.class),
ThroughputMonitor(410, EnumSet.of(AEFeature.PartThroughputMonitor), EnumSet.noneOf(IntegrationType.class),
PartThroughputMonitor.class),
ConversionMonitor(420, EnumSet.of(AEFeature.PartConversionMonitor), EnumSet.noneOf(IntegrationType.class),
PartConversionMonitor.class),
@@ -316,6 +316,12 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
}
this.tesrRenderItemNumber(ais);
// GL11.glPopAttrib();
}
public void tesrRenderItemNumber(final IAEItemStack ais) {
GL11.glTranslatef(0.0f, 0.14f, -0.24f);
GL11.glScalef(1.0f / 62.0f, 1.0f / 62.0f, 1.0f / 62.0f);
@@ -326,8 +332,6 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay
final int width = fr.getStringWidth(renderedStackSize);
GL11.glTranslatef(-0.5f * width, 0.0f, -1.0f);
fr.drawString(renderedStackSize, 0, 0, 0);
// GL11.glPopAttrib();
}
@Override
@@ -0,0 +1,206 @@
package appeng.parts.reporting;
import java.io.IOException;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.Vec3;
import org.lwjgl.opengl.GL11;
import appeng.api.networking.IGridNode;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.texture.CableBusTextures;
import appeng.core.settings.TickRates;
import appeng.helpers.Reflected;
import appeng.util.IWideReadableNumberConverter;
import appeng.util.Platform;
import appeng.util.ReadableNumberConverter;
import io.netty.buffer.ByteBuf;
/**
* @author MCTBL
* @version rv3-beta-538-GTNH
* @since rv3-beta-538-GTNH
*/
public class PartThroughputMonitor extends AbstractPartMonitor implements IGridTickable {
private enum TimeUnit {
Tick("/t", 1),
Second("/s", 20),
Minute("/m", 1_200),
Hour("/h", 72_000);
String label;
int totalTicks;
TimeUnit(String label, int totalTicks) {
this.totalTicks = totalTicks;
this.label = label;
}
public TimeUnit getNext() {
if (this.ordinal() == TimeUnit.values().length - 1) {
return Tick;
}
return TimeUnit.values()[this.ordinal() + 1];
}
public static TimeUnit fromOrdinal(int ordinal) {
if (ordinal < 0 || ordinal >= TimeUnit.values().length) {
return Tick;
} else {
return TimeUnit.values()[ordinal];
}
}
}
private static final IWideReadableNumberConverter NUMBER_CONVERTER = ReadableNumberConverter.INSTANCE;
private static final CableBusTextures FRONT_BRIGHT_ICON = CableBusTextures.PartThroughputMonitor_Bright;
private static final CableBusTextures FRONT_DARK_ICON = CableBusTextures.PartThroughputMonitor_Dark;
private static final CableBusTextures FRONT_COLORED_ICON = CableBusTextures.PartThroughputMonitor_Colored;
private static final CableBusTextures FRONT_COLORED_ICON_LOCKED = CableBusTextures.PartThroughputMonitor_Dark_Locked;
private TimeUnit timeMode;
private double itemNumsChange;
private long lastStackSize;
@Reflected
public PartThroughputMonitor(final ItemStack is) {
super(is);
this.itemNumsChange = 0;
this.lastStackSize = -1;
this.timeMode = TimeUnit.Tick;
}
@Override
public CableBusTextures getFrontBright() {
return FRONT_BRIGHT_ICON;
}
@Override
public CableBusTextures getFrontColored() {
return this.isLocked() ? FRONT_COLORED_ICON_LOCKED : FRONT_COLORED_ICON;
}
@Override
public CableBusTextures getFrontDark() {
return FRONT_DARK_ICON;
}
@Override
public void readFromNBT(final NBTTagCompound data) {
super.readFromNBT(data);
this.timeMode = TimeUnit.fromOrdinal(data.getInteger("timeMode"));
}
@Override
public void writeToNBT(final NBTTagCompound data) {
super.writeToNBT(data);
data.setInteger("timeMode", this.timeMode.ordinal());
}
@Override
public void writeToStream(final ByteBuf data) throws IOException {
super.writeToStream(data);
data.writeInt(this.timeMode.ordinal());
data.writeDouble(this.itemNumsChange);
}
@Override
public boolean readFromStream(final ByteBuf data) throws IOException {
boolean needRedraw = super.readFromStream(data);
this.timeMode = TimeUnit.fromOrdinal(data.readInt());
this.itemNumsChange = data.readDouble();
return needRedraw;
}
@Override
public boolean onPartShiftActivate(final EntityPlayer player, final Vec3 pos) {
if (Platform.isClient()) {
return true;
}
if (!this.getProxy().isActive()) {
return false;
}
if (!Platform.hasPermissions(this.getLocation(), player)) {
return false;
}
this.timeMode = this.timeMode.getNext();
this.host.markForUpdate();
return true;
}
@Override
public void tesrRenderItemNumber(final IAEItemStack ais) {
GL11.glTranslatef(0.0f, 0.14f, -0.24f);
GL11.glScalef(1.0f / 120.0f, 1.0f / 120.0f, 1.0f / 120.0f);
final long stackSize = ais.getStackSize();
final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm(stackSize);
final String renderedStackSizeChange = (this.itemNumsChange > 0 ? "+" : "")
+ (Platform.formatNumberDoubleRestrictedByWidth(this.itemNumsChange, 3))
+ (this.timeMode.label);
final FontRenderer fr = Minecraft.getMinecraft().fontRenderer;
int width = fr.getStringWidth(renderedStackSize);
GL11.glTranslatef(-0.5f * width, 0.0f, -1.0f);
fr.drawString(renderedStackSize, 0, 0, 0);
GL11.glTranslatef(+0.5f * width, fr.FONT_HEIGHT + 3, -1.0f);
width = fr.getStringWidth(renderedStackSizeChange);
GL11.glTranslatef(-0.5f * width, 0.0f, -1.0f);
int color = 0;
if (this.itemNumsChange < 0) {
color = 0xFF0000;
} else if (this.itemNumsChange > 0) {
color = 0x17B66C;
}
fr.drawString(renderedStackSizeChange, 0, 0, color);
}
@Override
public TickingRequest getTickingRequest(IGridNode node) {
return new TickingRequest(
TickRates.ThroughputMonitor.getMin(),
TickRates.ThroughputMonitor.getMax(),
false,
false);
}
@Override
public TickRateModulation tickingRequest(IGridNode node, int TicksSinceLastCall) {
if (Platform.isClient()) {
return TickRateModulation.SAME;
}
if (this.getDisplayed() == null) {
this.lastStackSize = -1;
this.host.markForUpdate();
return TickRateModulation.IDLE;
} else {
long nowStackSize = this.getDisplayed().getStackSize();
if (this.lastStackSize != -1) {
long changeStackSize = nowStackSize - this.lastStackSize;
this.itemNumsChange = (changeStackSize * this.timeMode.totalTicks) / TicksSinceLastCall;
this.host.markForUpdate();
}
this.lastStackSize = nowStackSize;
}
return TickRateModulation.FASTER;
}
}
+46 -10
View File
@@ -160,9 +160,9 @@ public class Platform {
UUID.fromString("839eb18c-50bc-400c-8291-9383f09763e7"),
"[AE2Player]");
private static final String[] BYTE_UNIT = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", "BB" };
private static final String[] NUM_UNIT = { "K", "M", "B", "T" };
private static final char[] NUM_UNIT = "kMGTPE".toCharArray();
private static final double[] BYTE_LIMIT;
private static final long[] NUM_LIMIT = { 1_000, 1_000_000, 1_000_000_000, 1_000_000_000_000l };
private static final int DIVISION_BASE = 1000;
private static final DecimalFormat df = new DecimalFormat("#.##");
static {
@@ -1887,15 +1887,51 @@ public class Platform {
return (n / BYTE_LIMIT[0]) + " " + BYTE_UNIT[0];
}
public static String formatNumberLong(final long n) {
if (n > 1_000) {
for (int i = 1; i < NUM_LIMIT.length; i++) {
if (n < NUM_LIMIT[i]) {
return String.valueOf(n / NUM_LIMIT[i - 1]) + " " + NUM_UNIT[i - 1];
}
}
/**
* From large double to num with unit
*
* @param n number wait to format
* @return String
*/
public static String formatNumberDouble(final double n) {
return formatNumberDoubleRestrictedByWidth(n, 3);
}
/**
* From large double to num with unit
*
* @param n number wait to format
* @return String
*/
public static String formatNumberDoubleRestrictedByWidth(final double n, final int width) {
final String numberString = df.format(n);
int numberSize = numberString.length();
if (numberSize <= width) {
return numberString;
}
return String.valueOf(n);
double base = n;
double last = base * 1000;
int exponent = -1;
String postFix = "";
while (base >= 1000) {
last = base;
base /= DIVISION_BASE;
// adds +1 due to the postfix
exponent++;
postFix = String.valueOf(NUM_UNIT[exponent]);
}
final String withPrecision = df.format(last / DIVISION_BASE);
final String withoutPrecision = Long.toString((long) base);
final String slimResult = (withPrecision.length() <= width) ? withPrecision : withoutPrecision;
// post condition
assert slimResult.length() <= width;
return slimResult + postFix;
}
}
@@ -734,6 +734,7 @@ item.appliedenergistics2.ItemPart.CableDense.name=ME Dense Smart Cable
item.appliedenergistics2.ItemPart.CableDenseCovered.name=ME Dense Covered Cable
item.appliedenergistics2.ItemPart.StorageMonitor.name=ME Storage Monitor
item.appliedenergistics2.ItemPart.ConversionMonitor.name=ME Conversion Monitor
item.appliedenergistics2.ItemPart.ThroughputMonitor.name=ME Throughput Monitor
item.appliedenergistics2.ItemPart.SemiDarkMonitor.name=Illuminated Panel
item.appliedenergistics2.ItemPart.Monitor.name=Bright Illuminated Panel
item.appliedenergistics2.ItemPart.DarkMonitor.name=Dark Illuminated Panel
@@ -695,6 +695,7 @@ item.appliedenergistics2.ItemPart.CableDense.name=ME致密智能线缆
item.appliedenergistics2.ItemPart.CableDenseCovered.name=ME致密包层线缆
item.appliedenergistics2.ItemPart.StorageMonitor.name=ME存储监控器
item.appliedenergistics2.ItemPart.ConversionMonitor.name=ME交换监控器
item.appliedenergistics2.ItemPart.ThroughputMonitor.name=ME吞吐量监控器
item.appliedenergistics2.ItemPart.SemiDarkMonitor.name=照明面板
item.appliedenergistics2.ItemPart.Monitor.name=亮色照明面板
item.appliedenergistics2.ItemPart.DarkMonitor.name=暗色照明面板
@@ -5,3 +5,7 @@ shapeless=
shapeless=
ae2:ItemMaterial.AnnihilationCore ae2:ItemPart.StorageMonitor ae2:ItemMaterial.FormationCore
-> ae2:ItemPart.ConversionMonitor
shapeless=
ae2:ItemMaterial.EngProcessor ae2:ItemPart.StorageMonitor ae2:ItemMaterial.EngProcessor
-> ae2:ItemPart.ThroughputMonitor
Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB