Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve crafter performanc #418

Merged
merged 3 commits into from
Aug 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.enderio.machines.common.io.item.SingleSlotAccess;
import com.enderio.machines.common.menu.CrafterMenu;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
Expand All @@ -20,6 +21,7 @@
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayDeque;
import java.util.Optional;
Expand All @@ -37,6 +39,7 @@ public class CrafterBlockEntity extends PoweredMachineBlockEntity {
public static final MultiSlotAccess GHOST = new MultiSlotAccess();
public static final SingleSlotAccess PREVIEW = new SingleSlotAccess();

@Nullable
private CraftingRecipe recipe;
private final Queue<ItemStack> outputBuffer = new ArrayDeque<>();

Expand All @@ -55,6 +58,25 @@ public boolean stillValid(Player pPlayer) {

public CrafterBlockEntity(BlockEntityType<?> type, BlockPos worldPosition, BlockState blockState) {
super(EnergyIOMode.Input, ENERGY_CAPACITY, ENERGY_USAGE, type, worldPosition, blockState);
getInventoryNN().addSlotChangedCallback(this::onSlotChanged);
}

private void onSlotChanged(int slot) {
if (GHOST.contains(slot)) {
updateRecipe();
}
}

private void updateRecipe() {
for (int i = 0; i < 9; i++) {
dummyCContainer.setItem(i, GHOST.get(i).getItemStack(this).copy());
}
recipe = getLevel()
.getRecipeManager()
.getRecipeFor(RecipeType.CRAFTING, dummyCContainer, getLevel()).orElse(null);
PREVIEW.setStackInSlot(this, ItemStack.EMPTY);
if (recipe != null)
PREVIEW.setStackInSlot(this, recipe.getResultItem(getLevel().registryAccess()));
}

@Override
Expand Down Expand Up @@ -85,6 +107,19 @@ private boolean acceptSlotInput(int slot, ItemStack stack) {
return ItemStack.isSameItem(this.getInventoryNN().getStackInSlot(slot + 10), stack);
}

@Override
public void onLoad() {
super.onLoad();
updateRecipe();
}

@Override
public void load(CompoundTag pTag) {
super.load(pTag);
if (level != null && !level.isClientSide())
updateRecipe();
}

@Override
public void serverTick() {
tryCraft();
Expand All @@ -94,21 +129,15 @@ public void serverTick() {

@Override
protected boolean isActive() {
// TODO: How to determine active state beyond power.
return canAct() && hasEnergy();
}

private void tryCraft() {
Optional<ItemStack> opt = getRecipeResult();
if (opt.isPresent()) {
ItemStack result = opt.get();
PREVIEW.setStackInSlot(this, result);
getRecipeResult().ifPresent(result -> {
if (shouldActTick() && hasPowerToCraft() && canMergeOutput(result) && outputBuffer.isEmpty()) {
craftItem();
}
} else {
PREVIEW.setStackInSlot(this, ItemStack.EMPTY);
}
});
}

private boolean shouldActTick() {
Expand Down Expand Up @@ -141,12 +170,7 @@ private void processOutputBuffer() {
}

private Optional<ItemStack> getRecipeResult() {
for (int i = 0; i < 9; i++) {
dummyCContainer.setItem(i, GHOST.get(i).getItemStack(this).copy());
}
Optional<CraftingRecipe> opt = getLevel().getRecipeManager().getRecipeFor(RecipeType.CRAFTING, dummyCContainer, getLevel());
if (opt.isPresent()) {
recipe = opt.get();
if (recipe != null) {
return Optional.of(recipe.assemble(dummyCContainer, getLevel().registryAccess()));
}
return Optional.empty();
Expand Down Expand Up @@ -175,7 +199,10 @@ private void craftItem() {
outputBuffer.removeIf(ItemStack::isEmpty);
// consume power
this.energyStorage.consumeEnergy(ENERGY_USAGE_PER_ITEM, false);

//ceck resource reload
if (level.getRecipeManager().byKey(recipe.getId()).orElse(null) != recipe) {
recipe = null;
}
}

private void clearInput() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.jetbrains.annotations.Nullable;

import java.util.EnumMap;
import java.util.function.IntConsumer;

/**
* A machine inventory.
Expand All @@ -24,6 +25,8 @@ public class MachineInventory extends ItemStackHandler implements IEnderCapabili
private final EnumMap<Direction, LazyOptional<Wrapped>> sideCache = new EnumMap<>(Direction.class);
private LazyOptional<Wrapped> selfCache = LazyOptional.empty();

private IntConsumer changeListener = i -> {};

/**
* Create a new machine inventory.
*/
Expand All @@ -32,6 +35,9 @@ public MachineInventory(IIOConfig config, MachineInventoryLayout layout) {
this.config = config;
this.layout = layout;
}
public void addSlotChangedCallback(IntConsumer callback) {
Rover656 marked this conversation as resolved.
Show resolved Hide resolved
changeListener = changeListener.andThen(callback);
}

/**
* Get the IO config for the machine.
Expand Down Expand Up @@ -63,7 +69,7 @@ public Capability<IItemHandler> getCapabilityType() {
}

@Override
public LazyOptional<IItemHandler> getCapability(Direction side) {
public LazyOptional<IItemHandler> getCapability(@Nullable Direction side) {
if (side == null) {
// Create own cache if its been invalidated or not created yet.
if (!selfCache.isPresent())
Expand All @@ -77,7 +83,7 @@ public LazyOptional<IItemHandler> getCapability(Direction side) {
}

@Override
public void invalidateSide(Direction side) {
public void invalidateSide(@Nullable Direction side) {
if (side != null) {
if (sideCache.containsKey(side)) {
sideCache.get(side).invalidate();
Expand All @@ -95,6 +101,31 @@ public void invalidateCaps() {
}
}

@Override
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
boolean wasEmpty = !simulate && getStackInSlot(slot).isEmpty();
ItemStack itemStack = super.insertItem(slot, stack, simulate);
if (wasEmpty && itemStack.getCount() != stack.getCount())
changeListener.accept(slot);
return itemStack;
}

@Override
public ItemStack extractItem(int slot, int amount, boolean simulate) {
ItemStack itemStack = super.extractItem(slot, amount, simulate);
if (!itemStack.isEmpty() && !simulate && getStackInSlot(slot).isEmpty())
changeListener.accept(slot);
return itemStack;
}

@Override
public void setStackInSlot(int slot, ItemStack stack) {
boolean changed = stack.getItem() != getStackInSlot(slot).getItem();
super.setStackInSlot(slot, stack);
if (changed)
this.changeListener.accept(slot);
}

private record Wrapped(MachineInventory master, @Nullable Direction side) implements IItemHandler {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ public List<SingleSlotAccess> getAccesses() {
return accesses;
}

public boolean contains(int slotIndex) {
return slotIndex >= accesses.get(0).getIndex() && slotIndex <= accesses.get(accesses.size() - 1).getIndex();
}

public static MultiSlotAccess wrap(SingleSlotAccess access) {
MultiSlotAccess multi = new MultiSlotAccess();
multi.accesses = List.of(access);
Expand Down