diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/util/IItemStackList.java b/src/main/java/com/raoulvdberge/refinedstorage/api/util/IItemStackList.java index 3c8d09bdc..3045d6119 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/util/IItemStackList.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/util/IItemStackList.java @@ -6,6 +6,7 @@ import net.minecraft.item.ItemStack; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Collection; +import java.util.List; /** * An item stack list. @@ -67,6 +68,8 @@ public interface IItemStackList { */ void undo(); + List getRemoveTracker(); + /** * Returns a stack. * @@ -123,4 +126,10 @@ public interface IItemStackList { */ @Nonnull IItemStackList copy(); + + /** + * @return the list wrapped in an ore dictionary optimized {@link IItemStackList} + */ + @Nonnull + IItemStackList prepOreDict(); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java index 7010dc487..c3cf6550d 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java @@ -72,6 +72,7 @@ public class CraftingTask implements ICraftingTask { // Copy here might be expensive but since it is only executed once it isn't a big impact IItemStackList networkList = network.getItemStorageCache().getList().copy(); networkList.clean(); // Remove the zero stacks + networkList = networkList.prepOreDict(); IItemStackList toInsert = API.instance().createItemStackList(); toCraft.add(ItemHandlerHelper.copyStackWithSize(requested, quantity)); @@ -250,6 +251,8 @@ public class CraftingTask implements ICraftingTask { toTakeFluids.clean(); + IItemStackList oreDictPrepped = network.getItemStorageCache().getList().prepOreDict(); + for (ICraftingStep step : steps) { ICraftingPatternContainer container = step.getPattern().getContainer(); Integer timesUsed = usedContainers.get(container); @@ -259,9 +262,10 @@ public class CraftingTask implements ICraftingTask { } if (timesUsed++ <= container.getSpeedUpdateCount()) { - if (!step.hasStartedProcessing() && step.canStartProcessing(network.getItemStorageCache().getList(), tookFluids)) { + if (!step.hasStartedProcessing() && step.canStartProcessing(oreDictPrepped, tookFluids)) { step.setStartedProcessing(); step.execute(toInsertItems, toInsertFluids); + oreDictPrepped.clean(); // Might have to clean out some zero stacks usedContainers.put(container, timesUsed); network.sendCraftingMonitorUpdate(); } @@ -362,6 +366,8 @@ public class CraftingTask implements ICraftingTask { if (steps.stream().filter(s -> !s.getPattern().isProcessing()).count() > 0) { elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_crafting", 16)); + IItemStackList oreDictPrepped = network.getItemStorageCache().getList().prepOreDict(); + for (ICraftingStep step : steps.stream().filter(s -> !s.getPattern().isProcessing()).collect(Collectors.toList())) { for (int i = 0; i < step.getPattern().getOutputs().size(); ++i) { ICraftingMonitorElement element = new CraftingMonitorElementItemRender( @@ -371,7 +377,7 @@ public class CraftingTask implements ICraftingTask { 32 ); - if (!step.hasStartedProcessing() && !step.canStartProcessing(network.getItemStorageCache().getList(), tookFluids)) { + if (!step.hasStartedProcessing() && !step.canStartProcessing(oreDictPrepped, tookFluids)) { element = new CraftingMonitorElementInfo(element, "gui.refinedstorage:crafting_monitor.waiting_for_items"); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/ItemStackList.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/ItemStackList.java index 6f3dfa613..6c73028b6 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/ItemStackList.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/ItemStackList.java @@ -18,7 +18,7 @@ import java.util.stream.Collectors; public class ItemStackList implements IItemStackList { private ArrayListMultimap stacks = ArrayListMultimap.create(); - private List removeTracker = new LinkedList<>(); + protected List removeTracker = new LinkedList<>(); @Override public void add(ItemStack stack) { @@ -75,6 +75,11 @@ public class ItemStackList implements IItemStackList { return false; } + @Override + public List getRemoveTracker() { + return removeTracker; + } + @Override public void undo() { removeTracker.forEach(this::add); @@ -143,6 +148,12 @@ public class ItemStackList implements IItemStackList { return list; } + @Nonnull + @Override + public IItemStackList prepOreDict() { + return new OreDictedItemStackList(this); + } + @Override public String toString() { return stacks.toString(); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/OreDictedItemStackList.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/OreDictedItemStackList.java new file mode 100644 index 000000000..3f9c9b907 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/OreDictedItemStackList.java @@ -0,0 +1,141 @@ +package com.raoulvdberge.refinedstorage.apiimpl.util; + +import com.google.common.collect.ArrayListMultimap; +import com.raoulvdberge.refinedstorage.api.util.IComparer; +import com.raoulvdberge.refinedstorage.api.util.IItemStackList; +import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.OreDictionary; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class OreDictedItemStackList implements IItemStackList { + private IItemStackList underlyingList; + private ArrayListMultimap stacks = ArrayListMultimap.create(); + + private OreDictedItemStackList() {} + + public OreDictedItemStackList(IItemStackList list) { + this.underlyingList = list; + initOreDict(); + } + + private void initOreDict() { + for (ItemStack stack : underlyingList.getStacks()) { + for (int id : OreDictionary.getOreIDs(stack)) { + stacks.put(id, stack); + } + } + } + + @Override + public void add(ItemStack stack) { + underlyingList.add(stack); + if (underlyingList.get(stack).stackSize == stack.stackSize) { + for (int id : OreDictionary.getOreIDs(stack)) { + stacks.put(id, stack); + } + } + } + + @Override + public boolean remove(@Nonnull ItemStack stack, int size, boolean removeIfReachedZero) { + boolean rvalue = underlyingList.remove(stack, size, removeIfReachedZero); + if (removeIfReachedZero) { + localClean(); + } + return rvalue; + } + + @Override + public boolean trackedRemove(@Nonnull ItemStack stack, int size, boolean removeIfReachedZero) { + boolean rvalue = underlyingList.trackedRemove(stack, size, removeIfReachedZero); + if (removeIfReachedZero) { + localClean(); + } + return rvalue; + } + + @Override + public List getRemoveTracker() { + return underlyingList.getRemoveTracker(); + } + + @Override + public void undo() { + underlyingList.getRemoveTracker().forEach(this::add); + underlyingList.getRemoveTracker().clear(); + } + + @Nullable + @Override + public ItemStack get(@Nonnull ItemStack stack, int flags) { + if ((flags & IComparer.COMPARE_OREDICT) == IComparer.COMPARE_OREDICT) { + int[] ids = OreDictionary.getOreIDs(stack); + for (int id : ids) { + List stacks = this.stacks.get(id); + if (stacks != null && !stacks.isEmpty()) { + return stacks.get(0); + } + } + } + return underlyingList.get(stack, flags); + } + + @Nullable + @Override + public ItemStack get(int hash) { + return underlyingList.get(hash); + } + + @Override + public void clear() { + underlyingList.clear(); + } + + private void localClean() { + List> toRemove = stacks.entries().stream() + .filter(entry -> entry.getValue().stackSize <= 0) + .collect(Collectors.toList()); + + toRemove.forEach(entry -> stacks.remove(entry.getKey(), entry.getValue())); + } + + @Override + public void clean() { + localClean(); + underlyingList.clean(); + } + + @Override + public boolean isEmpty() { + return underlyingList.isEmpty(); + } + + @Nonnull + @Override + public Collection getStacks() { + return underlyingList.getStacks(); + } + + @Nonnull + @Override + public IItemStackList copy() { + OreDictedItemStackList newList = new OreDictedItemStackList(); + newList.underlyingList = this.underlyingList.copy(); + for (Map.Entry entry : this.stacks.entries()) { + newList.stacks.put(entry.getKey(), entry.getValue()); + } + return newList; + } + + @Nonnull + @Override + public IItemStackList prepOreDict() { + return this; + } +}