Improve compartment inventory and GUI performance (#109)

This commit is contained in:
Algent authored and GitHub committed 2026-08-03 14:56:47 +07:00
1 parent b5ad490947
commit 171c5b29f6
8 files changed
+123 -89

No files matched your search

@@ -1,10 +1,7 @@
package binnie.core.craftgui;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.List;
import java.util.ListIterator;
import org.lwjgl.input.Mouse;
@@ -168,17 +165,14 @@ public abstract class TopLevelWidget extends Widget implements ITopLevelWidget {
}
public Deque<IWidget> calculateMousedOverWidgets() {
Deque<IWidget> list = new ArrayDeque<>();
for (IWidget widget : getQueuedWidgets(this)) {
if (widget.calculateIsMouseOver()) {
list.addLast(widget);
}
}
return list;
Deque<IWidget> widgets = new ArrayDeque<>();
addMousedOverWidgets(this, widgets);
return widgets;
}
private Collection<IWidget> getQueuedWidgets(IWidget widget) {
List<IWidget> widgets = new ArrayList<>();
private void addMousedOverWidgets(IWidget widget, Deque<IWidget> widgets) {
if (!widget.isVisible()) return;
boolean addChildren = true;
if (widget.isCroppedWidget()) {
addChildren = widget.getCroppedZone().contains(widget.getCropWidget().getRelativeMousePosition());
@@ -188,11 +182,12 @@ public abstract class TopLevelWidget extends Widget implements ITopLevelWidget {
ListIterator<IWidget> li = widget.getWidgets().listIterator(widget.getWidgets().size());
while (li.hasPrevious()) {
IWidget child = li.previous();
widgets.addAll(getQueuedWidgets(child));
addMousedOverWidgets(child, widgets);
}
}
widgets.add(widget);
return widgets;
if (widget.calculateIsMouseOver()) {
widgets.addLast(widget);
}
}
@Override
@@ -306,17 +306,22 @@ public class Widget implements IWidget {
}
onUpdateClient();
List<IWidget> deletedWidgets = new ArrayList<>();
List<IWidget> deletedWidgets = null;
for (IWidget widget : getWidgets()) {
if (widget.hasAttribute(WidgetAttribute.NEEDS_DELETION)) {
if (deletedWidgets == null) {
deletedWidgets = new ArrayList<>();
}
deletedWidgets.add(widget);
} else {
widget.updateClient();
}
}
for (IWidget widget : deletedWidgets) {
deleteChild(widget);
if (deletedWidgets != null) {
for (IWidget widget : deletedWidgets) {
deleteChild(widget);
}
}
}
@@ -201,22 +201,22 @@ public class ContainerCraftGUI extends Container {
Slot shiftClickedSlot = inventorySlots.get(index);
ItemStack itemstack = null;
if (shiftClickedSlot.getHasStack()) {
itemstack = shiftClickedSlot.getStack().copy();
itemstack = shiftClickedSlot.getStack();
}
IInventory playerInventory = player.inventory;
IInventory entityInventory = window.getInventory();
IInventory windowInventory = window.getWindowInventory();
IInventory fromPlayer = (entityInventory == null) ? windowInventory : entityInventory;
int[] target = new int[36];
for (int i = 0; i < target.length; ++i) {
target[i] = i;
}
TransferRequest request;
if (shiftClickedSlot.inventory == playerInventory) {
request = new TransferRequest(itemstack, fromPlayer).setOrigin(shiftClickedSlot.inventory);
} else {
int[] target = new int[36];
for (int i = 0; i < target.length; ++i) {
target[i] = i;
}
request = new TransferRequest(itemstack, playerInventory).setOrigin(shiftClickedSlot.inventory)
.setTargetSlots(target);
}
@@ -246,7 +246,14 @@ public class ContainerCraftGUI extends Container {
}
public void handleNBT(Side side, EntityPlayer player, NBTTagCompound action) {
if (handleNBTAction(side, player, action)) {
sendContainerContents();
}
}
private boolean handleNBTAction(Side side, EntityPlayer player, NBTTagCompound action) {
final String actionType = action.getString(ACTION_TYPE);
boolean slotRegistered = false;
if (side == Side.SERVER) {
switch (actionType) {
@@ -256,11 +263,7 @@ public class ContainerCraftGUI extends Container {
final int slotIndex = action.getShort(SLOT_INDEX);
final int slotNumber = action.getShort(SLOT_NUMBER);
createSlot(InventoryType.values()[slotType % 4], slotIndex, slotNumber);
for (ICrafting crafterObject : crafters) {
crafterObject.sendContainerAndContentsToPlayer(this, getInventory());
}
slotRegistered = createSlot(InventoryType.values()[slotType % 4], slotIndex, slotNumber);
}
}
}
@@ -275,6 +278,7 @@ public class ContainerCraftGUI extends Container {
if (actionType.contains(TANK_UPDATE)) onTankUpdate(action);
}
}
return slotRegistered;
}
@Override
@@ -307,8 +311,7 @@ public class ContainerCraftGUI extends Container {
if (machineSync != null) machineSync.sendGuiNBT(syncedNBT);
Map<String, NBTTagCompound> sentThisTime = new HashMap<>();
NBTTagList actions = new NBTTagList();
NBTTagList actions = null;
for (Map.Entry<String, NBTTagCompound> entry : syncedNBT.entrySet()) {
final String actionType = entry.getKey();
@@ -319,10 +322,16 @@ public class ContainerCraftGUI extends Container {
if (action.equals(actionPrev)) continue;
if (actions == null) {
actions = new NBTTagList();
}
actions.appendTag(action);
sentThisTime.put(actionType, action);
sentNBT.put(actionType, action);
}
syncedNBT.clear();
if (actions == null) return;
NBTTagCompound actionsBatch = new NBTTagCompound();
actionsBatch.setString(ACTION_TYPE, ACTION_BATCH);
actionsBatch.setTag(ACTIONS, actions);
@@ -333,9 +342,6 @@ public class ContainerCraftGUI extends Container {
BinnieCore.proxy.sendToPlayer(packet, playerMP);
}
}
sentNBT.putAll(sentThisTime);
syncedNBT.clear();
}
private NBTTagCompound createErrorNBT(IErrorStateSource error) {
@@ -486,19 +492,34 @@ public class ContainerCraftGUI extends Container {
}
public void receiveNBT(Side side, EntityPlayer player, NBTTagCompound action) {
if (receiveNBTAction(side, player, action)) {
sendContainerContents();
}
}
private boolean receiveNBTAction(Side side, EntityPlayer player, NBTTagCompound action) {
String actionType = action.getString(ACTION_TYPE);
if (actionType.equals(ACTION_BATCH)) {
boolean slotRegistered = false;
NBTTagList actionsBatch = action.getTagList(ACTIONS, TAG_COMPOUND);
for (int i = 0; i < actionsBatch.tagCount(); i++) {
receiveNBT(side, player, actionsBatch.getCompoundTagAt(i));
slotRegistered |= receiveNBTAction(side, player, actionsBatch.getCompoundTagAt(i));
}
return;
return slotRegistered;
}
handleNBT(side, player, action);
boolean slotRegistered = handleNBTAction(side, player, action);
window.receiveGuiNBT(getSide(), player, actionType, action);
INetwork.ReceiveGuiNBT machine = Machine.getInterface(INetwork.ReceiveGuiNBT.class, window.getInventory());
if (machine == null) return;
machine.receiveGuiNBT(getSide(), player, actionType, action);
if (machine != null) {
machine.receiveGuiNBT(getSide(), player, actionType, action);
}
return slotRegistered;
}
private void sendContainerContents() {
for (ICrafting crafter : crafters) {
crafter.sendContainerAndContentsToPlayer(this, getInventory());
}
}
public Slot getOrCreateSlot(InventoryType inventoryType, int slotIndex) {
@@ -522,13 +543,15 @@ public class ContainerCraftGUI extends Container {
};
}
private void createSlot(InventoryType type, int index, int slotNumber) {
if (inventorySlots.get(slotNumber) != null) return;
private boolean createSlot(InventoryType type, int index, int slotNumber) {
if (inventorySlots.get(slotNumber) != null) return false;
IInventory inventory = getInventory(type);
Slot slot = new CustomSlot(inventory, index);
slot.slotNumber = slotNumber;
inventorySlots.add(slotNumber, slot);
inventoryItemStacks.add(slotNumber, null);
ItemStack stack = slot.getStack();
inventoryItemStacks.add(slotNumber, stack == null ? null : stack.copy());
return true;
}
}
@@ -90,6 +90,7 @@ public class GuiCraftGUI extends GuiContainer {
zLevel = 10.0f;
GuiScreen.itemRender.zLevel = zLevel;
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
window.render();
RenderHelper.enableGUIStandardItemLighting();
@@ -102,7 +103,7 @@ public class GuiCraftGUI extends GuiContainer {
InventoryPlayer playerInventory = mc.thePlayer.inventory;
draggedItem = playerInventory.getItemStack();
if (draggedItem != null) {
renderItem(new IPoint(mouseX - 8, mouseY - 8), draggedItem, false);
GL11.glTranslatef(0.0f, 0.0f, 200.0f);
renderItem(new IPoint(mouseX - 8, mouseY - 8), draggedItem, false);
}
GL11.glDisable(32826); // GL_RESCALE_NORMAL_EXT
@@ -116,7 +117,6 @@ public class GuiCraftGUI extends GuiContainer {
} else {
tooltip.setType(Tooltip.Type.STANDARD);
window.getTooltip(tooltip);
NEIHook.renderToolTips(mouseX, mouseY);
}
if (tooltip.exists()) {
@@ -448,7 +448,6 @@ public class GuiCraftGUI extends GuiContainer {
}
GuiScreen.itemRender.renderItemOverlayIntoGUI(font, mc.renderEngine, item, (int) pos.x(), (int) pos.y(), null);
GL11.glClear(256);
RenderHelper.disableStandardItemLighting();
GL11.glPopAttrib();
}
@@ -10,6 +10,7 @@ import java.util.Map;
class ListMap<T> implements List<T> {
private final LinkedHashMap<Integer, T> map;
private int size;
ListMap() {
map = new LinkedHashMap<>();
@@ -17,13 +18,7 @@ class ListMap<T> implements List<T> {
@Override
public int size() {
int i = -1;
for (int k : map.keySet()) {
if (k > i) {
i = k;
}
}
return i + 1;
return size;
}
@Override
@@ -93,6 +88,7 @@ class ListMap<T> implements List<T> {
@Override
public void clear() {
map.clear();
size = 0;
}
@Override
@@ -103,12 +99,14 @@ class ListMap<T> implements List<T> {
@Override
public T set(int index, T element) {
map.put(index, element);
size = Math.max(size, index + 1);
return element;
}
@Override
public void add(int index, T element) {
map.put(index, element);
size = Math.max(size, index + 1);
}
@Override
@@ -17,6 +17,7 @@ class ComponentCompartmentInventory extends ComponentInventorySlots implements I
private final int numberOfTabs;
private final int slotsPerPage;
private final Map<Integer, CompartmentTab> tabs;
private NBTTagCompound cachedGuiNBT;
public ComponentCompartmentInventory(IMachine machine, int sections) {
this(machine, sections, 4);
@@ -51,21 +52,24 @@ class ComponentCompartmentInventory extends ComponentInventorySlots implements I
public CompartmentTab getTab(int i) {
if (!tabs.containsKey(i)) {
tabs.put(i, new CompartmentTab(i));
cachedGuiNBT = null;
}
return tabs.get(i);
}
@Override
public void sendGuiNBT(Map<String, NBTTagCompound> nbts) {
NBTTagList list = new NBTTagList();
for (int i = 0; i < numberOfTabs; ++i) {
NBTTagCompound nbt2 = new NBTTagCompound();
getTab(i).writeToNBT(nbt2);
list.appendTag(nbt2);
if (cachedGuiNBT == null) {
NBTTagList list = new NBTTagList();
for (int i = 0; i < numberOfTabs; ++i) {
NBTTagCompound tabNBT = new NBTTagCompound();
getTab(i).writeToNBT(tabNBT);
list.appendTag(tabNBT);
}
cachedGuiNBT = new NBTTagCompound();
cachedGuiNBT.setTag("tabs", list);
}
NBTTagCompound tag = new NBTTagCompound();
tag.setTag("tabs", list);
nbts.put("comp-tabs", tag);
nbts.put("comp-tabs", cachedGuiNBT);
}
@Override
@@ -78,11 +82,13 @@ class ComponentCompartmentInventory extends ComponentInventorySlots implements I
tab.readFromNBT(tag);
tabs.put(tab.getId(), tab);
}
cachedGuiNBT = null;
}
if (name.equals("comp-change-tab")) {
CompartmentTab tab2 = new CompartmentTab(0);
tab2.readFromNBT(nbt);
tabs.put(tab2.getId(), tab2);
cachedGuiNBT = null;
getMachine().getTileEntity().markDirty();
}
}
@@ -97,6 +103,7 @@ class ComponentCompartmentInventory extends ComponentInventorySlots implements I
tab.readFromNBT(tag);
tabs.put(tab.getId(), tab);
}
cachedGuiNBT = null;
}
@Override
@@ -173,6 +173,7 @@ public class WindowCompartment extends WindowMachine implements IWindowAffectsSh
}
CraftGUIUtil.linkWidgets(tab, compartmentPages);
int i = 0;
final NBTTagList actions = new NBTTagList();
for (int p2 = 0; p2 < inv.getTabNumber(); ++p2) {
ControlPage thisPage = page[p2];
Panel panel = new Panel(thisPage, 0.0f, 0.0f, thisPage.w(), thisPage.h(), MinecraftGUI.PanelType.Black) {
@@ -191,11 +192,10 @@ public class WindowCompartment extends WindowMachine implements IWindowAffectsSh
slotsIDs[k] = i++;
}
final NBTTagList actions = new NBTTagList();
new ControlSlotArray(thisPage, 8, 8, inv.getPageSize() / 5, 5)
.create(actions, InventoryType.Machine, slotsIDs);
MessageCraftGUI.sendToServer(actions);
}
MessageCraftGUI.sendToServer(actions);
x += compartmentPageWidth;
if (tabs2.length > 0) {
ControlTabBar<Integer> tab2 = new ControlTabBar<Integer>(
@@ -27,24 +27,19 @@ public class TransferRequest {
private boolean transferLiquids;
private boolean ignoreReadOnly;
private EntityPlayer overflowPlayer;
private final List<TransferSlot> insertedSlots;
private final List<Integer> insertedTanks;
private List<TransferSlot> insertedSlots;
private List<Integer> insertedTanks;
public TransferRequest(ItemStack toTransfer, IInventory destination) {
itemToTransfer = null;
returnItem = null;
targetSlots = new int[0];
targetSlots = null;
targetTanks = new int[0];
transferLiquids = true;
ignoreReadOnly = false;
overflowPlayer = null;
insertedSlots = new ArrayList<>();
insertedTanks = new ArrayList<>();
int[] target = new int[destination.getSizeInventory()];
for (int i = 0; i < target.length; ++i) {
target[i] = i;
}
insertedSlots = null;
insertedTanks = null;
int[] targetTanks = new int[0];
if (destination instanceof ITankMachine) {
@@ -61,7 +56,6 @@ public class TransferRequest {
setOrigin(null);
setDestination(destination);
setTargetSlots(target);
setTargetTanks(targetTanks);
transferLiquids = true;
}
@@ -108,7 +102,7 @@ public class TransferRequest {
}
public ItemStack transfer(boolean doAdd) {
ItemStack item = returnItem;
ItemStack item = doAdd || returnItem == null ? returnItem : returnItem.copy();
if (item == null || destination == null) {
return null;
}
@@ -130,38 +124,39 @@ public class TransferRequest {
// TODO simplify
if (item != null) {
for (int slot : targetSlots) {
int[] slots = getTargetSlots();
for (int slot : slots) {
if (destination.isItemValidForSlot(slot, item) || ignoreReadOnly) {
if (!(destination instanceof IInventorySlots)
|| ((IInventorySlots) destination).getSlot(slot) == null
|| !((IInventorySlots) destination).getSlot(slot).isRecipe()) {
if (destination.getStackInSlot(slot) != null) {
if (item.isStackable() && destination.getInventoryStackLimit() > 1) {
ItemStack merged = destination.getStackInSlot(slot).copy();
ItemStack[] newStacks = mergeStacks(item.copy(), merged.copy());
item = newStacks[0];
if (!areItemsEqual(merged, newStacks[1])) {
insertedSlots.add(new TransferSlot(slot, destination));
}
ItemStack merged = destination.getStackInSlot(slot);
if (merged != null && item.isStackable()
&& destination.getInventoryStackLimit() > 1
&& areItemsEqual(item, merged)) {
int amount = Math.min(item.stackSize, merged.getMaxStackSize() - merged.stackSize);
if (amount > 0) {
getInsertedSlots().add(new TransferSlot(slot, destination));
if (doAdd) {
destination.setInventorySlotContents(slot, newStacks[1]);
}
if (item == null) {
return null;
ItemStack newStack = merged.copy();
newStack.stackSize += amount;
destination.setInventorySlotContents(slot, newStack);
}
item.stackSize -= amount;
if (item.stackSize <= 0) return null;
}
}
}
}
}
for (int slot : targetSlots) {
for (int slot : slots) {
if (destination.isItemValidForSlot(slot, item) || ignoreReadOnly) {
if (!(destination instanceof IInventorySlots)
|| ((IInventorySlots) destination).getSlot(slot) == null
|| !((IInventorySlots) destination).getSlot(slot).isRecipe()) {
if (destination.getStackInSlot(slot) == null) {
insertedSlots.add(new TransferSlot(slot, destination));
getInsertedSlots().add(new TransferSlot(slot, destination));
if (doAdd) {
ItemStack movedStack = item.copy();
if (movedStack.stackSize > destination.getInventoryStackLimit()) {
@@ -471,10 +466,16 @@ public class TransferRequest {
}
public List<TransferSlot> getInsertedSlots() {
if (insertedSlots == null) {
insertedSlots = new ArrayList<>();
}
return insertedSlots;
}
public List<Integer> getInsertedTanks() {
if (insertedTanks == null) {
insertedTanks = new ArrayList<>();
}
return insertedTanks;
}
@@ -491,6 +492,12 @@ public class TransferRequest {
}
public int[] getTargetSlots() {
if (targetSlots == null) {
targetSlots = new int[destination.getSizeInventory()];
for (int i = 0; i < targetSlots.length; ++i) {
targetSlots[i] = i;
}
}
return targetSlots;
}