diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/item/ItemStorageCache.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/item/ItemStorageCache.java index 4e1307706..c008277ed 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/item/ItemStorageCache.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/item/ItemStorageCache.java @@ -39,7 +39,9 @@ public class ItemStorageCache implements IItemStorageCache { } for (ItemStack stack : storage.getStacks()) { - add(stack, true); + if (stack != null) { + add(stack, true); + } } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileController.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileController.java index d92528100..200cb8f3b 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileController.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileController.java @@ -530,13 +530,13 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR if (remainder == null || remainder.stackSize < 0) { if (storage instanceof ItemStorageExternal && !simulate) { - ((ItemStorageExternal) storage).updateCacheForcefully(); + ((ItemStorageExternal) storage).updateForced(); } break; } else { if (size != remainder.stackSize && storage instanceof ItemStorageExternal && !simulate) { - ((ItemStorageExternal) storage).updateCacheForcefully(); + ((ItemStorageExternal) storage).updateForced(); } size = remainder.stackSize; @@ -586,7 +586,7 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR if (took != null) { if (storage instanceof ItemStorageExternal) { - ((ItemStorageExternal) storage).updateCacheForcefully(); + ((ItemStorageExternal) storage).updateForced(); } if (newStack == null) { diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/externalstorage/ItemStorageExternal.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/externalstorage/ItemStorageExternal.java index 678b390ff..5c4646826 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/externalstorage/ItemStorageExternal.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/externalstorage/ItemStorageExternal.java @@ -1,9 +1,12 @@ package com.raoulvdberge.refinedstorage.tile.externalstorage; +import com.raoulvdberge.refinedstorage.api.network.INetworkMaster; import com.raoulvdberge.refinedstorage.api.storage.item.IItemStorage; import com.raoulvdberge.refinedstorage.apiimpl.API; import net.minecraft.item.ItemStack; +import net.minecraftforge.items.ItemHandlerHelper; +import java.util.LinkedList; import java.util.List; public abstract class ItemStorageExternal implements IItemStorage { @@ -11,29 +14,67 @@ public abstract class ItemStorageExternal implements IItemStorage { public abstract int getCapacity(); - public boolean updateCache() { - List newStacks = getStacks(); - - if (this.cache == null) { - this.cache = newStacks; - } else if (newStacks.size() != cache.size()) { - this.cache = newStacks; - - return true; + public void detectChanges(INetworkMaster network) { + if (cache == null) { + updateForced(); } else { - for (int i = 0; i < newStacks.size(); ++i) { - if (!API.instance().getComparer().isEqual(newStacks.get(i), cache.get(i))) { - this.cache = newStacks; + LinkedList changes = new LinkedList<>(); - return true; + List newStacks = getStacks(); + + for (int i = 0; i < newStacks.size(); ++i) { + ItemStack actual = newStacks.get(i); + + // If we exceed the cache size, than that means this items is added + if (i >= cache.size()) { + if (actual != null) { + changes.add(ItemHandlerHelper.copyStackWithSize(actual, actual.stackSize)); + } + + continue; + } + + ItemStack cached = cache.get(i); + + if (cached != null && actual == null) { + // If the cached is not null but the actual is, we removed this item + changes.add(ItemHandlerHelper.copyStackWithSize(cached, -cached.stackSize)); + } else if (cached == null && actual != null) { + // If the cached is null and the actual isn't, we added this item + changes.add(ItemHandlerHelper.copyStackWithSize(actual, actual.stackSize)); + } else if (cached == null && actual == null) { + // If they're both null, nothing happens + } else if (!API.instance().getComparer().isEqualNoQuantity(cached, actual)) { + // If both items mismatch, remove the old and add the new + changes.add(ItemHandlerHelper.copyStackWithSize(cached, -cached.stackSize)); + changes.add(ItemHandlerHelper.copyStackWithSize(actual, actual.stackSize)); + } else if (cached.stackSize != actual.stackSize) { + // If both items mismatch on itemcount, apply the change + changes.add(ItemHandlerHelper.copyStackWithSize(cached, actual.stackSize - cached.stackSize)); + } + } + + // If the cache size is somehow bigger than the actual stacks, that means the inventory shrunk + // In that case, we remove the items that have been removed due to the shrinkage + if (cache.size() > newStacks.size()) { + for (int i = newStacks.size(); i < cache.size(); ++i) { + changes.add(ItemHandlerHelper.copyStackWithSize(cache.get(i), -cache.get(i).stackSize)); + } + } + + this.cache = newStacks; + + for (ItemStack change : changes) { + if (change.stackSize > 0) { + network.getItemStorageCache().add(change, false); + } else { + network.getItemStorageCache().remove(change); } } } - - return false; } - public void updateCacheForcefully() { + public void updateForced() { this.cache = getStacks(); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/externalstorage/ItemStorageItemHandler.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/externalstorage/ItemStorageItemHandler.java index 63d865d3e..fc558652a 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/externalstorage/ItemStorageItemHandler.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/externalstorage/ItemStorageItemHandler.java @@ -34,9 +34,7 @@ public class ItemStorageItemHandler extends ItemStorageExternal { List items = new ArrayList<>(); for (int i = 0; i < handler.getSlots(); ++i) { - if (handler.getStackInSlot(i) != null && handler.getStackInSlot(i).getItem() != null) { - items.add(handler.getStackInSlot(i).copy()); - } + items.add(handler.getStackInSlot(i) != null ? handler.getStackInSlot(i).copy() : null); } return items; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/externalstorage/TileExternalStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/externalstorage/TileExternalStorage.java index f369d9f8c..b1f9722e8 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/externalstorage/TileExternalStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/externalstorage/TileExternalStorage.java @@ -127,24 +127,18 @@ public class TileExternalStorage extends TileMultipartNode implements IItemStora @Override public void update() { if (!worldObj.isRemote && network != null) { - boolean itemChangeDetected = false, fluidChangeDetected = false; - for (ItemStorageExternal storage : itemStorages) { - if (storage.updateCache()) { - itemChangeDetected = true; - } + storage.detectChanges(network); } + boolean fluidChangeDetected = false; + for (FluidStorageExternal storage : fluidStorages) { if (storage.updateCache()) { fluidChangeDetected = true; } } - if (itemChangeDetected) { - network.getItemStorageCache().invalidate(); - } - if (fluidChangeDetected) { network.getFluidStorageCache().invalidate(); }