Oredict doesn't work in 1.11 anymore
raoulvdberge opened this issue ยท 7 comments
Thanks to my optimization in 69d92c4 storages now use a multimap instead of a list. Thanks to that, we no longer have to iterate over every item in the storage.
This has an unintended side-effect that oredict extractions don't work anymore because when using the oredict the item will differ thus it won't be found in the multimap.
This only affects the StorageDiskItem
class, since all other storage classes have to iterate over every item (for example the item handler external storage handler).
I have this patch laying around, but it appears to show weird behavior (unlimited extractions):
--- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageDiskItem.java
+++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageDiskItem.java
@@ -5,12 +5,14 @@ import com.google.common.collect.Multimap;
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
import com.raoulvdberge.refinedstorage.api.storage.IStorageDisk;
import com.raoulvdberge.refinedstorage.api.storage.StorageDiskType;
+import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.items.ItemHandlerHelper;
+import net.minecraftforge.oredict.OreDictionary;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -190,7 +192,27 @@ public class StorageDiskItem implements IStorageDisk<ItemStack> {
@Override
@Nullable
public synchronized ItemStack extract(@Nonnull ItemStack stack, int size, int flags, boolean simulate) {
- for (ItemStack otherStack : stacks.get(stack.getItem())) {
+ Collection<ItemStack> toAttempt = null;
+
+ if ((flags & IComparer.COMPARE_OREDICT) == IComparer.COMPARE_OREDICT) {
+ for (int id : OreDictionary.getOreIDs(stack)) {
+ Collection<ItemStack> ores = OreDictionary.getOres(OreDictionary.getOreName(id));
+
+ for (ItemStack ore : ores) {
+ if (toAttempt == null) {
+ toAttempt = stacks.get(ore.getItem());
+ } else {
+ toAttempt.addAll(stacks.get(ore.getItem()));
+ }
+ }
+ }
+ }
+
+ if (toAttempt == null) {
+ toAttempt = stacks.get(stack.getItem());
+ }
+
+ for (ItemStack otherStack : toAttempt) {
if (API.instance().getComparer().isEqual(otherStack, stack, flags)) {
if (size > otherStack.getCount()) {
size = otherStack.getCount();
for (int id : OreDictionary.getOreIDs(stack))
and OreDictionary.getOres(OreDictionary.getOreName(id))
so you would like to trow performance out of your window? Kappa
You need to clone the list returned by ArrayListMultimap.get
. Though I'm not entirely sure how it causes the bug you identified.
https://google.github.io/guava/releases/snapshot/api/docs/com/google/common/collect/ArrayListMultimap.html#get-K-
Changes to the returned collection will update the underlying multimap, and vice versa.
Something else, am I seeing correctly that with the change, in case there are two or more stacks of different item types, but same oredict entries, it will stop retrieving them at the first, rather than continue looking for more when size > otherStack.getCount()
?
@way2muchnoise The first looks slow, yeah, but getOres
is O(1), it's a simple arraylist lookup.
https://github.com/MinecraftForge/MinecraftForge/blob/1.11.x/src/main/java/net/minecraftforge/oredict/OreDictionary.java#L542
@Dykam I know it looks that way, but for some reason the oredict is very slow. This is speaking out of experience. Also even if that part is O(1), the whole thing will still be horrible performance wise.
@Dykam Thanks, that was the cause.
getOreIds
is the slowdown, but I'm caching it now.
Something else, am I seeing correctly that with the change, in case there are two or more stacks of different item types, but same oredict entries, it will stop retrieving them at the first, rather than continue looking for more when size > otherStack.getCount()?
Yes, it has to do that or it will convert stacks of an other type to the equivalent oredict type, which is not allowed