From a4aea95ad6b71a015d4354e0183d8f895b37dfb8 Mon Sep 17 00:00:00 2001 From: hiroscho Date: Tue, 12 Nov 2024 20:15:17 +0100 Subject: [PATCH 1/4] Fix that having multiple extract-only storage busses extracting from the same network will only have one of them work --- .../java/appeng/me/cache/NetworkMonitor.java | 2 +- .../appeng/me/storage/MEInventoryHandler.java | 69 +++++++++++++++++-- 2 files changed, 63 insertions(+), 8 deletions(-) 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..b8084803fbc 100644 --- a/src/main/java/appeng/me/storage/MEInventoryHandler.java +++ b/src/main/java/appeng/me/storage/MEInventoryHandler.java @@ -10,6 +10,13 @@ package appeng.me.storage; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Predicate; import javax.annotation.Nonnull; @@ -24,11 +31,15 @@ import appeng.api.storage.StorageChannel; import appeng.api.storage.data.IAEStack; import appeng.api.storage.data.IItemList; +import appeng.core.AELog; +import appeng.me.cache.NetworkMonitor; import appeng.util.prioitylist.DefaultPriorityList; import appeng.util.prioitylist.IPartitionList; public class MEInventoryHandler> implements IMEInventoryHandler { + private static final ThreadLocal, IItemList>>> networkItemsForIteration = new ThreadLocal<>(); + private final IMEInventoryHandler internal; private int myPriority; private IncludeExclude myWhitelist; @@ -111,8 +122,9 @@ public T extractItems(final T request, final Actionable type, final BaseActionSo return null; } } - - return this.internal.extractItems(request, type, src); + // keep extractable items + T items = this.internal.extractItems(request, type, src); + return items; } @Override @@ -133,17 +145,60 @@ public boolean isVisible() { } protected IItemList filterAvailableItems(IItemList out, int iteration) { - final IItemList allAvailableItems = this.internal - .getAvailableItems((IItemList) this.internal.getChannel().createList(), iteration); + final IItemList allAvailableItems = this.getAllAvailableItems(iteration); Predicate filterCondition = this.getExtractFilterCondition(); - for (T item : allAvailableItems) { - if (filterCondition.test(item)) { - out.add(item); + 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) { + final ThreadLocal, IItemList>>> iterationMap = networkItemsForIteration; + + Map, IItemList>> s = iterationMap.get(); + + NetworkInventoryHandler networkInventoryHandler = getNetworkInventoryHandler(); + if (s != null && s.get(iteration) == null) { + s = null; + } + if (s == null) { + s = Collections.singletonMap(iteration, new HashMap<>()); + iterationMap.set(s); + } + Map, IItemList> networkInventoryItems = s.get(iteration); + if (networkInventoryItems.get(networkInventoryHandler) == null) { + IItemList allAvailableItems = this.internal.getAvailableItems((IItemList) this.internal.getChannel().createList(), iteration); + networkInventoryItems.put(networkInventoryHandler, allAvailableItems); + } + + return (IItemList) networkInventoryItems.get(networkInventoryHandler); + } + + private NetworkInventoryHandler getNetworkInventoryHandler() { + return (NetworkInventoryHandler) findNetworkInventoryHandler(this.getInternal()); + } + + private NetworkInventoryHandler findNetworkInventoryHandler(IMEInventory inventory) { + if(inventory instanceof MEMonitorPassThrough passThrough) { + return findNetworkInventoryHandler(passThrough.getInternal()); + } else if(inventory instanceof NetworkMonitor networkMonitor) { + return findNetworkInventoryHandler(networkMonitor.getHandler()); + } else if(inventory instanceof NetworkInventoryHandler networkInventoryHandler) { + return networkInventoryHandler; + } else { + AELog.error("NetworkInventoryHandler cannot be determined for %s", inventory.getClass()); + return null; + } + } + @Override public T getAvailableItem(@Nonnull T request, int iteration) { if (!this.hasReadAccess && !isVisible()) { From 7f354adce74dab9efc1cde2a8fb03f8e4f392961 Mon Sep 17 00:00:00 2001 From: hiroscho Date: Tue, 12 Nov 2024 21:18:37 +0100 Subject: [PATCH 2/4] Fix extract-only storage bus with filter and extract-only storage bus without filter reading from the same network --- .../appeng/me/storage/MEInventoryHandler.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/java/appeng/me/storage/MEInventoryHandler.java b/src/main/java/appeng/me/storage/MEInventoryHandler.java index b8084803fbc..9b2caa1394c 100644 --- a/src/main/java/appeng/me/storage/MEInventoryHandler.java +++ b/src/main/java/appeng/me/storage/MEInventoryHandler.java @@ -10,13 +10,10 @@ package appeng.me.storage; -import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; -import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.function.Predicate; import javax.annotation.Nonnull; @@ -31,7 +28,6 @@ import appeng.api.storage.StorageChannel; import appeng.api.storage.data.IAEStack; import appeng.api.storage.data.IItemList; -import appeng.core.AELog; import appeng.me.cache.NetworkMonitor; import appeng.util.prioitylist.DefaultPriorityList; import appeng.util.prioitylist.IPartitionList; @@ -122,7 +118,7 @@ public T extractItems(final T request, final Actionable type, final BaseActionSo return null; } } - // keep extractable items + // TODO keep extractable items T items = this.internal.extractItems(request, type, src); return items; } @@ -136,7 +132,7 @@ public IItemList getAvailableItems(final IItemList out, int iteration) { if (this.isExtractFilterActive() && !this.myExtractPartitionList.isEmpty()) { return this.filterAvailableItems(out, iteration); } else { - return this.internal.getAvailableItems(out, iteration); + return this.getAvailableItems(out, iteration, e -> true); } } @@ -145,8 +141,13 @@ public boolean isVisible() { } protected IItemList filterAvailableItems(IItemList out, int iteration) { - final IItemList allAvailableItems = this.getAllAvailableItems(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(); @@ -156,7 +157,6 @@ protected IItemList filterAvailableItems(IItemList out, int iteration) { it.remove(); } } - return out; } @@ -166,6 +166,10 @@ private IItemList getAllAvailableItems(int iteration) { Map, IItemList>> s = iterationMap.get(); NetworkInventoryHandler networkInventoryHandler = getNetworkInventoryHandler(); + if(networkInventoryHandler == null) { + return this.internal.getAvailableItems((IItemList) this.internal.getChannel().createList(), iteration); + } + if (s != null && s.get(iteration) == null) { s = null; } @@ -186,15 +190,15 @@ private NetworkInventoryHandler getNetworkInventoryHandler() { return (NetworkInventoryHandler) findNetworkInventoryHandler(this.getInternal()); } + // should give back the NetworkInventoryHandler for storage buses, everything else can be null private NetworkInventoryHandler findNetworkInventoryHandler(IMEInventory inventory) { - if(inventory instanceof MEMonitorPassThrough passThrough) { + if(inventory instanceof MEPassThrough passThrough) { return findNetworkInventoryHandler(passThrough.getInternal()); } else if(inventory instanceof NetworkMonitor networkMonitor) { return findNetworkInventoryHandler(networkMonitor.getHandler()); } else if(inventory instanceof NetworkInventoryHandler networkInventoryHandler) { return networkInventoryHandler; } else { - AELog.error("NetworkInventoryHandler cannot be determined for %s", inventory.getClass()); return null; } } From 6a0943e32183c77a41047ac5eb3b0ae8c3c7efd2 Mon Sep 17 00:00:00 2001 From: hiroscho Date: Thu, 14 Nov 2024 18:22:48 +0100 Subject: [PATCH 3/4] refine --- .../appeng/me/storage/MEInventoryHandler.java | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/main/java/appeng/me/storage/MEInventoryHandler.java b/src/main/java/appeng/me/storage/MEInventoryHandler.java index 9b2caa1394c..bbb14525150 100644 --- a/src/main/java/appeng/me/storage/MEInventoryHandler.java +++ b/src/main/java/appeng/me/storage/MEInventoryHandler.java @@ -11,7 +11,7 @@ package appeng.me.storage; import java.util.Collections; -import java.util.HashMap; +import java.util.IdentityHashMap; import java.util.Iterator; import java.util.Map; import java.util.function.Predicate; @@ -118,9 +118,8 @@ public T extractItems(final T request, final Actionable type, final BaseActionSo return null; } } - // TODO keep extractable items - T items = this.internal.extractItems(request, type, src); - return items; + + return this.internal.extractItems(request, type, src); } @Override @@ -149,7 +148,7 @@ protected IItemList filterAvailableItems(IItemList out, int iteration) { private IItemList getAvailableItems(IItemList out, int iteration, Predicate filterCondition) { final IItemList allAvailableItems = this.getAllAvailableItems(iteration); Iterator it = allAvailableItems.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { T items = it.next(); if (filterCondition.test(items)) { out.add(items); @@ -161,25 +160,23 @@ private IItemList getAvailableItems(IItemList out, int iteration, Predicat } private IItemList getAllAvailableItems(int iteration) { - final ThreadLocal, IItemList>>> iterationMap = networkItemsForIteration; - - Map, IItemList>> s = iterationMap.get(); - NetworkInventoryHandler networkInventoryHandler = getNetworkInventoryHandler(); - if(networkInventoryHandler == null) { + if (networkInventoryHandler == null) { return this.internal.getAvailableItems((IItemList) this.internal.getChannel().createList(), iteration); } - if (s != null && s.get(iteration) == null) { + Map, IItemList>> s = networkItemsForIteration.get(); + if (s != null && !s.containsKey(iteration)) { s = null; } if (s == null) { - s = Collections.singletonMap(iteration, new HashMap<>()); - iterationMap.set(s); + s = Collections.singletonMap(iteration, new IdentityHashMap<>()); + networkItemsForIteration.set(s); } Map, IItemList> networkInventoryItems = s.get(iteration); - if (networkInventoryItems.get(networkInventoryHandler) == null) { - IItemList allAvailableItems = this.internal.getAvailableItems((IItemList) this.internal.getChannel().createList(), iteration); + if (!networkInventoryItems.containsKey(networkInventoryHandler)) { + IItemList allAvailableItems = this.internal + .getAvailableItems((IItemList) this.internal.getChannel().createList(), iteration); networkInventoryItems.put(networkInventoryHandler, allAvailableItems); } @@ -192,11 +189,11 @@ private NetworkInventoryHandler getNetworkInventoryHandler() { // should give back the NetworkInventoryHandler for storage buses, everything else can be null private NetworkInventoryHandler findNetworkInventoryHandler(IMEInventory inventory) { - if(inventory instanceof MEPassThrough passThrough) { + if (inventory instanceof MEPassThroughpassThrough) { return findNetworkInventoryHandler(passThrough.getInternal()); - } else if(inventory instanceof NetworkMonitor networkMonitor) { + } else if (inventory instanceof NetworkMonitornetworkMonitor) { return findNetworkInventoryHandler(networkMonitor.getHandler()); - } else if(inventory instanceof NetworkInventoryHandler networkInventoryHandler) { + } else if (inventory instanceof NetworkInventoryHandlernetworkInventoryHandler) { return networkInventoryHandler; } else { return null; From 2854f414529647969013f7f0b3697f7efc760803 Mon Sep 17 00:00:00 2001 From: hiroscho Date: Sun, 17 Nov 2024 13:54:10 +0100 Subject: [PATCH 4/4] extract changes to StorageBusInventoryHandler --- .../appeng/me/storage/MEInventoryHandler.java | 70 ++---------- .../storage/StorageBusInventoryHandler.java | 100 ++++++++++++++++++ .../appeng/parts/misc/PartStorageBus.java | 3 +- 3 files changed, 109 insertions(+), 64 deletions(-) create mode 100644 src/main/java/appeng/me/storage/StorageBusInventoryHandler.java diff --git a/src/main/java/appeng/me/storage/MEInventoryHandler.java b/src/main/java/appeng/me/storage/MEInventoryHandler.java index bbb14525150..5a98e7ce2a6 100644 --- a/src/main/java/appeng/me/storage/MEInventoryHandler.java +++ b/src/main/java/appeng/me/storage/MEInventoryHandler.java @@ -10,10 +10,6 @@ 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 javax.annotation.Nonnull; @@ -28,14 +24,11 @@ import appeng.api.storage.StorageChannel; import appeng.api.storage.data.IAEStack; import appeng.api.storage.data.IItemList; -import appeng.me.cache.NetworkMonitor; import appeng.util.prioitylist.DefaultPriorityList; import appeng.util.prioitylist.IPartitionList; public class MEInventoryHandler> implements IMEInventoryHandler { - private static final ThreadLocal, IItemList>>> networkItemsForIteration = new ThreadLocal<>(); - private final IMEInventoryHandler internal; private int myPriority; private IncludeExclude myWhitelist; @@ -44,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; @@ -131,7 +124,7 @@ public IItemList getAvailableItems(final IItemList out, int iteration) { if (this.isExtractFilterActive() && !this.myExtractPartitionList.isEmpty()) { return this.filterAvailableItems(out, iteration); } else { - return this.getAvailableItems(out, iteration, e -> true); + return this.internal.getAvailableItems(out, iteration); } } @@ -140,66 +133,17 @@ public boolean isVisible() { } protected IItemList filterAvailableItems(IItemList out, int iteration) { + final IItemList allAvailableItems = this.internal + .getAvailableItems((IItemList) this.internal.getChannel().createList(), 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(); + for (T item : allAvailableItems) { + if (filterCondition.test(item)) { + out.add(item); } } return out; } - private IItemList getAllAvailableItems(int iteration) { - NetworkInventoryHandler networkInventoryHandler = getNetworkInventoryHandler(); - if (networkInventoryHandler == null) { - return this.internal.getAvailableItems((IItemList) this.internal.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.internal - .getAvailableItems((IItemList) this.internal.getChannel().createList(), iteration); - networkInventoryItems.put(networkInventoryHandler, allAvailableItems); - } - - return (IItemList) networkInventoryItems.get(networkInventoryHandler); - } - - private NetworkInventoryHandler getNetworkInventoryHandler() { - return (NetworkInventoryHandler) findNetworkInventoryHandler(this.getInternal()); - } - - // should give back the NetworkInventoryHandler for storage buses, everything else can be null - 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; - } - } - @Override public T getAvailableItem(@Nonnull T request, int iteration) { if (!this.hasReadAccess && !isVisible()) { 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 3b79764e50d..79cac390ed7 100644 --- a/src/main/java/appeng/parts/misc/PartStorageBus.java +++ b/src/main/java/appeng/parts/misc/PartStorageBus.java @@ -72,6 +72,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; @@ -458,7 +459,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);