Implement Crafting CPU selector widget

This commit is contained in:
alongstringofnumbers
2022-08-17 15:54:03 -07:00
parent 327b26559f
commit b84c25e64c
14 changed files with 788 additions and 48 deletions
@@ -19,12 +19,16 @@
package appeng.container.implementations;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.io.IOException;
import java.util.*;
import appeng.api.networking.IGrid;
import appeng.core.AELog;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketCraftingCPUsUpdate;
import com.google.common.collect.ImmutableSet;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import appeng.api.networking.crafting.ICraftingCPU;
@@ -37,13 +41,13 @@ import appeng.util.Platform;
public class ContainerCraftingStatus extends ContainerCraftingCPU
{
private final List<CraftingCPURecord> cpus = new ArrayList<>();
@GuiSync( 5 )
public int selectedCpu = -1;
@GuiSync( 6 )
public boolean noCPU = true;
@GuiSync( 7 )
public String myName = "";
private ImmutableSet<ICraftingCPU> lastCpuSet = null;
private List<CraftingCPUStatus> cpus = new ArrayList<CraftingCPUStatus>();
private final WeakHashMap<ICraftingCPU, Integer> cpuSerialMap = new WeakHashMap<>();
private int nextCpuSerial = 1;
private int lastUpdate = 0;
@GuiSync(5)
public int selectedCpuSerial = -1;
public ContainerCraftingStatus( final InventoryPlayer ip, final ITerminalHost te )
{
@@ -53,12 +57,13 @@ public class ContainerCraftingStatus extends ContainerCraftingCPU
@Override
public void detectAndSendChanges()
{
if( Platform.isServer() && this.getNetwork() != null )
IGrid network = this.getNetwork();
if( Platform.isServer() && network != null )
{
final ICraftingGrid cc = this.getNetwork().getCache( ICraftingGrid.class );
final ICraftingGrid cc = network.getCache( ICraftingGrid.class );
final ImmutableSet<ICraftingCPU> cpuSet = cc.getCpus();
int matches = 0;
/*int matches = 0;
boolean changed = false;
for( final ICraftingCPU c : cpuSet )
{
@@ -98,12 +103,65 @@ public class ContainerCraftingStatus extends ContainerCraftingCPU
this.sendCPUs();
}
this.noCPU = this.cpus.isEmpty();
this.noCPU = this.cpus.isEmpty(); */
// Update at least once a second
++lastUpdate;
if (!cpuSet.equals( lastCpuSet ) || lastUpdate > 20) {
lastUpdate = 0;
lastCpuSet = cpuSet;
updateCpuList();
sendCPUs();
}
}
// Clear selection if CPU is no longer in list
if (selectedCpuSerial != -1) {
if (cpus.stream().noneMatch(c -> c.getSerial() == selectedCpuSerial)) {
selectCPU(-1);
}
}
// Select a suitable CPU if none is selected
if (selectedCpuSerial == -1) {
// Try busy CPUs first
for (CraftingCPUStatus cpu : cpus) {
if (cpu.getRemainingItems() > 0) {
selectCPU(cpu.getSerial());
break;
}
}
// If we couldn't find a busy one, just select the first
if (selectedCpuSerial == -1 && !cpus.isEmpty()) {
selectCPU(cpus.get(0).getSerial());
}
}
super.detectAndSendChanges();
}
private static final Comparator<CraftingCPUStatus> CPU_COMPARATOR = Comparator
.comparing((CraftingCPUStatus e) -> e.getName() == null || e.getName().isEmpty())
.thenComparing(e -> e.getName() != null ? e.getName() : "")
.thenComparingInt(CraftingCPUStatus::getSerial);
private void updateCpuList()
{
this.cpus.clear();
for (ICraftingCPU cpu : lastCpuSet)
{
int serial = getOrAssignCpuSerial(cpu);
this.cpus.add( new CraftingCPUStatus( cpu, serial ) );
}
this.cpus.sort(CPU_COMPARATOR);
}
private int getOrAssignCpuSerial( ICraftingCPU cpu )
{
return cpuSerialMap.computeIfAbsent( cpu, unused -> nextCpuSerial++ );
}
private boolean cpuMatches( final ICraftingCPU c )
{
return c.isBusy();
@@ -111,7 +169,22 @@ public class ContainerCraftingStatus extends ContainerCraftingCPU
private void sendCPUs()
{
Collections.sort( this.cpus );
final PacketCraftingCPUsUpdate update;
for( final Object player : this.listeners )
{
if( player instanceof EntityPlayerMP)
{
try
{
NetworkHandler.instance.sendTo( new PacketCraftingCPUsUpdate( this.cpus ), (EntityPlayerMP) player );
}
catch( IOException e )
{
AELog.debug( e );
}
}
}
/*Collections.sort( this.cpus );
if( this.selectedCpu >= this.cpus.size() )
{
@@ -138,10 +211,47 @@ public class ContainerCraftingStatus extends ContainerCraftingCPU
else
{
this.setCPU( null );
}*/
}
public void selectCPU( int serial )
{
if (Platform.isServer())
{
if( serial < -1 )
{
serial = -1;
}
final int searchedSerial = serial;
if( serial > -1 && cpus.stream().noneMatch(c -> c.getSerial() == searchedSerial) )
{
serial = -1;
}
ICraftingCPU newSelectedCpu = null;
if( serial != -1 )
{
for( ICraftingCPU cpu : lastCpuSet )
{
if( cpuSerialMap.getOrDefault( cpu, -1 ) == serial )
{
newSelectedCpu = cpu;
break;
}
}
}
if( newSelectedCpu != getMonitor() )
{
this.selectedCpuSerial = serial;
setCPU( newSelectedCpu );
}
}
}
public void cycleCpu( final boolean next )
/*public void cycleCpu( final boolean next )
{
if( next )
{
@@ -176,5 +286,15 @@ public class ContainerCraftingStatus extends ContainerCraftingCPU
this.myName = this.cpus.get( this.selectedCpu ).getName();
this.setCPU( this.cpus.get( this.selectedCpu ).getCpu() );
}
} */
public List<CraftingCPUStatus> getCPUs()
{
return Collections.unmodifiableList( cpus );
}
public void postCPUUpdate( CraftingCPUStatus[] cpus )
{
this.cpus = Arrays.asList( cpus );
}
}
@@ -0,0 +1,196 @@
package appeng.container.implementations;
import appeng.api.networking.crafting.ICraftingCPU;
import appeng.api.storage.data.IAEItemStack;
import appeng.util.ItemSorters;
import appeng.util.item.AEItemStack;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import javax.annotation.Nullable;
import java.io.*;
public class CraftingCPUStatus implements Comparable<CraftingCPUStatus> {
@Nullable
private final ICraftingCPU serverCluster;
private final String name;
private final int serial;
private final long storage;
private final long coprocessors;
private final long totalItems;
private final long remainingItems;
private final IAEItemStack crafting;
public CraftingCPUStatus( )
{
this.serverCluster = null;
this.name = "ERROR";
this.serial = 0;
this.storage = 0;
this.coprocessors = 0;
this.totalItems = 0;
this.remainingItems = 0;
this.crafting = null;
}
public CraftingCPUStatus( ICraftingCPU cluster, int serial )
{
this.serverCluster = cluster;
this.name = cluster.getName();
this.serial = serial;
if (cluster.isBusy())
{
crafting = cluster.getFinalOutput();
totalItems = cluster.getStartItemCount();
remainingItems = cluster.getRemainingItemCount();
}
else
{
crafting = null;
totalItems = 0;
remainingItems = 0;
}
this.storage = cluster.getAvailableStorage();
this.coprocessors = cluster.getCoProcessors();
}
public CraftingCPUStatus( NBTTagCompound i )
{
this.serverCluster = null;
this.name = i.getString( "name" );
this.serial = i.getInteger( "serial" );
this.storage = i.getLong("storage");
this.coprocessors = i.getLong("coprocessors");
this.totalItems = i.getLong("totalItems");
this.remainingItems = i.getLong("remainingItems");
this.crafting = i.hasKey( "crafting" ) ? AEItemStack.fromNBT( i.getCompoundTag( "crafting" ) ) : null;
}
public CraftingCPUStatus(ByteBuf packet) throws IOException
{
this(readNBTFromPacket( packet ));
}
private static NBTTagCompound readNBTFromPacket(ByteBuf packet) throws IOException
{
final int size = packet.readInt();
final byte[] tagBytes = new byte[size];
packet.readBytes( tagBytes );
final ByteArrayInputStream di = new ByteArrayInputStream( tagBytes );
return CompressedStreamTools.read( new DataInputStream( di ));
}
public void writeToNBT( NBTTagCompound i )
{
if (name != null && !name.isEmpty())
{
i.setString( "name", name );
}
i.setInteger( "serial", serial );
i.setLong( "storage", storage );
i.setLong( "coprocessors", coprocessors );
i.setLong( "totalItems", totalItems );
i.setLong( "remainingItems", remainingItems );
if (crafting != null)
{
NBTTagCompound stack = new NBTTagCompound();
crafting.writeToNBT( stack );
i.setTag( "crafting", stack );
}
}
public void writeToPacket( ByteBuf i ) throws IOException
{
final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
final DataOutputStream data = new DataOutputStream( bytes );
NBTTagCompound tag = new NBTTagCompound();
this.writeToNBT( tag );
CompressedStreamTools.write( tag, data );
final byte[] tagBytes = bytes.toByteArray();
final int size = tagBytes.length;
i.writeInt( size );
i.writeBytes( tagBytes );
}
@Nullable
public ICraftingCPU getServerCluster()
{
return serverCluster;
}
public String getName()
{
return name;
}
public int getSerial()
{
return serial;
}
public long getStorage()
{
return storage;
}
public long getCoprocessors()
{
return coprocessors;
}
public long getTotalItems()
{
return totalItems;
}
public long getRemainingItems()
{
return remainingItems;
}
public IAEItemStack getCrafting()
{
return crafting;
}
@Override
public int compareTo( CraftingCPUStatus o )
{
final int a = ItemSorters.compareLong( o.getCoprocessors(), this.getCoprocessors() );
if( a != 0 )
{
return a;
}
return ItemSorters.compareLong( o.getStorage(), this.getStorage() );
}
public String formatStorage()
{
long val = getStorage();
if (val > 4_000_000_000_000L)
{
return String.format("%dT", val / 1024 / 1024 / 1024 / 1024);
}
else if (val > 4_000_000_000L)
{
return String.format("%dG", val / 1024 / 1024 / 1024);
}
else if (val > 4_000_000L)
{
return String.format("%dM", val / 1024 / 1024);
}
else if (val > 4_000L)
{
return String.format("%dk", val / 1024);
}
else
{
return Long.toString( val );
}
}
}