From 215d205906434f9030a67c73c0b8fe369eb326ac Mon Sep 17 00:00:00 2001 From: mystchonky Date: Mon, 13 Nov 2023 23:06:20 +0530 Subject: [PATCH] implement FluidHandlers --- .../common/io/fluid/MachineFluidHandler.java | 108 +++++++++-------- .../machines/common/io/fluid/MachineTank.java | 110 ++++++++++++++++++ .../common/io/fluid/MachineTankLayout.java | 12 +- 3 files changed, 181 insertions(+), 49 deletions(-) create mode 100644 src/machines/java/com/enderio/machines/common/io/fluid/MachineTank.java diff --git a/src/machines/java/com/enderio/machines/common/io/fluid/MachineFluidHandler.java b/src/machines/java/com/enderio/machines/common/io/fluid/MachineFluidHandler.java index 01b9cc0f75..3d2e6945c8 100644 --- a/src/machines/java/com/enderio/machines/common/io/fluid/MachineFluidHandler.java +++ b/src/machines/java/com/enderio/machines/common/io/fluid/MachineFluidHandler.java @@ -13,27 +13,41 @@ import java.util.EnumMap; import java.util.List; +import java.util.function.IntConsumer; /** * MachineFluidStorage takes a list of fluid tanks and handles IO for them all. */ public class MachineFluidHandler implements IFluidHandler, IEnderCapabilityProvider { private final IIOConfig config; - - private final List tanks; + private final MachineTankLayout layout; + private final List tanks; private final EnumMap> sideCache = new EnumMap<>(Direction.class); private LazyOptional selfCache = LazyOptional.empty(); - public MachineFluidHandler(IIOConfig config, IFluidTank... tanks) { + // Not sure if we need this but might be useful to update recipe/task if tank is filled. + private IntConsumer changeListener = i -> {}; + + public MachineFluidHandler(IIOConfig config, MachineTankLayout layout) { this.config = config; - this.tanks = List.of(tanks); + this.layout = layout; + this.tanks = layout.createTanks(); + } + + public void addSlotChangedCallback(IntConsumer callback) { + changeListener = changeListener.andThen(callback); } public final IIOConfig getConfig() { return config; } + public MachineTankLayout getLayout() { + return layout; + } + + //Not a good idea to use this method. Tank Access should be the way to access tanks public final IFluidTank getTank(int tank) { return tanks.get(tank); } @@ -58,6 +72,49 @@ public boolean isFluidValid(int tank, FluidStack stack) { return tanks.get(tank).isFluidValid(stack); } + @Override + public Capability getCapabilityType() { + return ForgeCapabilities.FLUID_HANDLER; + } + + @Override + public LazyOptional getCapability(@Nullable Direction side) { + if (side == null) { + // Create own cache if its been invalidated or not created yet. + if (!selfCache.isPresent()) { + selfCache = LazyOptional.of(() -> this); + } + + return selfCache.cast(); + } + + if (!config.getMode(side).canConnect()) { + return LazyOptional.empty(); + } + + return sideCache.computeIfAbsent(side, dir -> LazyOptional.of(() -> new Sided(this, dir))).cast(); + } + + @Override + public void invalidateSide(@Nullable Direction side) { + if (side != null) { + if (sideCache.containsKey(side)) { + sideCache.get(side).invalidate(); + sideCache.remove(side); + } + } else { + selfCache.invalidate(); + } + } + + @Override + public void invalidateCaps() { + for (LazyOptional side : sideCache.values()) { + side.invalidate(); + } + selfCache.invalidate(); + } + @Override public int fill(FluidStack resource, FluidAction action) { // Don't waste any time. @@ -106,49 +163,6 @@ public FluidStack drain(int maxDrain, FluidAction action) { return FluidStack.EMPTY; } - @Override - public Capability getCapabilityType() { - return ForgeCapabilities.FLUID_HANDLER; - } - - @Override - public LazyOptional getCapability(@Nullable Direction side) { - if (side == null) { - // Create own cache if its been invalidated or not created yet. - if (!selfCache.isPresent()) { - selfCache = LazyOptional.of(() -> this); - } - - return selfCache.cast(); - } - - if (!config.getMode(side).canConnect()) { - return LazyOptional.empty(); - } - - return sideCache.computeIfAbsent(side, dir -> LazyOptional.of(() -> new Sided(this, dir))).cast(); - } - - @Override - public void invalidateSide(@Nullable Direction side) { - if (side != null) { - if (sideCache.containsKey(side)) { - sideCache.get(side).invalidate(); - sideCache.remove(side); - } - } else { - selfCache.invalidate(); - } - } - - @Override - public void invalidateCaps() { - for (LazyOptional side : sideCache.values()) { - side.invalidate(); - } - selfCache.invalidate(); - } - // Sided capability access private static class Sided implements IFluidHandler { diff --git a/src/machines/java/com/enderio/machines/common/io/fluid/MachineTank.java b/src/machines/java/com/enderio/machines/common/io/fluid/MachineTank.java new file mode 100644 index 0000000000..24cf522c25 --- /dev/null +++ b/src/machines/java/com/enderio/machines/common/io/fluid/MachineTank.java @@ -0,0 +1,110 @@ +package com.enderio.machines.common.io.fluid; + +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.IFluidHandler; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Predicate; + +//Replace MachineFluidTank +public class MachineTank implements IFluidTank { + + private final int capacity; + private final Predicate validator; + + private boolean canInsert; + + private boolean canExtract; + @NotNull private FluidStack fluid = FluidStack.EMPTY; + + public MachineTank(int capacity, Predicate validator, boolean canInsert, boolean canExtract) { + this.capacity = capacity; + this.validator = validator; + this.canInsert = canInsert; + this.canExtract = canExtract; + } + + @Override + public int getCapacity() { + return capacity; + } + + @Override + public @NotNull FluidStack getFluid() { + return fluid; + } + + @Override + public int getFluidAmount() { + return fluid.getAmount(); + } + + @Override + public boolean isFluidValid(FluidStack stack) { + return validator.test(stack); + } + + public int fill(FluidStack resource, IFluidHandler.FluidAction action) { + if (!canInsert || resource.isEmpty() || !isFluidValid(resource)) { + return 0; + } + if (action.simulate()) { + if (fluid.isEmpty()) { + return Math.min(capacity, resource.getAmount()); + } + if (!fluid.isFluidEqual(resource)) { + return 0; + } + return Math.min(capacity - fluid.getAmount(), resource.getAmount()); + } + if (fluid.isEmpty()) { + fluid = new FluidStack(resource, Math.min(capacity, resource.getAmount())); + onContentsChanged(); + return fluid.getAmount(); + } + if (!fluid.isFluidEqual(resource)) { + return 0; + } + int filled = capacity - fluid.getAmount(); + + if (resource.getAmount() < filled) { + fluid.grow(resource.getAmount()); + filled = resource.getAmount(); + } else { + fluid.setAmount(capacity); + } + if (filled > 0) + onContentsChanged(); + return filled; + } + + @NotNull + @Override + public FluidStack drain(FluidStack resource, IFluidHandler.FluidAction action) { + if (!canExtract || resource.isEmpty() || !resource.isFluidEqual(fluid)) { + return FluidStack.EMPTY; + } + return drain(resource.getAmount(), action); + } + + @NotNull + @Override + public FluidStack drain(int maxDrain, IFluidHandler.FluidAction action) { + int drained = maxDrain; + if (fluid.getAmount() < drained) { + drained = fluid.getAmount(); + } + FluidStack stack = new FluidStack(fluid, drained); + if (action.execute() && drained > 0) { + fluid.shrink(drained); + onContentsChanged(); + } + return stack; + } + + protected void onContentsChanged() { + + } + +} diff --git a/src/machines/java/com/enderio/machines/common/io/fluid/MachineTankLayout.java b/src/machines/java/com/enderio/machines/common/io/fluid/MachineTankLayout.java index 741380ef21..e30792693f 100644 --- a/src/machines/java/com/enderio/machines/common/io/fluid/MachineTankLayout.java +++ b/src/machines/java/com/enderio/machines/common/io/fluid/MachineTankLayout.java @@ -44,11 +44,19 @@ public boolean isFluidValid(int slot, FluidStack stack) { return tanks.get(slot).filter().test(stack); } + public List createTanks() { + List tankList = new ArrayList<>(); + tanks.forEach((config -> { + tankList.add(new MachineTank(config.capacity, config.filter, config.insert, config.extract)); + })); + return tankList; + } + public static class Builder { private final ArrayList tanks = new ArrayList<>(); - public Builder tank(TankAccess access, int capacity, boolean canInsert, boolean canRemove, Predicate filter) { - tanks.add(new TankConfig(capacity, canInsert, canRemove, filter)); + public Builder tank(TankAccess access, int capacity, boolean canInsert, boolean canExtract, Predicate filter) { + tanks.add(new TankConfig(capacity, canInsert, canExtract, filter)); access.init(tanks.size() - 1); return this; }