diff --git a/src/main/java/appeng/core/api/ApiStorage.java b/src/main/java/appeng/core/api/ApiStorage.java index 1d693613..301f21d7 100644 --- a/src/main/java/appeng/core/api/ApiStorage.java +++ b/src/main/java/appeng/core/api/ApiStorage.java @@ -41,6 +41,7 @@ import appeng.util.Platform; import appeng.util.item.AEFluidStack; import appeng.util.item.AEItemStack; import appeng.util.item.ItemList; +import appeng.util.item.FluidList; public class ApiStorage implements IStorageHelper @@ -67,13 +68,13 @@ public class ApiStorage implements IStorageHelper @Override public IItemList createItemList() { - return new ItemList( IAEItemStack.class ); + return new ItemList(); } @Override public IItemList createFluidList() { - return new ItemList( IAEFluidStack.class ); + return new FluidList(); } @Override diff --git a/src/main/java/appeng/util/item/FluidList.java b/src/main/java/appeng/util/item/FluidList.java new file mode 100644 index 00000000..1d675aa7 --- /dev/null +++ b/src/main/java/appeng/util/item/FluidList.java @@ -0,0 +1,201 @@ +/* + * This file is part of Applied Energistics 2. + * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved. + * + * Applied Energistics 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Applied Energistics 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Applied Energistics 2. If not, see . + */ + +package appeng.util.item; + + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import appeng.api.config.FuzzyMode; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IItemList; + + +public final class FluidList implements IItemList +{ + + private final Map records = new HashMap(); + + @Override + public void add( IAEFluidStack option ) + { + if( option == null ) + { + return; + } + + final IAEFluidStack st = this.getFluidRecord( option ); + + if( st != null ) + { + st.add( option ); + return; + } + + final IAEFluidStack opt = option.copy(); + + this.putFluidRecord( opt ); + } + + @Override + public IAEFluidStack findPrecise( IAEFluidStack fluidStack ) + { + if( fluidStack == null ) + { + return null; + } + + return this.getFluidRecord( fluidStack ); + } + + @Override + public Collection findFuzzy( IAEFluidStack filter, FuzzyMode fuzzy ) + { + if( filter == null ) + { + return Collections.emptyList(); + } + + return Collections.singletonList( this.findPrecise( filter ) ); + } + + @Override + public boolean isEmpty() + { + return !this.iterator().hasNext(); + } + + @Override + public void addStorage( IAEFluidStack option ) + { + if( option == null ) + { + return; + } + + final IAEFluidStack st = this.getFluidRecord( option ); + + if( st != null ) + { + st.incStackSize( option.getStackSize() ); + return; + } + + final IAEFluidStack opt = option.copy(); + + this.putFluidRecord( opt ); + } + + /* + * public synchronized void clean() { Iterator i = iterator(); while (i.hasNext()) { StackType AEI = + * i.next(); if ( !AEI.isMeaningful() ) i.remove(); } } + */ + + @Override + public void addCrafting( IAEFluidStack option ) + { + if( option == null ) + { + return; + } + + final IAEFluidStack st = this.getFluidRecord( option ); + + if( st != null ) + { + st.setCraftable( true ); + return; + } + + final IAEFluidStack opt = option.copy(); + opt.setStackSize( 0 ); + opt.setCraftable( true ); + + this.putFluidRecord( opt ); + } + + @Override + public void addRequestable( IAEFluidStack option ) + { + if( option == null ) + { + return; + } + + final IAEFluidStack st = this.getFluidRecord( option ); + + if( st != null ) + { + st.setCountRequestable( st.getCountRequestable() + option.getCountRequestable() ); + return; + } + + final IAEFluidStack opt = option.copy(); + opt.setStackSize( 0 ); + opt.setCraftable( false ); + opt.setCountRequestable( option.getCountRequestable() ); + + this.putFluidRecord( opt ); + } + + @Override + public IAEFluidStack getFirstItem() + { + for( IAEFluidStack stackType : this ) + { + return stackType; + } + + return null; + } + + @Override + public int size() + { + return this.records.values().size(); + } + + @Override + public Iterator iterator() + { + return new MeaningfulFluidIterator( this.records.values().iterator() ); + } + + @Override + public void resetStatus() + { + for( IAEFluidStack i : this ) + { + i.reset(); + } + } + + private IAEFluidStack getFluidRecord( IAEFluidStack fluid ) + { + return this.records.get( fluid ); + } + + private IAEFluidStack putFluidRecord( IAEFluidStack fluid ) + { + return this.records.put( fluid, fluid ); + } +} diff --git a/src/main/java/appeng/util/item/ItemList.java b/src/main/java/appeng/util/item/ItemList.java index c275e97f..8cea8554 100644 --- a/src/main/java/appeng/util/item/ItemList.java +++ b/src/main/java/appeng/util/item/ItemList.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved. * * Applied Energistics 2 is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -19,126 +19,83 @@ package appeng.util.item; -import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.IdentityHashMap; import java.util.Iterator; import java.util.LinkedList; -import java.util.List; +import java.util.Map; import java.util.NavigableMap; import java.util.concurrent.ConcurrentSkipListMap; -import com.google.common.collect.Lists; - +import net.minecraft.item.Item; import net.minecraftforge.oredict.OreDictionary; import appeng.api.config.FuzzyMode; -import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IAEItemStack; -import appeng.api.storage.data.IAEStack; import appeng.api.storage.data.IItemList; -public final class ItemList implements IItemList +public final class ItemList implements IItemList { - private final NavigableMap records = new ConcurrentSkipListMap(); - private final Class clz; - - // private int currentPriority = Integer.MIN_VALUE; - public Throwable stacktrace; - int iteration = Integer.MIN_VALUE; - - public ItemList( Class cla ) - { - this.clz = cla; - } + private final Map> records = new IdentityHashMap>(); @Override - public synchronized void add( StackType option ) + public void add( IAEItemStack option ) { - if( this.checkStackType( option ) ) + if( option == null ) { return; } - StackType st = this.records.get( option ); + final IAEItemStack st = this.getItemRecord( option.getItem() ).get( option ); if( st != null ) { - // st.setPriority( currentPriority ); st.add( option ); return; } - StackType opt = (StackType) option.copy(); - // opt.setPriority( currentPriority ); - this.records.put( opt, opt ); - } + final IAEItemStack opt = option.copy(); - private boolean checkStackType( StackType st ) - { - if( st == null ) - { - return true; - } - - if( !this.clz.isInstance( st ) ) - { - throw new IllegalArgumentException( "WRONG TYPE - got " + st.getClass().getName() + " expected " + this.clz.getName() ); - } - - return false; + this.putItemRecord( opt ); } @Override - public synchronized StackType findPrecise( StackType i ) + public IAEItemStack findPrecise( IAEItemStack itemStack ) { - if( this.checkStackType( i ) ) + if( itemStack == null ) { return null; } - StackType is = this.records.get( i ); - if( is != null ) - { - return is; - } - - return null; + return this.getItemRecord( itemStack.getItem() ).get( itemStack ); } @Override - public Collection findFuzzy( StackType filter, FuzzyMode fuzzy ) + public Collection findFuzzy( IAEItemStack filter, FuzzyMode fuzzy ) { - if( this.checkStackType( filter ) ) + if( filter == null ) { - return new ArrayList(); + return Collections.emptyList(); } - if( filter instanceof IAEFluidStack ) - { - List result = Lists.newArrayList(); + final AEItemStack ais = (AEItemStack) filter; - if( filter.equals( this ) ) - { - result.add( filter ); - } - - return result; - } - - AEItemStack ais = (AEItemStack) filter; if( ais.isOre() ) { - OreReference or = ais.def.isOre; + final OreReference or = ais.def.isOre; + if( or.getAEEquivalents().size() == 1 ) { - IAEItemStack is = or.getAEEquivalents().get( 0 ); + final IAEItemStack is = or.getAEEquivalents().get( 0 ); + return this.findFuzzyDamage( (AEItemStack) is, fuzzy, is.getItemDamage() == OreDictionary.WILDCARD_VALUE ); } else { - Collection output = new LinkedList(); + final Collection output = new LinkedList(); for( IAEItemStack is : or.getAEEquivalents() ) { @@ -158,123 +115,141 @@ public final class ItemList implements IItemList findFuzzyDamage( AEItemStack filter, FuzzyMode fuzzy, boolean ignoreMeta ) - { - StackType low = (StackType) filter.getLow( fuzzy, ignoreMeta ); - StackType high = (StackType) filter.getHigh( fuzzy, ignoreMeta ); - return this.records.subMap( low, true, high, true ).descendingMap().values(); - } - @Override - public synchronized void addStorage( StackType option ) // adds a stack as - // stored. + public void addStorage( IAEItemStack option ) { - if( this.checkStackType( option ) ) + if( option == null ) { return; } - StackType st = this.records.get( option ); + final IAEItemStack st = this.getItemRecord( option.getItem() ).get( option ); if( st != null ) { - // st.setPriority( currentPriority ); st.incStackSize( option.getStackSize() ); return; } - StackType opt = (StackType) option.copy(); - // opt.setPriority( currentPriority ); - this.records.put( opt, opt ); + final IAEItemStack opt = option.copy(); + + this.putItemRecord( opt ); } /* - * public synchronized void clean() { Iterator i = iterator(); while (i.hasNext()) { StackType AEI = + * public void clean() { Iterator i = iterator(); while (i.hasNext()) { StackType AEI = * i.next(); if ( !AEI.isMeaningful() ) i.remove(); } } */ @Override - public synchronized void addCrafting( StackType option ) // adds a stack as - // craftable. + public void addCrafting( IAEItemStack option ) { - if( this.checkStackType( option ) ) + if( option == null ) { return; } - StackType st = this.records.get( option ); + final IAEItemStack st = this.getItemRecord( option.getItem() ).get( option ); if( st != null ) { - // st.setPriority( currentPriority ); st.setCraftable( true ); return; } - StackType opt = (StackType) option.copy(); - // opt.setPriority( currentPriority ); + final IAEItemStack opt = option.copy(); opt.setStackSize( 0 ); opt.setCraftable( true ); - this.records.put( opt, opt ); + this.putItemRecord( opt ); } @Override - public synchronized void addRequestable( StackType option ) // adds a stack - // as - // requestable. + public void addRequestable( IAEItemStack option ) { - if( this.checkStackType( option ) ) + if( option == null ) { return; } - StackType st = this.records.get( option ); + final IAEItemStack st = this.getItemRecord( option.getItem() ).get( option ); if( st != null ) { - // st.setPriority( currentPriority ); - ( (IAEItemStack) st ).setCountRequestable( st.getCountRequestable() + option.getCountRequestable() ); + st.setCountRequestable( st.getCountRequestable() + option.getCountRequestable() ); return; } - StackType opt = (StackType) option.copy(); - // opt.setPriority( currentPriority ); + final IAEItemStack opt = option.copy(); opt.setStackSize( 0 ); opt.setCraftable( false ); - opt.setCountRequestable( opt.getCountRequestable() ); + opt.setCountRequestable( option.getCountRequestable() ); - this.records.put( opt, opt ); + this.putItemRecord( opt ); } @Override - public synchronized StackType getFirstItem() + public IAEItemStack getFirstItem() { - for( StackType stackType : this ) + for( IAEItemStack stackType : this ) { return stackType; } + return null; } @Override - public synchronized int size() + public int size() { - return this.records.values().size(); + int size = 0; + + for( Map element : this.records.values() ) + { + size += element.size(); + } + + return size; } @Override - public synchronized Iterator iterator() + public Iterator iterator() { - return new MeaningfulIterator( this.records.values().iterator() ); + return new MeaningfulItemIterator( this.records.values().iterator() ); } @Override - public synchronized void resetStatus() + public void resetStatus() { - for( StackType i : this ) + for( IAEItemStack i : this ) { i.reset(); } } + + private NavigableMap getItemRecord( Item item ) + { + NavigableMap itemRecords = this.records.get( item ); + + if( itemRecords == null ) + { + itemRecords = new ConcurrentSkipListMap(); + this.records.put( item, itemRecords ); + } + + return itemRecords; + } + + private IAEItemStack putItemRecord( IAEItemStack itemStack ) + { + return this.getItemRecord( itemStack.getItem() ).put( itemStack, itemStack ); + } + + private Collection findFuzzyDamage( AEItemStack filter, FuzzyMode fuzzy, boolean ignoreMeta ) + { + final IAEItemStack low = filter.getLow( fuzzy, ignoreMeta ); + final IAEItemStack high = filter.getHigh( fuzzy, ignoreMeta ); + + return this.getItemRecord( filter.getItem() ).subMap( low, true, high, true ).descendingMap().values(); + } } diff --git a/src/main/java/appeng/util/item/MeaningfulIterator.java b/src/main/java/appeng/util/item/MeaningfulFluidIterator.java similarity index 75% rename from src/main/java/appeng/util/item/MeaningfulIterator.java rename to src/main/java/appeng/util/item/MeaningfulFluidIterator.java index 3f0597d6..c65ec676 100644 --- a/src/main/java/appeng/util/item/MeaningfulIterator.java +++ b/src/main/java/appeng/util/item/MeaningfulFluidIterator.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved. * * Applied Energistics 2 is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -20,17 +20,18 @@ package appeng.util.item; import java.util.Iterator; +import java.util.NoSuchElementException; import appeng.api.storage.data.IAEStack; -public class MeaningfulIterator implements Iterator +public class MeaningfulFluidIterator implements Iterator { - private final Iterator parent; - private StackType next; + private final Iterator parent; + private T next; - public MeaningfulIterator( Iterator iterator ) + public MeaningfulFluidIterator( Iterator iterator ) { this.parent = iterator; } @@ -51,12 +52,18 @@ public class MeaningfulIterator implements Iterator< } } + this.next = null; return false; } @Override - public StackType next() + public T next() { + if( this.next == null ) + { + throw new NoSuchElementException(); + } + return this.next; } diff --git a/src/main/java/appeng/util/item/MeaningfulItemIterator.java b/src/main/java/appeng/util/item/MeaningfulItemIterator.java new file mode 100644 index 00000000..2becf838 --- /dev/null +++ b/src/main/java/appeng/util/item/MeaningfulItemIterator.java @@ -0,0 +1,96 @@ +/* + * This file is part of Applied Energistics 2. + * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved. + * + * Applied Energistics 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Applied Energistics 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Applied Energistics 2. If not, see . + */ + +package appeng.util.item; + + +import java.util.Iterator; +import java.util.NavigableMap; +import java.util.NoSuchElementException; + +import appeng.api.storage.data.IAEItemStack; + + +public class MeaningfulItemIterator implements Iterator +{ + + private final Iterator> parent; + private Iterator innerIterater = null; + private T next; + + public MeaningfulItemIterator( Iterator> iterator ) + { + this.parent = iterator; + + if( this.parent.hasNext() ) + { + this.innerIterater = this.parent.next().values().iterator(); + } + } + + @Override + public boolean hasNext() + { + if( this.innerIterater == null ) + { + return false; + } + + while( this.innerIterater.hasNext() || this.parent.hasNext() ) + { + if( this.innerIterater.hasNext() ) + { + this.next = this.innerIterater.next(); + + if( this.next.isMeaningful() ) + { + return true; + } + else + { + this.innerIterater.remove(); // self cleaning :3 + } + } + + if( this.parent.hasNext() ) + { + this.innerIterater = this.parent.next().values().iterator(); + } + } + + this.next = null; + return false; + } + + @Override + public T next() + { + if( this.next == null ) + { + throw new NoSuchElementException(); + } + + return this.next; + } + + @Override + public void remove() + { + this.parent.remove(); + } +}