Skip to content

Commit

Permalink
Fix #3770 Add an ItemStack cache for creating ItemStack from typed in…
Browse files Browse the repository at this point in the history
…gredients
  • Loading branch information
mezz committed Sep 20, 2024
1 parent 4639a3f commit 4fa7b98
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import mezz.jei.api.ingredients.IIngredientType;
import mezz.jei.api.ingredients.ITypedIngredient;
import mezz.jei.api.runtime.IIngredientManager;
import mezz.jei.library.ingredients.itemStacks.NormalizedTypedItemStack;
import mezz.jei.library.ingredients.itemStacks.TypedItemStack;
import net.minecraft.world.item.ItemStack;
import org.apache.logging.log4j.LogManager;
Expand Down Expand Up @@ -38,7 +37,7 @@ public static <T> ITypedIngredient<T> normalize(ITypedIngredient<T> typedIngredi
if (type == VanillaTypes.ITEM_STACK) {
@SuppressWarnings("unchecked")
ITypedIngredient<ItemStack> cast = (ITypedIngredient<ItemStack>) typedIngredient;
ITypedIngredient<ItemStack> normalized = NormalizedTypedItemStack.normalize(cast);
ITypedIngredient<ItemStack> normalized = TypedItemStack.normalize(cast);
@SuppressWarnings("unchecked")
ITypedIngredient<T> castNormalized = (ITypedIngredient<T>) normalized;
return castNormalized;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package mezz.jei.library.ingredients.itemStacks;

import net.minecraft.core.Holder;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.Nullable;

final class FullTypedItemStack extends TypedItemStack {
private final Holder<Item> itemHolder;
private final @Nullable CompoundTag tag;
private final int count;

public FullTypedItemStack(
Holder<Item> itemHolder,
@Nullable CompoundTag tag,
int count
) {
this.itemHolder = itemHolder;
this.tag = tag;
this.count = count;
}

@Override
protected ItemStack createItemStackUncached() {
ItemStack itemStack = new ItemStack(itemHolder, count);
itemStack.setTag(tag);
return itemStack;
}

@Override
protected TypedItemStack getNormalized() {
return NormalizedTypedItemStack.create(itemHolder, tag);
}

@Override
public String toString() {
return "TypedItemStack{" +
"itemHolder=" + itemHolder +
", tag=" + tag +
", count=" + count +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
package mezz.jei.library.ingredients.itemStacks;

import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.ingredients.IIngredientType;
import mezz.jei.api.ingredients.ITypedIngredient;
import net.minecraft.core.Holder;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;

import java.util.Optional;
final class NormalizedTypedItem extends TypedItemStack {
private final Holder<Item> itemHolder;

record NormalizedTypedItem(Holder<Item> itemHolder) implements ITypedIngredient<ItemStack> {
@Override
public ItemStack getIngredient() {
return new ItemStack(itemHolder);
NormalizedTypedItem(Holder<Item> itemHolder) {
this.itemHolder = itemHolder;
}

@Override
public Optional<ItemStack> getItemStack() {
return Optional.of(getIngredient());
protected ItemStack createItemStackUncached() {
return new ItemStack(itemHolder);
}

@Override
public IIngredientType<ItemStack> getType() {
return VanillaTypes.ITEM_STACK;
public TypedItemStack getNormalized() {
return this;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,61 +1,40 @@
package mezz.jei.library.ingredients.itemStacks;

import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.ingredients.IIngredientType;
import mezz.jei.api.ingredients.ITypedIngredient;
import net.minecraft.core.Holder;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;

import javax.annotation.Nullable;
import java.util.Optional;

public record NormalizedTypedItemStack(
Holder<Item> itemHolder,
CompoundTag tag
) implements ITypedIngredient<ItemStack> {
public static ITypedIngredient<ItemStack> normalize(ITypedIngredient<ItemStack> typedIngredient) {
if (typedIngredient instanceof NormalizedTypedItemStack normalized) {
return normalized;
} else if (typedIngredient instanceof NormalizedTypedItem normalized) {
return normalized;
} else if (typedIngredient instanceof TypedItemStack typedItemStack) {
return create(typedItemStack.itemHolder(), typedItemStack.tag());
}
ItemStack itemStack = typedIngredient.getIngredient();
return create(itemStack.getItemHolder(), itemStack.getTag());
import org.jetbrains.annotations.Nullable;

final class NormalizedTypedItemStack extends TypedItemStack {
private final Holder<Item> itemHolder;
private final CompoundTag tag;

public NormalizedTypedItemStack(
Holder<Item> itemHolder,
CompoundTag tag
) {
this.itemHolder = itemHolder;
this.tag = tag;
}

public static ITypedIngredient<ItemStack> create(Holder<Item> itemHolder, @Nullable CompoundTag tag) {
static TypedItemStack create(Holder<Item> itemHolder, @Nullable CompoundTag tag) {
if (tag == null) {
return new NormalizedTypedItem(itemHolder);
}
return new NormalizedTypedItemStack(itemHolder, tag);
}

public static ITypedIngredient<ItemStack> create(ItemStack itemStack) {
return create(
itemStack.getItemHolder(),
itemStack.getTag()
);
}

@Override
public ItemStack getIngredient() {
public ItemStack createItemStackUncached() {
ItemStack itemStack = new ItemStack(itemHolder, 1);
itemStack.setTag(tag);
return itemStack;
}

@Override
public Optional<ItemStack> getItemStack() {
return Optional.of(getIngredient());
}

@Override
public IIngredientType<ItemStack> getType() {
return VanillaTypes.ITEM_STACK;
public TypedItemStack getNormalized() {
return this;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,57 +1,64 @@
package mezz.jei.library.ingredients.itemStacks;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.ingredients.IIngredientType;
import mezz.jei.api.ingredients.ITypedIngredient;
import net.minecraft.core.Holder;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;

import javax.annotation.Nullable;
import java.time.Duration;
import java.util.Optional;

public record TypedItemStack(
Holder<Item> itemHolder,
@Nullable CompoundTag tag,
int count
) implements ITypedIngredient<ItemStack> {
public abstract class TypedItemStack implements ITypedIngredient<ItemStack> {
private static final LoadingCache<TypedItemStack, ItemStack> CACHE = CacheBuilder.newBuilder()
.expireAfterAccess(Duration.ofSeconds(1))
.build(new CacheLoader<>() {
@Override
public ItemStack load(TypedItemStack key) {
return key.createItemStackUncached();
}
});

public static ITypedIngredient<ItemStack> create(ItemStack ingredient) {
if (ingredient.getCount() == 1) {
return NormalizedTypedItemStack.create(ingredient.getItemHolder(), ingredient.getTag());
return NormalizedTypedItemStack.create(
ingredient.getItemHolder(),
ingredient.getTag()
);
}
return new TypedItemStack(
return new FullTypedItemStack(
ingredient.getItemHolder(),
ingredient.getTag(),
ingredient.getCount()
);
}

@Override
public ItemStack getIngredient() {
ItemStack itemStack = new ItemStack(itemHolder, count);
if (tag != null) {
itemStack.setTag(tag);
public static ITypedIngredient<ItemStack> normalize(ITypedIngredient<ItemStack> typedIngredient) {
if (typedIngredient instanceof TypedItemStack typedItemStack) {
return typedItemStack.getNormalized();
}
return itemStack;
ItemStack itemStack = typedIngredient.getIngredient();
return NormalizedTypedItemStack.create(itemStack.getItemHolder(), itemStack.getTag());
}

@Override
public Optional<ItemStack> getItemStack() {
return Optional.of(getIngredient());
public final ItemStack getIngredient() {
return CACHE.getUnchecked(this);
}

@Override
public IIngredientType<ItemStack> getType() {
return VanillaTypes.ITEM_STACK;
public final Optional<ItemStack> getItemStack() {
return Optional.of(getIngredient());
}

@Override
public String toString() {
return "TypedItemStack{" +
"itemHolder=" + itemHolder +
", tag=" + tag +
", count=" + count +
'}';
public final IIngredientType<ItemStack> getType() {
return VanillaTypes.ITEM_STACK;
}

protected abstract TypedItemStack getNormalized();

protected abstract ItemStack createItemStackUncached();
}

0 comments on commit 4fa7b98

Please sign in to comment.