From 9b63cc81b1765d566e8ce2872b655cd5712194ca Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 21 Mar 2024 19:47:41 +0000 Subject: [PATCH] Custom equality for Fabric's storage types Double chests peripherals were getting reattached every time there was a block update, as the inventories were not comparing equal (despite being so!). We now check for a couple of common cases, which should be enough for vanilla/vanilla-like inventories. I actively Do Not Like This Code, but do not see a good alternative. --- .../generic/methods/InventoryMethods.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java b/projects/fabric/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java index e1848775b..f14753d37 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java +++ b/projects/fabric/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java @@ -13,6 +13,8 @@ import net.fabricmc.fabric.api.transfer.v1.item.ItemStorage; import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant; import net.fabricmc.fabric.api.transfer.v1.storage.SlottedStorage; +import net.fabricmc.fabric.api.transfer.v1.storage.base.CombinedSlottedStorage; +import net.fabricmc.fabric.api.transfer.v1.storage.base.CombinedStorage; import net.fabricmc.fabric.api.transfer.v1.storage.base.SingleSlotStorage; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -42,6 +44,34 @@ public final class InventoryMethods extends AbstractInventoryMethods storage) { + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof StorageWrapper other)) return false; + + var otherStorage = other.storage; + + /* + Equality for inventory storage isn't really defined, and most of the time falls back to reference + equality. + - Vanilla inventories are exposed via InventoryStorage - the creation of this is cached, so will be + the same object. + - Double chests are combined into a CombinedSlottedStorage. We check the parts are equal. + */ + if ( + storage instanceof CombinedSlottedStorage cs && storage.getClass() == otherStorage.getClass() + && cs.parts.equals(((CombinedStorage) otherStorage).parts) + ) { + return true; + } + + return storage.equals(otherStorage); + } + + @Override + public int hashCode() { + return storage instanceof CombinedSlottedStorage cs ? cs.parts.hashCode() : storage.hashCode(); + } } @Override