Files
NotEnoughItems/src/main/java/codechicken/nei/ItemStackMap.java
T

271 lines
8.7 KiB
Java
Raw Normal View History

2014-04-29 10:54:20 +10:00
package codechicken.nei;
2019-12-30 20:19:16 -08:00
import com.google.common.base.Objects;
2014-04-29 10:54:20 +10:00
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
2014-05-02 17:31:05 +10:00
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
2014-04-29 10:54:20 +10:00
import static codechicken.lib.inventory.InventoryUtils.actualDamage;
import static codechicken.lib.inventory.InventoryUtils.newItemStack;
import static net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE;
/**
* A maplike class for ItemStack keys with wildcard damage/NBT. Optimised for lookup
*/
public class ItemStackMap<T>
2014-04-29 10:54:20 +10:00
{
public static class StackMetaKey
{
2019-12-30 20:19:16 -08:00
public final int damage;
public final NBTTagCompound tag;
2014-04-29 10:54:20 +10:00
public StackMetaKey(int damage, NBTTagCompound tag) {
this.damage = damage;
this.tag = tag;
}
public StackMetaKey(ItemStack key) {
this(actualDamage(key), key.stackTagCompound);
}
public int hashCode() {
2014-05-02 17:31:05 +10:00
return Objects.hashCode(damage, tag);
2014-04-29 10:54:20 +10:00
}
public boolean equals(Object o) {
if (!(o instanceof StackMetaKey))
2014-04-29 10:54:20 +10:00
return false;
StackMetaKey t = (StackMetaKey) o;
2014-05-02 17:31:05 +10:00
return damage == t.damage && Objects.equal(tag, t.tag);
2014-04-29 10:54:20 +10:00
}
}
public static class Entry<T>
{
2019-12-30 20:19:16 -08:00
public final ItemStack key;
public final T value;
2014-04-29 10:54:20 +10:00
public Entry(ItemStack key, T value) {
this.key = key;
this.value = value;
}
}
public class DetailMap
{
private boolean hasWildcard;
private T wildcard;
private HashMap<Integer, T> damageMap;
private HashMap<NBTTagCompound, T> tagMap;
private HashMap<StackMetaKey, T> metaMap;
private int size;
2014-04-29 10:54:20 +10:00
public T get(ItemStack key) {
if (wildcard != null)
2014-04-29 10:54:20 +10:00
return wildcard;
if (damageMap != null) {
2019-12-30 20:19:16 -08:00
final T ret = damageMap.get(actualDamage(key));
if (ret != null) return ret;
2014-04-29 10:54:20 +10:00
}
if (tagMap != null) {
2019-12-30 20:19:16 -08:00
final T ret = tagMap.get(key.stackTagCompound);
if (ret != null) return ret;
2014-04-29 10:54:20 +10:00
}
if (metaMap != null)
2014-04-29 10:54:20 +10:00
return metaMap.get(new StackMetaKey(key));
return null;
}
public T put(ItemStack key, T value) {
try {
switch (getKeyType(actualDamage(key), key.stackTagCompound)) {
case 0:
2019-12-30 20:19:16 -08:00
if (metaMap == null) metaMap = new HashMap<>();
return metaMap.put(new StackMetaKey(key), value);
case 1:
2019-12-30 20:19:16 -08:00
if (tagMap == null) tagMap = new HashMap<>();
return tagMap.put(key.stackTagCompound, value);
case 2:
2019-12-30 20:19:16 -08:00
if (damageMap == null) damageMap = new HashMap<>();
return damageMap.put(actualDamage(key), value);
case 3:
T ret = wildcard;
wildcard = value;
hasWildcard = true;
return ret;
}
} finally {
updateSize();
2014-04-29 10:54:20 +10:00
}
return null;
2014-04-29 10:54:20 +10:00
}
public T remove(ItemStack key) {
try {
switch (getKeyType(actualDamage(key), key.stackTagCompound)) {
case 0:
return metaMap != null ? metaMap.remove(new StackMetaKey(key)) : null;
case 1:
return tagMap != null ? tagMap.remove(key.stackTagCompound) : null;
case 2:
return damageMap != null ? damageMap.remove(actualDamage(key)) : null;
case 3:
T ret = wildcard;
wildcard = null;
hasWildcard = false;
return ret;
}
} finally {
updateSize();
2014-04-29 10:54:20 +10:00
}
return null;
}
private void updateSize() {
int newSize = (hasWildcard ? 1 : 0) +
(metaMap != null ? metaMap.size() : 0) +
(tagMap != null ? tagMap.size() : 0) +
(damageMap != null ? damageMap.size() : 0);
if(newSize != size) {
ItemStackMap.this.size += newSize-size;
size = newSize;
}
}
2014-04-29 10:54:20 +10:00
public void addKeys(Item item, List<ItemStack> list) {
if (wildcard != null)
list.add(wildcard(item));
if (damageMap != null)
for (int damage : damageMap.keySet())
2014-04-29 10:54:20 +10:00
list.add(newItemStack(item, 1, damage, WILDCARD_TAG));
if (tagMap != null)
for (NBTTagCompound tag : tagMap.keySet())
2014-04-29 10:54:20 +10:00
list.add(newItemStack(item, 1, WILDCARD_VALUE, tag));
if (metaMap != null)
for (StackMetaKey key : metaMap.keySet())
2014-04-29 10:54:20 +10:00
list.add(newItemStack(item, 1, key.damage, key.tag));
}
2014-05-02 17:31:05 +10:00
public void addValues(List<T> list) {
if (wildcard != null)
2014-04-29 10:54:20 +10:00
list.add(wildcard);
if (damageMap != null)
2014-04-29 10:54:20 +10:00
list.addAll(damageMap.values());
if (tagMap != null)
2014-04-29 10:54:20 +10:00
list.addAll(tagMap.values());
if (metaMap != null)
2014-04-29 10:54:20 +10:00
list.addAll(metaMap.values());
}
2014-05-02 17:31:05 +10:00
public void addEntries(Item item, List<Entry<T>> list) {
if (wildcard != null)
2019-12-30 20:19:16 -08:00
list.add(new Entry<>(newItemStack(item, 1, WILDCARD_VALUE, WILDCARD_TAG), wildcard));
if (damageMap != null)
for (Map.Entry<Integer, T> entry : damageMap.entrySet())
2019-12-30 20:19:16 -08:00
list.add(new Entry<>(newItemStack(item, 1, entry.getKey(), WILDCARD_TAG), entry.getValue()));
if (tagMap != null)
for (Map.Entry<NBTTagCompound, T> entry : tagMap.entrySet())
2019-12-30 20:19:16 -08:00
list.add(new Entry<>(newItemStack(item, 1, WILDCARD_VALUE, entry.getKey()), entry.getValue()));
if (metaMap != null)
for (Map.Entry<StackMetaKey, T> entry : metaMap.entrySet())
2019-12-30 20:19:16 -08:00
list.add(new Entry<>(newItemStack(item, 1, entry.getKey().damage, entry.getKey().tag), entry.getValue()));
2014-04-29 10:54:20 +10:00
}
}
public static int getKeyType(int damage, NBTTagCompound tag) {
int i = 0;
if (isWildcard(damage)) i = 1;
if (isWildcard(tag)) i |= 2;
return i;
}
public static ItemStack wildcard(Item item) {
return newItemStack(item, 1, WILDCARD_VALUE, WILDCARD_TAG);
2014-04-29 10:54:20 +10:00
}
public static boolean isWildcard(int damage) {
return damage == WILDCARD_VALUE;
}
public static boolean isWildcard(NBTTagCompound tag) {
return tag != null && tag.getBoolean("*");
}
2019-12-30 20:19:16 -08:00
public static final NBTTagCompound WILDCARD_TAG;
2014-04-29 10:54:20 +10:00
static {
WILDCARD_TAG = new NBTTagCompound();
WILDCARD_TAG.setBoolean("*", true);
}
2019-12-30 20:19:16 -08:00
private final HashMap<Item, DetailMap> itemMap = new HashMap<>();
private int size;
2014-04-29 10:54:20 +10:00
public T get(ItemStack key) {
2019-12-30 20:19:16 -08:00
if (key == null) return null;
final Item item = key.getItem();
if (item == null) return null;
2014-04-29 10:54:20 +10:00
2019-12-30 20:19:16 -08:00
final DetailMap map = itemMap.get(item);
2014-04-29 10:54:20 +10:00
return map == null ? null : map.get(key);
}
public void put(ItemStack key, T value) {
if (key == null || key.getItem() == null)
2014-04-29 10:54:20 +10:00
return;
DetailMap map = itemMap.get(key.getItem());
if (map == null)
2014-04-29 10:54:20 +10:00
itemMap.put(key.getItem(), map = new DetailMap());
map.put(key, value);
}
public void clear() {
itemMap.clear();
}
public T remove(ItemStack key) {
if (key == null || key.getItem() == null)
return null;
DetailMap map = itemMap.get(key.getItem());
return map == null ? null : map.remove(key);
}
public List<ItemStack> keys() {
2019-12-30 20:19:16 -08:00
LinkedList<ItemStack> list = new LinkedList<>();
for (Map.Entry<Item, DetailMap> entry : itemMap.entrySet())
2014-04-29 10:54:20 +10:00
entry.getValue().addKeys(entry.getKey(), list);
return list;
}
public List<T> values() {
2019-12-30 20:19:16 -08:00
LinkedList<T> list = new LinkedList<>();
for (DetailMap map : itemMap.values())
2014-04-29 10:54:20 +10:00
map.addValues(list);
return list;
}
public List<Entry<T>> entries() {
2019-12-30 20:19:16 -08:00
LinkedList<Entry<T>> list = new LinkedList<>();
for (Map.Entry<Item, DetailMap> entry : itemMap.entrySet())
2014-04-29 10:54:20 +10:00
entry.getValue().addEntries(entry.getKey(), list);
return list;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
2014-04-29 10:54:20 +10:00
}