backport 0bdc408e950fe787277d1e48be61ebf928127429

This commit is contained in:
Salomão
2021-03-31 20:53:26 -03:00
parent ca7ce33f34
commit 011b3a4b94
12 changed files with 524 additions and 600 deletions
@@ -56,9 +56,6 @@ public enum FuzzyMode {
*/ */
public final float percentage; public final float percentage;
public final float breakPoint;
public final float percentage;
FuzzyMode( final float p ) FuzzyMode( final float p )
{ {
this.percentage = p; this.percentage = p;
@@ -112,4 +112,13 @@ public interface IAEItemStack extends IAEStack<IAEItemStack>
* @return definition stack * @return definition stack
*/ */
ItemStack getDefinition(); ItemStack getDefinition();
/**
* Compare this AE item stack to another item stack, but ignores the amount. It checks the item type, NBT and damage
* values.
*
* @param is An item stack
*/
boolean equals(ItemStack is);
} }
@@ -23,20 +23,17 @@
package appeng.api.storage.data; package appeng.api.storage.data;
import java.io.IOException; import java.io.IOException;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.PacketBuffer;
import appeng.api.config.FuzzyMode; import appeng.api.config.FuzzyMode;
import appeng.api.storage.IStorageChannel; import appeng.api.storage.IStorageChannel;
public interface IAEStack<T extends IAEStack<T>> {
public interface IAEStack<T extends IAEStack<T>>
{
/** /**
* add two stacks together * add two stacks together
@@ -126,7 +123,7 @@ public interface IAEStack<T extends IAEStack<T>>
void decCountRequestable(long i); void decCountRequestable(long i);
/** /**
* write to a NBTTagCompound. * write to a CompoundNBT.
* *
* @param i to be written data * @param i to be written data
*/ */
@@ -149,7 +146,8 @@ public interface IAEStack<T extends IAEStack<T>>
boolean equals(Object obj); boolean equals(Object obj);
/** /**
* Compare the same subtype of {@link IAEStack} with another using a fuzzy comparison. * Compare the same subtype of {@link IAEStack} with another using a fuzzy
* comparison.
* *
* @param other The stack to compare. * @param other The stack to compare.
* @param mode Which {@link FuzzyMode} should be used. * @param mode Which {@link FuzzyMode} should be used.
@@ -182,17 +180,7 @@ public interface IAEStack<T extends IAEStack<T>>
T empty(); T empty();
/** /**
* @return true if the stack is a {@link IAEItemStack} * @return The {@link IStorageChannel} backing this stack.
*/
boolean isItem();
/**
* @return true if the stack is a {@link IAEFluidStack}
*/
boolean isFluid();
/**
* @return ITEM or FLUID
*/ */
IStorageChannel<T> getChannel(); IStorageChannel<T> getChannel();
@@ -32,6 +32,7 @@ import io.netty.buffer.ByteBuf;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
@@ -216,18 +217,6 @@ public final class AEFluidStack extends AEStack<IAEFluidStack> implements IAEFlu
return dup; return dup;
} }
@Override
public boolean isItem()
{
return false;
}
@Override
public boolean isFluid()
{
return true;
}
@Override @Override
public IStorageChannel<IAEFluidStack> getChannel() public IStorageChannel<IAEFluidStack> getChannel()
{ {
@@ -318,17 +307,17 @@ public final class AEFluidStack extends AEStack<IAEFluidStack> implements IAEFlu
} }
@Override @Override
public void writeToPacket( final ByteBuf buffer ) throws IOException public void writeToPacket( final ByteBuf i ) throws IOException
{ {
final byte mask = (byte) ( ( this.getType( this.getStackSize() ) << 2 ) | ( this final byte mask = (byte) ( ( this.getType( this.getStackSize() ) << 2 ) | ( this
.getType( this.getCountRequestable() ) << 4 ) | ( (byte) ( this.isCraftable() ? 1 : 0 ) << 6 ) | ( this.hasTagCompound() ? 1 : 0 ) << 7 ); .getType( this.getCountRequestable() ) << 4 ) | ( (byte) ( this.isCraftable() ? 1 : 0 ) << 6 ) | ( this.hasTagCompound() ? 1 : 0 ) << 7 );
buffer.writeByte( mask ); i.writeByte( mask );
this.writeToStream( buffer ); this.writeToStream( i );
this.putPacketValue( buffer, this.getStackSize() ); this.putPacketValue( i, this.getStackSize() );
this.putPacketValue( buffer, this.getCountRequestable() ); this.putPacketValue( i, this.getCountRequestable() );
} }
private void writeToStream( final ByteBuf buffer ) throws IOException private void writeToStream( final ByteBuf buffer ) throws IOException
@@ -0,0 +1,51 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, 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 <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.util;
import java.util.regex.Pattern;
/**
* Regex wrapper for {@link java.util.UUID}s to not rely on try catch
*/
public final class UUIDMatcher
{
/**
* String which is the regular expression for {@link java.util.UUID}s
*/
private static final String UUID_REGEX = "[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}";
/**
* Pattern which pre-compiles the {@link appeng.util.UUIDMatcher#UUID_REGEX}
*/
private static final Pattern PATTERN = Pattern.compile( UUID_REGEX );
/**
* Checks if a potential {@link java.util.UUID} is an {@link java.util.UUID} by applying a regular expression on it.
*
* @param potential to be checked potential {@link java.util.UUID}
*
* @return true, if the potential {@link java.util.UUID} is indeed an {@link java.util.UUID}
*/
public boolean isUUID( final CharSequence potential )
{
return PATTERN.matcher( potential ).matches();
}
}
+64 -126
View File
@@ -1,6 +1,6 @@
/* /*
* This file is part of Applied Energistics 2. * This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. * Copyright (c) 2013 - 2020, AlgorithmX2, All rights reserved.
* *
* Applied Energistics 2 is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Lesser General Public License as published by
@@ -18,7 +18,6 @@
package appeng.util.item; package appeng.util.item;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
@@ -26,39 +25,33 @@ import java.util.Optional;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import appeng.api.AEApi;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.network.ByteBufUtils; import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemHandlerHelper;
import appeng.api.AEApi;
import appeng.api.config.FuzzyMode; import appeng.api.config.FuzzyMode;
import appeng.api.storage.IStorageChannel; import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEItemStack;
import appeng.util.Platform; import appeng.util.Platform;
public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemStack {
public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemStack private final AESharedItemStack sharedStack;
{
private AESharedItemStack sharedStack;
private Optional<OreReference> oreReference; private Optional<OreReference> oreReference;
@SideOnly( Side.CLIENT ) @SideOnly( Side.CLIENT )
private String displayName; private String displayName;
@SideOnly( Side.CLIENT ) @SideOnly( Side.CLIENT )
private List<String> tooltip; private List<String> tooltip;
@SideOnly( Side.CLIENT )
private ResourceLocation uniqueID;
private AEItemStack( final AEItemStack is ) private AEItemStack(final AEItemStack is) {
{
this.setStackSize(is.getStackSize()); this.setStackSize(is.getStackSize());
this.setCraftable(is.isCraftable()); this.setCraftable(is.isCraftable());
this.setCountRequestable(is.getCountRequestable()); this.setCountRequestable(is.getCountRequestable());
@@ -66,8 +59,7 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
this.oreReference = is.oreReference; this.oreReference = is.oreReference;
} }
private AEItemStack( final AESharedItemStack is, long size ) private AEItemStack(final AESharedItemStack is, long size) {
{
this.sharedStack = is; this.sharedStack = is;
this.setStackSize(size); this.setStackSize(size);
this.setCraftable(false); this.setCraftable(false);
@@ -76,10 +68,8 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
} }
@Nullable @Nullable
public static AEItemStack fromItemStack( @Nonnull final ItemStack stack ) public static AEItemStack fromItemStack(@Nonnull final ItemStack stack) {
{ if (stack.isEmpty()) {
if( stack.isEmpty() )
{
return null; return null;
} }
@@ -149,11 +139,16 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
this.putPacketValue( i, this.getCountRequestable() ); this.putPacketValue( i, this.getCountRequestable() );
} }
/**
* We're assuming that using capNBT here is safe, because {@link #getDefinition()} should have been created by
* {@link ItemStack#copy()}, and then never mutated. Copying an item stack will automatically serialize the
* capabilities of the source stack and initialize the target stacks capNBT field using that tag, which we are then
* reusing here.
*/
@Override @Override
public void add( final IAEItemStack option ) public void add(final IAEItemStack option) {
{ if (option == null) {
if( option == null )
{
return; return;
} }
@@ -163,13 +158,7 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
} }
@Override @Override
public boolean fuzzyComparison( final IAEItemStack other, final FuzzyMode mode ) public boolean fuzzyComparison(final IAEItemStack other, final FuzzyMode mode) {
{
if( mode == FuzzyMode.IGNORE_ALL && OreHelper.INSTANCE.sameOre( this, other ) )
{
return true;
}
final ItemStack itemStack = this.getDefinition(); final ItemStack itemStack = this.getDefinition();
final ItemStack otherStack = other.getDefinition(); final ItemStack otherStack = other.getDefinition();
@@ -177,47 +166,36 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
} }
@Override @Override
public IAEItemStack copy() public IAEItemStack copy() {
{
return new AEItemStack(this); return new AEItemStack(this);
} }
@Override @Override
public boolean isItem() public IStorageChannel<IAEItemStack> getChannel() {
{
return true;
}
@Override
public boolean isFluid()
{
return false;
}
@Override
public IStorageChannel<IAEItemStack> getChannel()
{
return AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class); return AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class);
} }
@Override @Override
public ItemStack createItemStack() public ItemStack createItemStack() {
{ return ItemHandlerHelper.copyStackWithSize(this.getDefinition(),
return ItemHandlerHelper.copyStackWithSize( this.getDefinition(), (int) Math.min( Integer.MAX_VALUE, this.getStackSize() ) ); (int) Math.min(Integer.MAX_VALUE, this.getStackSize()));
} }
@Override @Override
public Item getItem() public Item getItem() {
{
return this.getDefinition().getItem(); return this.getDefinition().getItem();
} }
@Override @Override
public int getItemDamage() public int getItemDamage() {
{
return this.sharedStack.getItemDamage(); return this.sharedStack.getItemDamage();
} }
public Optional<OreReference> getOre()
{
return this.oreReference;
}
@Override @Override
public boolean sameOre( final IAEItemStack is ) public boolean sameOre( final IAEItemStack is )
{ {
@@ -225,10 +203,8 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
} }
@Override @Override
public boolean isSameType( final IAEItemStack otherStack ) public boolean isSameType(final IAEItemStack otherStack) {
{ if (otherStack == null) {
if( otherStack == null )
{
return false; return false;
} }
@@ -236,10 +212,8 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
} }
@Override @Override
public boolean isSameType( final ItemStack otherStack ) public boolean isSameType(final ItemStack otherStack) {
{ if (otherStack.isEmpty()) {
if( otherStack.isEmpty() )
{
return false; return false;
} }
int oldSize = otherStack.getCount(); int oldSize = otherStack.getCount();
@@ -252,122 +226,86 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
} }
@Override @Override
public int hashCode() public int hashCode() {
{
return this.sharedStack.hashCode(); return this.sharedStack.hashCode();
} }
@Override @Override
public boolean equals( final Object ia ) public boolean equals(final Object ia) {
{ if (ia instanceof AEItemStack) {
if( ia instanceof AEItemStack )
{
return this.isSameType((AEItemStack) ia); return this.isSameType((AEItemStack) ia);
} } else if (ia instanceof ItemStack) {
else if( ia instanceof ItemStack ) // this actually breaks the equals contract (being equals to unrelated classes)
{ return equals((ItemStack) ia);
return this.isSameType( (ItemStack) ia );
} }
return false; return false;
} }
@Override @Override
public String toString() public String toString() {
{ return this.getStackSize() + "x" + this.getDefinition().getItem().getRegistryName();
return this.getStackSize() + "x" + this.getDefinition().getItem().getUnlocalizedName() + "@" + this.getDefinition().getItemDamage();
} }
@SideOnly( Side.CLIENT ) @SideOnly( Side.CLIENT )
public List<String> getToolTip() public List<String> getToolTip() {
{ if (this.tooltip == null) {
if( this.tooltip == null )
{
this.tooltip = Platform.getTooltip(this.asItemStackRepresentation()); this.tooltip = Platform.getTooltip(this.asItemStackRepresentation());
} }
return this.tooltip; return this.tooltip;
} }
@SideOnly( Side.CLIENT ) @SideOnly( Side.CLIENT )
public String getDisplayName() public String getDisplayName() {
{ if (this.displayName == null) {
if( this.displayName == null )
{
this.displayName = Platform.getItemDisplayName(this.asItemStackRepresentation()); this.displayName = Platform.getItemDisplayName(this.asItemStackRepresentation());
} }
return this.displayName; return this.displayName;
} }
@SideOnly( Side.CLIENT ) @SideOnly( Side.CLIENT )
public String getModID() public String getModID() {
{ return this.getDefinition().getItem().getRegistryName().getResourceDomain();
if( this.uniqueID == null )
{
this.uniqueID = Item.REGISTRY.getNameForObject( this.getDefinition().getItem() );
}
if( this.uniqueID == null )
{
return "** Null";
}
return this.uniqueID.getResourceDomain() == null ? "** Null" : this.uniqueID.getResourceDomain();
}
public Optional<OreReference> getOre()
{
return this.oreReference;
} }
@Override @Override
public boolean hasTagCompound() public boolean hasTagCompound() {
{
return this.getDefinition().hasTagCompound(); return this.getDefinition().hasTagCompound();
} }
@Override @Override
public ItemStack asItemStackRepresentation() public ItemStack asItemStackRepresentation() {
{
return this.getDefinition().copy(); return this.getDefinition().copy();
} }
@Override @Override
public ItemStack getDefinition() public ItemStack getDefinition() {
{
return this.sharedStack.getDefinition(); return this.sharedStack.getDefinition();
} }
AESharedItemStack getSharedStack() public boolean equals(final ItemStack is) {
{ return this.isSameType(is);
}
AESharedItemStack getSharedStack() {
return this.sharedStack; return this.sharedStack;
} }
private boolean fuzzyItemStackComparison( ItemStack a, ItemStack b, FuzzyMode mode ) private boolean fuzzyItemStackComparison(ItemStack a, ItemStack b, FuzzyMode mode) {
{ if (a.getItem() == b.getItem()) {
if( a.getItem() == b.getItem() ) if (a.getItem().isDamageable()) {
{ if (mode == FuzzyMode.IGNORE_ALL) {
if( a.getItem().isDamageable() )
{
if( mode == FuzzyMode.IGNORE_ALL )
{
return true; return true;
} } else if (mode == FuzzyMode.PERCENT_99) {
else if( mode == FuzzyMode.PERCENT_99 )
{
return (a.getItemDamage() > 1) == (b.getItemDamage() > 1); return (a.getItemDamage() > 1) == (b.getItemDamage() > 1);
} } else {
else final float percentDamageOfA = (float) a.getItemDamage() / a.getMaxDamage();
{ final float percentDamageOfB = (float) b.getItemDamage() / b.getMaxDamage();
final float percentDamageOfA = (float) a.getItemDamage() / (float) a.getMaxDamage();
final float percentDamageOfB = (float) b.getItemDamage() / (float) b.getMaxDamage();
return (percentDamageOfA > mode.breakPoint) == (percentDamageOfB > mode.breakPoint); return (percentDamageOfA > mode.breakPoint) == (percentDamageOfB > mode.breakPoint);
} }
} }
return a.getMetadata() == b.getMetadata();
} }
return false; return false;
} }
} }
@@ -23,7 +23,6 @@
package appeng.util.item; package appeng.util.item;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.WeakHashMap; import java.util.WeakHashMap;
@@ -31,34 +30,14 @@ import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import appeng.util.Platform; public final class AEItemStackRegistry {
private static final WeakHashMap<AESharedItemStack, WeakReference<AESharedItemStack>> REGISTRY = new WeakHashMap<>();
private AEItemStackRegistry() {
public final class AEItemStackRegistry
{
private static final WeakHashMap<AESharedItemStack, WeakReference<AESharedItemStack>> SERVER_REGISTRY = new WeakHashMap<>();
private static final WeakHashMap<AESharedItemStack, WeakReference<AESharedItemStack>> CLIENT_REGISTRY = new WeakHashMap<>();
private AEItemStackRegistry()
{
} }
private static WeakHashMap<AESharedItemStack, WeakReference<AESharedItemStack>> registry() static synchronized AESharedItemStack getRegisteredStack(final @Nonnull ItemStack itemStack) {
{ if (itemStack.isEmpty()) {
if( Platform.isClient() )
{
return CLIENT_REGISTRY;
}
else
{
return SERVER_REGISTRY;
}
}
static synchronized AESharedItemStack getRegisteredStack( final @Nonnull ItemStack itemStack )
{
if( itemStack.isEmpty() )
{
throw new IllegalArgumentException("stack cannot be empty"); throw new IllegalArgumentException("stack cannot be empty");
} }
@@ -66,18 +45,16 @@ public final class AEItemStackRegistry
itemStack.setCount(1); itemStack.setCount(1);
AESharedItemStack search = new AESharedItemStack(itemStack); AESharedItemStack search = new AESharedItemStack(itemStack);
WeakReference<AESharedItemStack> weak = registry().get( search ); WeakReference<AESharedItemStack> weak = REGISTRY.get(search);
AESharedItemStack ret = null; AESharedItemStack ret = null;
if( weak != null ) if (weak != null) {
{
ret = weak.get(); ret = weak.get();
} }
if( ret == null ) if (ret == null) {
{
ret = new AESharedItemStack(itemStack.copy()); ret = new AESharedItemStack(itemStack.copy());
registry().put( ret, new WeakReference<>( ret ) ); REGISTRY.put(ret, new WeakReference<>(ret));
} }
itemStack.setCount(oldStackSize); itemStack.setCount(oldStackSize);
@@ -18,7 +18,6 @@
package appeng.util.item; package appeng.util.item;
import java.util.Objects; import java.util.Objects;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
@@ -33,31 +32,31 @@ final class AESharedItemStack {
private final int itemDamage; private final int itemDamage;
private final int hashCode; private final int hashCode;
private final ItemStack itemStack; public AESharedItemStack(final ItemStack itemStack) {
private final int itemId; this(itemStack, itemStack.getItemDamage());
private final int itemDamage;
private final int hashCode;
public AESharedItemStack( final ItemStack itemStack )
{
this.itemStack = itemStack;
this.itemId = Item.getIdFromItem( itemStack.getItem() );
this.itemDamage = itemStack.getItemDamage();
this.hashCode = this.makeHashCode();
} }
Bounds getBounds( final FuzzyMode fuzzy, final boolean ignoreMeta ) /**
{ * A constructor to explicitly set the damage value and not fetch it from the {@link ItemStack}
return new Bounds( this.itemStack, fuzzy, ignoreMeta ); *
* @param itemStack The {@link ItemStack} to filter
* @param damage The damage of the item
*/
private AESharedItemStack(ItemStack itemStack, int damage) {
this.itemStack = itemStack;
this.itemId = Item.getIdFromItem(itemStack.getItem());
this.itemDamage = damage;
// Ensure this is always called last.
this.hashCode = this.makeHashCode();
} }
ItemStack getDefinition() { ItemStack getDefinition() {
return this.itemStack; return this.itemStack;
} }
int getItemID() int getItemDamage() {
{ return this.itemDamage;
return this.itemId;
} }
@Override @Override
@@ -88,7 +87,7 @@ final class AESharedItemStack {
return Objects.hash( return Objects.hash(
this.itemId, this.itemId,
this.itemDamage, this.itemDamage,
this.itemStack.hasTag() ? this.itemStack.getTag() : 0); this.itemStack.hasTagCompound() ? this.itemStack.getTagCompound() : 0);
} }
} }
+87 -104
View File
@@ -18,19 +18,91 @@
package appeng.util.item; package appeng.util.item;
import appeng.api.storage.data.IAEStack;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import appeng.api.storage.data.IAEStack;
public abstract class AEStack<T extends IAEStack<T>> implements IAEStack<T> {
public abstract class AEStack<StackType extends IAEStack<StackType>> implements IAEStack<StackType>
{
private boolean isCraftable; private boolean isCraftable;
private long stackSize; private long stackSize;
private long countRequestable; private long countRequestable;
@Override
public long getStackSize() {
return this.stackSize;
}
@Override
public T setStackSize(final long ss) {
this.stackSize = ss;
return (T) this;
}
@Override
public long getCountRequestable() {
return this.countRequestable;
}
@Override
public T setCountRequestable(final long countRequestable) {
this.countRequestable = countRequestable;
return (T) this;
}
@Override
public boolean isCraftable() {
return this.isCraftable;
}
@Override
public T setCraftable(final boolean isCraftable) {
this.isCraftable = isCraftable;
return (T) this;
}
@Override
public T reset() {
this.stackSize = 0;
this.setCountRequestable(0);
this.setCraftable(false);
return (T) this;
}
@Override
public T empty() {
final T dup = this.copy();
dup.reset();
return dup;
}
@Override
public boolean isMeaningful() {
return this.stackSize != 0 || this.countRequestable > 0 || this.isCraftable;
}
@Override
public void incStackSize(final long i) {
this.stackSize += i;
}
@Override
public void decStackSize(final long i) {
this.stackSize -= i;
}
@Override
public void incCountRequestable(final long i) {
this.countRequestable += i;
}
@Override
public void decCountRequestable(final long i) {
this.countRequestable -= i;
}
protected abstract boolean hasTagCompound();
protected static long getPacketValue( final byte type, final ByteBuf tag ) protected static long getPacketValue( final byte type, final ByteBuf tag )
{ {
if( type == 0 ) if( type == 0 )
@@ -55,91 +127,24 @@ public abstract class AEStack<StackType extends IAEStack<StackType>> implements
return tag.readLong(); return tag.readLong();
} }
@Override protected void putPacketValue( final ByteBuf tag, final long num )
public long getStackSize()
{ {
return this.stackSize; if( num <= 255 )
{
tag.writeByte( (byte) ( num + Byte.MIN_VALUE ) );
} }
else if( num <= 65535 )
@Override
public StackType setStackSize( final long ss )
{ {
this.stackSize = ss; tag.writeShort( (short) ( num + Short.MIN_VALUE ) );
return (StackType) this;
} }
else if( num <= 4294967295L )
@Override
public long getCountRequestable()
{ {
return this.countRequestable; tag.writeInt( (int) ( num + Integer.MIN_VALUE ) );
} }
else
@Override
public StackType setCountRequestable( final long countRequestable )
{ {
this.countRequestable = countRequestable; tag.writeLong( num );
return (StackType) this;
} }
@Override
public boolean isCraftable()
{
return this.isCraftable;
}
@Override
public StackType setCraftable( final boolean isCraftable )
{
this.isCraftable = isCraftable;
return (StackType) this;
}
@Override
public StackType reset()
{
this.stackSize = 0;
// priority = Integer.MIN_VALUE;
this.setCountRequestable( 0 );
this.setCraftable( false );
return (StackType) this;
}
@Override
public StackType empty()
{
final StackType dup = this.copy();
dup.reset();
return dup;
}
@Override
public boolean isMeaningful()
{
return this.stackSize != 0 || this.countRequestable > 0 || this.isCraftable;
}
@Override
public void incStackSize( final long i )
{
this.stackSize += i;
}
@Override
public void decStackSize( final long i )
{
this.stackSize -= i;
}
@Override
public void incCountRequestable( final long i )
{
this.countRequestable += i;
}
@Override
public void decCountRequestable( final long i )
{
this.countRequestable -= i;
} }
protected byte getType( final long num ) protected byte getType( final long num )
@@ -161,26 +166,4 @@ public abstract class AEStack<StackType extends IAEStack<StackType>> implements
return 3; return 3;
} }
} }
protected abstract boolean hasTagCompound();
protected void putPacketValue( final ByteBuf tag, final long num )
{
if( num <= 255 )
{
tag.writeByte( (byte) ( num + Byte.MIN_VALUE ) );
}
else if( num <= 65535 )
{
tag.writeShort( (short) ( num + Short.MIN_VALUE ) );
}
else if( num <= 4294967295L )
{
tag.writeInt( (int) ( num + Integer.MIN_VALUE ) );
}
else
{
tag.writeLong( num );
}
}
} }
@@ -145,14 +145,14 @@ class FuzzyItemVariantList extends ItemVariantList {
* higher number than the upper bound. * higher number than the upper bound.
*/ */
static ItemDamageBound makeLowerBound(final ItemStack stack, final FuzzyMode fuzzy) { static ItemDamageBound makeLowerBound(final ItemStack stack, final FuzzyMode fuzzy) {
Preconditions.checkState(stack.isDamageable(), "ItemStack#isDamageable() has to be true"); Preconditions.checkState(((stack.getMaxDamage() == 0 && stack.getItemDamage() > 0 ) || stack.isItemStackDamageable()), "ItemStack#isDamageable() has to be true");
int damage; int damage;
if (fuzzy == FuzzyMode.IGNORE_ALL) { if (fuzzy == FuzzyMode.IGNORE_ALL) {
damage = stack.getMaxDamage(); damage = stack.getMaxDamage();
} else { } else {
final int breakpoint = fuzzy.calculateBreakPoint(stack.getMaxDamage()); final int breakpoint = fuzzy.calculateBreakPoint(stack.getMaxDamage());
damage = stack.getDamage() <= breakpoint ? breakpoint : stack.getMaxDamage(); damage = stack.getItemDamage() <= breakpoint ? breakpoint : stack.getMaxDamage();
} }
return new ItemDamageBound(damage); return new ItemDamageBound(damage);
@@ -163,14 +163,14 @@ class FuzzyItemVariantList extends ItemVariantList {
* lower number than the lower bound. It also is exclusive. * lower number than the lower bound. It also is exclusive.
*/ */
static ItemDamageBound makeUpperBound(final ItemStack stack, final FuzzyMode fuzzy) { static ItemDamageBound makeUpperBound(final ItemStack stack, final FuzzyMode fuzzy) {
Preconditions.checkState(stack.isDamageable(), "ItemStack#isDamageable() has to be true"); Preconditions.checkState(((stack.getMaxDamage() == 0 && stack.getItemDamage() > 0 ) || stack.isItemStackDamageable()), "ItemStack#isDamageable() has to be true");
int damage; int damage;
if (fuzzy == FuzzyMode.IGNORE_ALL) { if (fuzzy == FuzzyMode.IGNORE_ALL) {
damage = MIN_DAMAGE_VALUE; damage = MIN_DAMAGE_VALUE;
} else { } else {
final int breakpoint = fuzzy.calculateBreakPoint(stack.getMaxDamage()); final int breakpoint = fuzzy.calculateBreakPoint(stack.getMaxDamage());
damage = stack.getDamage() <= breakpoint ? MIN_DAMAGE_VALUE : breakpoint; damage = stack.getItemDamage() <= breakpoint ? MIN_DAMAGE_VALUE : breakpoint;
} }
return new ItemDamageBound(damage); return new ItemDamageBound(damage);
+28 -33
View File
@@ -1,6 +1,6 @@
/* /*
* This file is part of Applied Energistics 2. * This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved. * Copyright (c) 2013 - 2020, AlgorithmX2, All rights reserved.
* *
* Applied Energistics 2 is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Lesser General Public License as published by
@@ -18,8 +18,6 @@
package appeng.util.item; package appeng.util.item;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.ConcurrentModificationException; import java.util.ConcurrentModificationException;
@@ -27,13 +25,16 @@ import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import net.minecraftforge.oredict.OreDictionary; import net.minecraft.item.Item;
import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import appeng.api.config.FuzzyMode; import appeng.api.config.FuzzyMode;
import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList; import appeng.api.storage.data.IItemList;
import appeng.util.item.AESharedItemStack.Bounds;
public final class ItemList implements IItemList<IAEItemStack> {
private final Reference2ObjectMap<Item, ItemVariantList> records = new Reference2ObjectOpenHashMap<>(); private final Reference2ObjectMap<Item, ItemVariantList> records = new Reference2ObjectOpenHashMap<>();
/** /**
@@ -53,17 +54,19 @@ import appeng.util.item.AESharedItemStack.Bounds;
return record != null ? record.findPrecise(itemStack) : null; return record != null ? record.findPrecise(itemStack) : null;
} }
if( st != null ) @Override
{ public Collection<IAEItemStack> findFuzzy(final IAEItemStack filter, final FuzzyMode fuzzy) {
st.add( option ); if (filter == null) {
return; return Collections.emptyList();
} }
ItemVariantList record = this.records.get(filter.getItem()); ItemVariantList record = this.records.get(filter.getItem());
return record != null ? record.findFuzzy(filter, fuzzy) : Collections.emptyList(); return record != null ? record.findFuzzy(filter, fuzzy) : Collections.emptyList();
} }
this.putItemRecord( opt ); @Override
public boolean isEmpty() {
return !this.iterator().hasNext();
} }
@Override @Override
@@ -74,7 +77,7 @@ import appeng.util.item.AESharedItemStack.Bounds;
return; return;
} }
return this.records.get( ( (AEItemStack) itemStack ).getSharedStack() ); this.getOrCreateRecord(itemStack.getItem()).add(itemStack);
} }
@Override @Override
@@ -85,7 +88,8 @@ import appeng.util.item.AESharedItemStack.Bounds;
return; return;
} }
final AEItemStack ais = (AEItemStack) filter; this.getOrCreateRecord(itemStack.getItem()).addStorage(itemStack);
}
@Override @Override
public void addCrafting(final IAEItemStack itemStack) { public void addCrafting(final IAEItemStack itemStack) {
@@ -95,11 +99,8 @@ import appeng.util.item.AESharedItemStack.Bounds;
return; return;
} }
return this.findFuzzyDamage( is, fuzzy, is.getItemDamage() == OreDictionary.WILDCARD_VALUE ); this.getOrCreateRecord(itemStack.getItem()).addCrafting(itemStack);
} }
else
{
final Collection<IAEItemStack> output = new ArrayList<>();
@Override @Override
public void addRequestable(final IAEItemStack itemStack) { public void addRequestable(final IAEItemStack itemStack) {
@@ -109,23 +110,16 @@ import appeng.util.item.AESharedItemStack.Bounds;
return; return;
} }
return output; this.getOrCreateRecord(itemStack.getItem()).addRequestable(itemStack);
}
} ).orElse( this.findFuzzyDamage( ais, fuzzy, false ) );
} }
@Override @Override
public boolean isEmpty() public IAEItemStack getFirstItem() {
{ for (final IAEItemStack stackType : this) {
return !this.iterator().hasNext(); return stackType;
} }
@Override return null;
public void addStorage( final IAEItemStack option )
{
if( option == null )
{
return;
} }
@Override @Override
@@ -135,10 +129,7 @@ import appeng.util.item.AESharedItemStack.Bounds;
size += entry.size(); size += entry.size();
} }
if( st != null ) return size;
{
st.incStackSize( option.getStackSize() );
return;
} }
@Override @Override
@@ -146,7 +137,11 @@ import appeng.util.item.AESharedItemStack.Bounds;
return new ChainedIterator(this.records.values().iterator(), version); return new ChainedIterator(this.records.values().iterator(), version);
} }
this.putItemRecord( opt ); @Override
public void resetStatus() {
for (final IAEItemStack i : this) {
i.reset();
}
} }
private ItemVariantList getOrCreateRecord(Item item) { private ItemVariantList getOrCreateRecord(Item item) {
@@ -44,10 +44,8 @@ public class MeaningfulItemIterator<T extends IAEItemStack> implements Iterator<
} }
@Override @Override
public T next() public T next() {
{ if (this.next == null) {
if( this.next == null )
{
throw new NoSuchElementException(); throw new NoSuchElementException();
} }