Skip to content

Instantly share code, notes, and snippets.

@Geolykt
Created April 24, 2023 20:20
Show Gist options
  • Save Geolykt/480a40e43e981f7740ea52515770732b to your computer and use it in GitHub Desktop.
Save Geolykt/480a40e43e981f7740ea52515770732b to your computer and use it in GitHub Desktop.
SidedProcessingSlotWrapper attempt
package com.smashingmods.alchemylib.api.storage;
import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import net.minecraft.core.Direction;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.ItemStackHandler;
/**
* A wrapper around a {@link ProcessingSlotHandler} instance that can be used for
* inserting and extracting items at the same time.
*
* <p>However, this implementation is aware of input and output slot restrictions and won't allow
* the insertion of items into output slots as per {@link IItemHandler#insertItem(int, net.minecraft.world.item.ItemStack, boolean)}
* and similarly won't allow the extraction in input slots.
*
* <p>The {@link SlotMode} of each slot, which defines whether a slot is an input or an output slot, has to be defined upfront in the constructor
* and can be changed later on through {@link #setSlotMode(int, SlotMode)}. The amount of slot modes (and as such the amount of slots supported
* by the wrapper) cannot be changed later on. Additionally, the {@link SideMode} of each side can be configured through {@link #setSideMode(Direction, SideMode)}
*
* <p>If direct, unfiltered, access is required {@link #getDelegate()} can be used.
*/
@SuppressWarnings("unused")
public class SidedProcessingSlotWrapper {
private final ProcessingSlotHandler delegate;
private final SideMode[] sideModes = new SideMode[7]; // 4 cardinal directions + up/down + unspecified side = 7 sides total
@SuppressWarnings("unchecked") // Java does not allow creating arrays with generics for some ungodly reason
private final LazyOptional<IItemHandler>[] views = new LazyOptional[7];
private final SlotMode[] slotModes;
private class SidedItemHandlerView implements IItemHandlerModifiable {
private final Direction side;
public SidedItemHandlerView(Direction side) {
this.side = side;
}
@Override
public int getSlots() {
return delegate.getSlots();
}
@Override
public ItemStack getStackInSlot(int slot) {
return delegate.getStackInSlot(slot);
}
@Override
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
if (!getSideMode(side).isPullEnabled() || slotModes[slot] != SlotMode.INPUT) {
return stack;
}
return delegate.insertItem(slot, stack, simulate);
}
@Override
public ItemStack extractItem(int slot, int amount, boolean simulate) {
if (!getSideMode(side).isPushEnabled() || slotModes[slot] != SlotMode.OUTPUT) {
return ItemStack.EMPTY;
}
return delegate.extractItem(slot, amount, simulate);
}
@Override
public int getSlotLimit(int slot) {
return delegate.getSlotLimit(slot);
}
@Override
public boolean isItemValid(int slot, ItemStack stack) {
return delegate.isItemValid(slot, stack);
}
@Override
public void setStackInSlot(int slot, ItemStack stack) {
delegate.setStackInSlot(slot, stack);
}
}
public SidedProcessingSlotWrapper(ProcessingSlotHandler delegate, SlotMode[] slotModes) {
if (slotModes.length != delegate.getSlots()) {
throw new IllegalStateException("The amount of slots in the delegate (" + delegate.getSlots() + ") should correspond to the amount of slot modes (" + slotModes.length + "). However it does not.");
}
for (int i = 0; i < 7; i++) {
this.sideModes[i] = SideMode.DISABLED;
}
this.delegate = delegate;
this.slotModes = slotModes;
}
public LazyOptional<IItemHandler> getViewLazily(@Nullable Direction side) {
LazyOptional<IItemHandler> view = views[side == null ? 6 : side.ordinal()];
if (view == null) {
view = LazyOptional.of(() -> new SidedItemHandlerView(side));
views[side == null ? 6 : side.ordinal()] = view;
}
return view;
}
public void setSideMode(@Nullable Direction side, SideMode mode) {
sideModes[side == null ? 6 : side.ordinal()] = mode;
}
public SideMode getSideMode(@Nullable Direction side) {
return sideModes[side == null ? 6 : side.ordinal()];
}
public void setSlotMode(int slot, SlotMode mode) {
slotModes[slot] = mode;
}
public SlotMode getSlotMode(int slot) {
return slotModes[slot];
}
public ProcessingSlotHandler getDelegate() {
return delegate;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment