Skip to content

Commit

Permalink
feat: add cache of last found ingredient spots for massive performanc…
Browse files Browse the repository at this point in the history
…e improvements #676
  • Loading branch information
BlayTheNinth committed Jan 9, 2024
1 parent c3e01fe commit 568fc7c
Show file tree
Hide file tree
Showing 13 changed files with 326 additions and 140 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.blay09.mods.cookingforblockheads;

import net.blay09.mods.cookingforblockheads.api.CacheHint;
import net.blay09.mods.cookingforblockheads.api.IngredientToken;
import net.blay09.mods.cookingforblockheads.api.KitchenItemProvider;
import net.minecraft.world.item.ItemStack;
Expand All @@ -17,7 +18,14 @@ public ItemHandlerKitchenItemProvider(IItemHandler itemHandler) {
}

@Override
public IngredientToken findIngredient(Ingredient ingredient, Collection<IngredientToken> ingredientTokens) {
public IngredientToken findIngredient(Ingredient ingredient, Collection<IngredientToken> ingredientTokens, CacheHint cacheHint) {
if (cacheHint instanceof ItemHandlerIngredientToken itemHandlerIngredientToken) {
final var slotStack = itemHandler.getStackInSlot(itemHandlerIngredientToken.slot);
if (ingredient.test(slotStack) && hasUsesLeft(itemHandlerIngredientToken.slot, slotStack, ingredientTokens)) {
return itemHandlerIngredientToken;
}
}

for (int i = 0; i < itemHandler.getSlots(); i++) {
final var slotStack = itemHandler.getStackInSlot(i);
if (ingredient.test(slotStack) && hasUsesLeft(i, slotStack, ingredientTokens)) {
Expand All @@ -28,7 +36,14 @@ public IngredientToken findIngredient(Ingredient ingredient, Collection<Ingredie
}

@Override
public IngredientToken findIngredient(ItemStack itemStack, Collection<IngredientToken> ingredientTokens) {
public IngredientToken findIngredient(ItemStack itemStack, Collection<IngredientToken> ingredientTokens, CacheHint cacheHint) {
if (cacheHint instanceof ItemHandlerIngredientToken itemHandlerIngredientToken) {
final var slotStack = itemHandler.getStackInSlot(itemHandlerIngredientToken.slot);
if (ItemStack.isSameItemSameTags(slotStack, itemStack) && hasUsesLeft(itemHandlerIngredientToken.slot, slotStack, ingredientTokens)) {
return itemHandlerIngredientToken;
}
}

for (int i = 0; i < itemHandler.getSlots(); i++) {
final var slotStack = itemHandler.getStackInSlot(i);
if (ItemStack.isSameItemSameTags(slotStack, itemStack) && hasUsesLeft(i, slotStack, ingredientTokens)) {
Expand All @@ -51,7 +66,12 @@ private boolean hasUsesLeft(int slot, ItemStack slotStack, Collection<Ingredient
return uses > 0;
}

public class ItemHandlerIngredientToken implements IngredientToken {
@Override
public CacheHint getCacheHint(IngredientToken ingredientToken) {
return ingredientToken instanceof ItemHandlerIngredientToken itemHandlerIngredientToken ? itemHandlerIngredientToken : CacheHint.NONE;
}

public class ItemHandlerIngredientToken implements IngredientToken, CacheHint {
private final int slot;

public ItemHandlerIngredientToken(int slot) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package net.blay09.mods.cookingforblockheads;

import net.blay09.mods.cookingforblockheads.api.CacheHint;
import net.blay09.mods.cookingforblockheads.api.IngredientToken;
import net.blay09.mods.cookingforblockheads.api.KitchenItemProvider;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.neoforged.neoforge.items.IItemHandler;
import net.neoforged.neoforge.items.ItemHandlerHelper;

import java.util.Collection;

public class ItemHandlerKitchenItemProvider implements KitchenItemProvider {
private final IItemHandler itemHandler;

public ItemHandlerKitchenItemProvider(IItemHandler itemHandler) {
this.itemHandler = itemHandler;
}

@Override
public IngredientToken findIngredient(Ingredient ingredient, Collection<IngredientToken> ingredientTokens, CacheHint cacheHint) {
if (cacheHint instanceof ItemHandlerIngredientToken itemHandlerIngredientToken) {
final var slotStack = itemHandler.getStackInSlot(itemHandlerIngredientToken.slot);
if (ingredient.test(slotStack) && hasUsesLeft(itemHandlerIngredientToken.slot, slotStack, ingredientTokens)) {
return itemHandlerIngredientToken;
}
}

for (int i = 0; i < itemHandler.getSlots(); i++) {
final var slotStack = itemHandler.getStackInSlot(i);
if (ingredient.test(slotStack) && hasUsesLeft(i, slotStack, ingredientTokens)) {
return new ItemHandlerIngredientToken(i);
}
}
return null;
}

@Override
public IngredientToken findIngredient(ItemStack itemStack, Collection<IngredientToken> ingredientTokens, CacheHint cacheHint) {
if (cacheHint instanceof ItemHandlerIngredientToken itemHandlerIngredientToken) {
final var slotStack = itemHandler.getStackInSlot(itemHandlerIngredientToken.slot);
if (ItemStack.isSameItemSameTags(slotStack, itemStack) && hasUsesLeft(itemHandlerIngredientToken.slot, slotStack, ingredientTokens)) {
return itemHandlerIngredientToken;
}
}

for (int i = 0; i < itemHandler.getSlots(); i++) {
final var slotStack = itemHandler.getStackInSlot(i);
if (ItemStack.isSameItemSameTags(slotStack, itemStack) && hasUsesLeft(i, slotStack, ingredientTokens)) {
return new ItemHandlerIngredientToken(i);
}
}
return null;
}

private boolean hasUsesLeft(int slot, ItemStack slotStack, Collection<IngredientToken> ingredientTokens) {
var uses = slotStack.getCount();
for (IngredientToken ingredientToken : ingredientTokens) {
if (ingredientToken instanceof ItemHandlerIngredientToken itemHandlerIngredientToken) {
if (itemHandlerIngredientToken.slot == slot) {
uses--;
}
}
}

return uses > 0;
}

@Override
public CacheHint getCacheHint(IngredientToken ingredientToken) {
return ingredientToken instanceof ItemHandlerIngredientToken itemHandlerIngredientToken ? itemHandlerIngredientToken : CacheHint.NONE;
}

public class ItemHandlerIngredientToken implements IngredientToken, CacheHint {
private final int slot;

public ItemHandlerIngredientToken(int slot) {
this.slot = slot;
}

@Override
public ItemStack peek() {
return itemHandler.getStackInSlot(slot);
}

@Override
public ItemStack consume() {
return itemHandler.extractItem(slot, 1, false);
}

@Override
public ItemStack restore(ItemStack itemStack) {
final var restItem = itemHandler.insertItem(slot, itemStack, false);
if (!restItem.isEmpty()) {
return ItemHandlerHelper.insertItemStacked(itemHandler, restItem, false);
}

return ItemStack.EMPTY;
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package net.blay09.mods.cookingforblockheads.api;

public interface CacheHint {
CacheHint NONE = new CacheHint() {
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,20 @@
*/
public interface KitchenItemProvider {
/**
* @param ingredient the ingredient to find
* @param ingredientTokens the ingredient tokens that have already been provided by this provider
* @param ingredient the ingredient to find
* @param ingredientTokens the ingredient tokens that have already been provided for this type of ingredient by this provider
* @param cacheHint a hint on where to start looking, based on {@link #getCacheHint(IngredientToken)} for the last returned token for this type of ingredient
* @return an ingredient token that matches the given ingredient, or null if none was found
*/
IngredientToken findIngredient(Ingredient ingredient, Collection<IngredientToken> ingredientTokens);
IngredientToken findIngredient(Ingredient ingredient, Collection<IngredientToken> ingredientTokens, CacheHint cacheHint);

/**
* @param itemStack the item to find
* @param ingredientTokens the ingredient tokens that have already been provided by this provider
* @param itemStack the item to find
* @param ingredientTokens the ingredient tokens that have already been provided for this type of ingredient by this provider
* @param cacheHint a hint on where to start looking, based on {@link #getCacheHint(IngredientToken)} for the last returned token for this type of ingredient
* @return an ingredient token that matches the given ingredient, or null if none was found
*/
IngredientToken findIngredient(ItemStack itemStack, Collection<IngredientToken> ingredientTokens);
IngredientToken findIngredient(ItemStack itemStack, Collection<IngredientToken> ingredientTokens, CacheHint cacheHint);

CacheHint getCacheHint(IngredientToken ingredientToken);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import net.blay09.mods.balm.api.menu.BalmMenuProvider;
import net.blay09.mods.balm.api.provider.BalmProvider;
import net.blay09.mods.balm.common.BalmBlockEntity;
import net.blay09.mods.cookingforblockheads.api.CacheHint;
import net.blay09.mods.cookingforblockheads.api.IngredientToken;
import net.blay09.mods.cookingforblockheads.api.KitchenItemProcessor;
import net.blay09.mods.cookingforblockheads.api.KitchenItemProvider;
Expand Down Expand Up @@ -70,7 +71,7 @@ public ItemStack restore(ItemStack itemStack) {
private final Set<ItemStack> providedItems = Set.of(new ItemStack(Items.SNOWBALL), new ItemStack(Items.SNOW_BLOCK), new ItemStack(Items.ICE));

@Override
public IngredientToken findIngredient(Ingredient ingredient, Collection<IngredientToken> ingredientTokens) {
public IngredientToken findIngredient(Ingredient ingredient, Collection<IngredientToken> ingredientTokens, CacheHint cacheHint) {
for (final var providedItem : providedItems) {
if (ingredient.test(providedItem)) {
return new IceUnitIngredientToken(providedItem);
Expand All @@ -80,14 +81,19 @@ public IngredientToken findIngredient(Ingredient ingredient, Collection<Ingredie
}

@Override
public IngredientToken findIngredient(ItemStack itemStack, Collection<IngredientToken> ingredientTokens) {
public IngredientToken findIngredient(ItemStack itemStack, Collection<IngredientToken> ingredientTokens, CacheHint cacheHint) {
for (final var providedItem : providedItems) {
if (ItemStack.isSameItem(providedItem, itemStack)) {
return new IceUnitIngredientToken(providedItem);
}
}
return null;
}

@Override
public CacheHint getCacheHint(IngredientToken ingredientToken) {
return CacheHint.NONE;
}
};

private final ContainerKitchenItemProvider conservingItemProvider = new ContainerKitchenItemProvider(container) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import net.blay09.mods.balm.api.fluid.FluidTank;
import net.blay09.mods.balm.api.provider.BalmProvider;
import net.blay09.mods.balm.common.BalmBlockEntity;
import net.blay09.mods.cookingforblockheads.api.CacheHint;
import net.blay09.mods.cookingforblockheads.api.IngredientToken;
import net.blay09.mods.cookingforblockheads.api.KitchenItemProvider;
import net.blay09.mods.cookingforblockheads.compat.Compat;
Expand Down Expand Up @@ -46,9 +47,9 @@ public ItemStack restore(ItemStack itemStack) {

private record MilkJarItemProvider(MilkJarBlockEntity milkJar) implements KitchenItemProvider {
@Override
public IngredientToken findIngredient(Ingredient ingredient, Collection<IngredientToken> ingredientTokens) {
public IngredientToken findIngredient(Ingredient ingredient, Collection<IngredientToken> ingredientTokens, CacheHint cacheHint) {
for (final var itemStack : ingredient.getItems()) {
final var found = findIngredient(itemStack, ingredientTokens);
final var found = findIngredient(itemStack, ingredientTokens, cacheHint);
if (found != null) {
return found;
}
Expand All @@ -58,7 +59,7 @@ public IngredientToken findIngredient(Ingredient ingredient, Collection<Ingredie
}

@Override
public IngredientToken findIngredient(ItemStack itemStack, Collection<IngredientToken> ingredientTokens) {
public IngredientToken findIngredient(ItemStack itemStack, Collection<IngredientToken> ingredientTokens, CacheHint cacheHint) {
if (!itemStack.is(ModItemTags.MILK)) {
return null;
}
Expand All @@ -71,6 +72,11 @@ public IngredientToken findIngredient(ItemStack itemStack, Collection<Ingredient
return null;
}
}

@Override
public CacheHint getCacheHint(IngredientToken ingredientToken) {
return CacheHint.NONE;
}
}

private final MilkJarItemProvider itemProvider = new MilkJarItemProvider(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.blay09.mods.balm.api.provider.BalmProvider;
import net.blay09.mods.balm.common.BalmBlockEntity;
import net.blay09.mods.cookingforblockheads.CookingForBlockheadsConfig;
import net.blay09.mods.cookingforblockheads.api.CacheHint;
import net.blay09.mods.cookingforblockheads.api.IngredientToken;
import net.blay09.mods.cookingforblockheads.api.KitchenItemProvider;
import net.blay09.mods.cookingforblockheads.compat.Compat;
Expand Down Expand Up @@ -49,9 +50,9 @@ public ItemStack restore(ItemStack itemStack) {

private record SinkItemProvider(SinkBlockEntity sink) implements KitchenItemProvider {
@Override
public IngredientToken findIngredient(Ingredient ingredient, Collection<IngredientToken> ingredientTokens) {
public IngredientToken findIngredient(Ingredient ingredient, Collection<IngredientToken> ingredientTokens, CacheHint cacheHint) {
for (final var itemStack : ingredient.getItems()) {
final var found = findIngredient(itemStack, ingredientTokens);
final var found = findIngredient(itemStack, ingredientTokens, cacheHint);
if (found != null) {
return found;
}
Expand All @@ -61,7 +62,7 @@ public IngredientToken findIngredient(Ingredient ingredient, Collection<Ingredie
}

@Override
public IngredientToken findIngredient(ItemStack itemStack, Collection<IngredientToken> ingredientTokens) {
public IngredientToken findIngredient(ItemStack itemStack, Collection<IngredientToken> ingredientTokens, CacheHint cacheHint) {
if (!itemStack.is(ModItemTags.WATER)) {
return null;
}
Expand All @@ -74,6 +75,11 @@ public IngredientToken findIngredient(ItemStack itemStack, Collection<Ingredient
return null;
}
}

@Override
public CacheHint getCacheHint(IngredientToken ingredientToken) {
return CacheHint.NONE;
}
}

private final FluidTank sinkTank = new FluidTank(16000) {
Expand Down
Loading

0 comments on commit 568fc7c

Please sign in to comment.