diff --git a/src/main/java/appeng/me/cache/NetworkMonitor.java b/src/main/java/appeng/me/cache/NetworkMonitor.java index 89a8bc40fdb..6902e12f335 100644 --- a/src/main/java/appeng/me/cache/NetworkMonitor.java +++ b/src/main/java/appeng/me/cache/NetworkMonitor.java @@ -166,7 +166,7 @@ public boolean validForPass(final int i) { @Nullable @SuppressWarnings("unchecked") - private IMEInventoryHandler getHandler() { + public IMEInventoryHandler getHandler() { switch (this.myChannel) { case ITEMS -> { return (IMEInventoryHandler) this.myGridCache.getItemInventoryHandler(); diff --git a/src/main/java/appeng/me/storage/MEInventoryHandler.java b/src/main/java/appeng/me/storage/MEInventoryHandler.java index c169e733c82..5a98e7ce2a6 100644 --- a/src/main/java/appeng/me/storage/MEInventoryHandler.java +++ b/src/main/java/appeng/me/storage/MEInventoryHandler.java @@ -37,7 +37,7 @@ public class MEInventoryHandler> implements IMEInventoryHa private IPartitionList myExtractPartitionList; private AccessRestriction cachedAccessRestriction; - private boolean hasReadAccess; + protected boolean hasReadAccess; protected boolean hasWriteAccess; protected boolean isSticky; protected boolean isExtractFilterActive; diff --git a/src/main/java/appeng/me/storage/StorageBusInventoryHandler.java b/src/main/java/appeng/me/storage/StorageBusInventoryHandler.java new file mode 100644 index 00000000000..63ce3732fda --- /dev/null +++ b/src/main/java/appeng/me/storage/StorageBusInventoryHandler.java @@ -0,0 +1,100 @@ +package appeng.me.storage; + +import java.util.Collections; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.function.Predicate; + +import appeng.api.storage.IMEInventory; +import appeng.api.storage.StorageChannel; +import appeng.api.storage.data.IAEStack; +import appeng.api.storage.data.IItemList; +import appeng.me.cache.NetworkMonitor; + +public class StorageBusInventoryHandler> extends MEInventoryHandler { + + private static final ThreadLocal, IItemList>>> networkItemsForIteration = new ThreadLocal<>(); + + public StorageBusInventoryHandler(IMEInventory i, StorageChannel channel) { + super(i, channel); + } + + @Override + public IItemList getAvailableItems(final IItemList out, int iteration) { + if (!this.hasReadAccess && !isVisible()) { + return out; + } + + if (this.isExtractFilterActive() && !this.getExtractPartitionList().isEmpty()) { + return this.filterAvailableItems(out, iteration); + } else { + return this.getAvailableItems(out, iteration, e -> true); + } + } + + @Override + protected IItemList filterAvailableItems(IItemList out, int iteration) { + Predicate filterCondition = this.getExtractFilterCondition(); + getAvailableItems(out, iteration, filterCondition); + return out; + } + + private IItemList getAvailableItems(IItemList out, int iteration, Predicate filterCondition) { + final IItemList allAvailableItems = this.getAllAvailableItems(iteration); + Iterator it = allAvailableItems.iterator(); + while (it.hasNext()) { + T items = it.next(); + if (filterCondition.test(items)) { + out.add(items); + // have to remove the item otherwise it could be counted double + it.remove(); + } + } + return out; + } + + private IItemList getAllAvailableItems(int iteration) { + NetworkInventoryHandler networkInventoryHandler = getNetworkInventoryHandler(); + if (networkInventoryHandler == null) { + return this.getInternal() + .getAvailableItems((IItemList) this.getInternal().getChannel().createList(), iteration); + } + + Map, IItemList>> s = networkItemsForIteration.get(); + if (s != null && !s.containsKey(iteration)) { + s = null; + } + if (s == null) { + s = Collections.singletonMap(iteration, new IdentityHashMap<>()); + networkItemsForIteration.set(s); + } + Map, IItemList> networkInventoryItems = s.get(iteration); + if (!networkInventoryItems.containsKey(networkInventoryHandler)) { + IItemList allAvailableItems = this.getInternal() + .getAvailableItems((IItemList) this.getInternal().getChannel().createList(), iteration); + networkInventoryItems.put(networkInventoryHandler, allAvailableItems); + } + + return (IItemList) networkInventoryItems.get(networkInventoryHandler); + } + + /** + * Find the NetworkInventoryHandler for this storage bus + */ + private NetworkInventoryHandler getNetworkInventoryHandler() { + return (NetworkInventoryHandler) findNetworkInventoryHandler(this.getInternal()); + } + + private NetworkInventoryHandler findNetworkInventoryHandler(IMEInventory inventory) { + if (inventory instanceof MEPassThroughpassThrough) { + return findNetworkInventoryHandler(passThrough.getInternal()); + } else if (inventory instanceof NetworkMonitornetworkMonitor) { + return findNetworkInventoryHandler(networkMonitor.getHandler()); + } else if (inventory instanceof NetworkInventoryHandlernetworkInventoryHandler) { + return networkInventoryHandler; + } else { + return null; + } + } +} diff --git a/src/main/java/appeng/parts/misc/PartStorageBus.java b/src/main/java/appeng/parts/misc/PartStorageBus.java index 770fe80360b..61642d265e5 100644 --- a/src/main/java/appeng/parts/misc/PartStorageBus.java +++ b/src/main/java/appeng/parts/misc/PartStorageBus.java @@ -73,6 +73,7 @@ import appeng.me.GridAccessException; import appeng.me.storage.MEInventoryHandler; import appeng.me.storage.MEMonitorIInventory; +import appeng.me.storage.StorageBusInventoryHandler; import appeng.parts.automation.PartUpgradeable; import appeng.tile.inventory.AppEngInternalAEInventory; import appeng.tile.inventory.InvOperation; @@ -480,7 +481,7 @@ public MEInventoryHandler getInternalHandler() { if (inv != null) { this.checkInterfaceVsStorageBus(target, this.getSide().getOpposite()); - this.handler = new MEInventoryHandler(inv, StorageChannel.ITEMS); + this.handler = new StorageBusInventoryHandler<>(inv, StorageChannel.ITEMS); AccessRestriction currentAccess = (AccessRestriction) this.getConfigManager() .getSetting(Settings.ACCESS);