From f71b42245e4e14d75e59583704dbf99d0ba2864c Mon Sep 17 00:00:00 2001 From: 90 Date: Sat, 16 Nov 2024 20:14:38 +0000 Subject: [PATCH] Fix previously-mentioned dupe/void bug TODO: Consider still how to go about using Supplier-based inventories as with every other ItemMenuHost --- .../cell/PortableCellWorkbenchMenuHost.java | 182 ++++++++++-------- .../megacells/mixin/ItemMenuHostMixin.java | 2 +- 2 files changed, 106 insertions(+), 78 deletions(-) diff --git a/src/main/java/gripe/_90/megacells/item/cell/PortableCellWorkbenchMenuHost.java b/src/main/java/gripe/_90/megacells/item/cell/PortableCellWorkbenchMenuHost.java index 0a43635c..6e348d69 100644 --- a/src/main/java/gripe/_90/megacells/item/cell/PortableCellWorkbenchMenuHost.java +++ b/src/main/java/gripe/_90/megacells/item/cell/PortableCellWorkbenchMenuHost.java @@ -2,10 +2,14 @@ import java.util.Collections; +import net.minecraft.core.HolderLookup; import net.minecraft.core.component.DataComponents; +import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.ItemContainerContents; +import net.minecraft.world.level.ItemLike; import appeng.api.config.CopyMode; import appeng.api.config.Settings; @@ -28,21 +32,13 @@ /** * See {@link appeng.blockentity.misc.CellWorkbenchBlockEntity} - *

- * FIXME: Currently suffers from a dupe/void bug due to the config and upgrades on the cell within not saving properly. - * This was more or less expected attempting to copy-paste the logic for a block entity to what is instead an item. */ public class PortableCellWorkbenchMenuHost extends ItemMenuHost implements InternalInventoryHost, ISegmentedInventory, IConfigurableObject, IConfigInvHost { - // FIXME: Ideally this should use a supplier-based inventory as with other ItemMenuHost impls private final AppEngInternalInventory cellInv = new AppEngInternalInventory(this, 1); private final GenericStackInv config = new GenericStackInv(this::configChanged, GenericStackInv.Mode.CONFIG_TYPES, 63); - private IUpgradeInventory cachedUpgrades; - private ConfigInventory cachedConfig; - private boolean locked; - public PortableCellWorkbenchMenuHost(PortableCellWorkbenchItem item, Player player, ItemMenuHostLocator locator) { super(item, player, locator); cellInv.setEnableClientEvents(true); @@ -66,29 +62,17 @@ public InternalInventory getSubInventory(ResourceLocation id) { @Override public void onChangeInventory(AppEngInternalInventory inv, int slot) { - if (inv == cellInv && !locked) { - locked = true; - - try { - cachedUpgrades = null; - cachedConfig = null; - - var configInventory = getCellConfigInventory(); - - if (configInventory != null) { - if (!configInventory.isEmpty()) { - CellWorkbenchBlockEntity.copy(configInventory, config); - } else { - CellWorkbenchBlockEntity.copy(config, configInventory); - CellWorkbenchBlockEntity.copy(configInventory, config); - } - } else if (getConfigManager().getSetting(Settings.COPY_MODE) == CopyMode.CLEAR_ON_REMOVE) { - config.clear(); - saveChanges(); - } - } finally { - locked = false; + var configInventory = getCellConfigInventory(); + + if (configInventory != null) { + if (!configInventory.isEmpty()) { + CellWorkbenchBlockEntity.copy(configInventory, config); + } else { + CellWorkbenchBlockEntity.copy(config, configInventory); + CellWorkbenchBlockEntity.copy(configInventory, config); } + } else if (getConfigManager().getSetting(Settings.COPY_MODE) == CopyMode.CLEAR_ON_REMOVE) { + config.clear(); } } @@ -103,48 +87,30 @@ private void saveChanges() { } private void configChanged() { - if (locked) { - return; - } - - locked = true; + var c = getCellConfigInventory(); - try { - var c = getCellConfigInventory(); - - if (c != null) { - CellWorkbenchBlockEntity.copy(config, c); - CellWorkbenchBlockEntity.copy(c, config); - } - } finally { - locked = false; + if (c != null) { + CellWorkbenchBlockEntity.copy(config, c); + CellWorkbenchBlockEntity.copy(c, config); } + + saveChanges(); } private ConfigInventory getCellConfigInventory() { - if (cachedConfig == null) { - var cell = getCell(); - - if (cell == null) { - return null; - } - - var is = cellInv.getStackInSlot(0); - - if (is.isEmpty()) { - return null; - } + var cell = getCell(); - var inv = cell.getConfigInventory(is); + if (cell == null) { + return null; + } - if (inv == null) { - return null; - } + var is = cellInv.getStackInSlot(0); - cachedConfig = inv; + if (is.isEmpty()) { + return null; } - return cachedConfig; + return cell.getConfigInventory(is); } @Override @@ -159,29 +125,91 @@ public GenericStackInv getConfig() { return config; } - public IUpgradeInventory getCachedUpgrades() { - if (cachedUpgrades == null) { - var cell = getCell(); + public IUpgradeInventory getCellUpgrades() { + var cell = getCell(); - if (cell == null) { - return UpgradeInventories.empty(); - } + if (cell == null) { + return UpgradeInventories.empty(); + } - var is = cellInv.getStackInSlot(0); + var is = cellInv.getStackInSlot(0); - if (is.isEmpty()) { - return UpgradeInventories.empty(); - } + if (is.isEmpty()) { + return UpgradeInventories.empty(); + } + + var inv = cell.getUpgrades(is); + return inv == null ? UpgradeInventories.empty() : new ProxiedUpgradeInventory(inv, this); + } - var inv = cell.getUpgrades(is); + private static class ProxiedUpgradeInventory extends AppEngInternalInventory implements IUpgradeInventory { + private final IUpgradeInventory delegate; - if (inv == null) { - return UpgradeInventories.empty(); + public ProxiedUpgradeInventory(IUpgradeInventory inventory, InternalInventoryHost host) { + super(host, inventory.size(), 1); + delegate = inventory; + } + + @Override + public ItemLike getUpgradableItem() { + return delegate.getUpgradableItem(); + } + + @Override + public int getInstalledUpgrades(ItemLike u) { + return delegate.getInstalledUpgrades(u); + } + + @Override + public int getMaxInstalled(ItemLike u) { + return delegate.getMaxInstalled(u); + } + + @Override + public void readFromNBT(CompoundTag data, String subtag, HolderLookup.Provider registries) { + delegate.readFromNBT(data, subtag, registries); + } + + @Override + public void writeToNBT(CompoundTag data, String subtag, HolderLookup.Provider registries) { + delegate.writeToNBT(data, subtag, registries); + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public ItemStack getStackInSlot(int slotIndex) { + return delegate.getStackInSlot(slotIndex); + } + + @Override + public void setItemDirect(int slotIndex, ItemStack stack) { + delegate.setItemDirect(slotIndex, stack); + onContentsChanged(slotIndex); + } + + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + var extracted = delegate.extractItem(slot, amount, simulate); + + if (!simulate && !extracted.isEmpty()) { + onContentsChanged(slot); } - cachedUpgrades = inv; + return extracted; } - return cachedUpgrades; + @Override + public boolean isItemValid(int slot, ItemStack stack) { + return delegate.isItemValid(slot, stack); + } + + @Override + protected boolean eventsEnabled() { + return true; + } } } diff --git a/src/main/java/gripe/_90/megacells/mixin/ItemMenuHostMixin.java b/src/main/java/gripe/_90/megacells/mixin/ItemMenuHostMixin.java index 824a05ab..c9f19788 100644 --- a/src/main/java/gripe/_90/megacells/mixin/ItemMenuHostMixin.java +++ b/src/main/java/gripe/_90/megacells/mixin/ItemMenuHostMixin.java @@ -18,7 +18,7 @@ public abstract class ItemMenuHostMixin { @Inject(method = "getUpgrades", at = @At("HEAD"), cancellable = true) private void getPortableCellWorkbenchUpgrades(CallbackInfoReturnable cir) { if (((ItemMenuHost) (Object) this) instanceof PortableCellWorkbenchMenuHost workbench) { - cir.setReturnValue(workbench.getCachedUpgrades()); + cir.setReturnValue(workbench.getCellUpgrades()); } } }