From 3e7ac396eee82da5cf194afb3af9185bd7059fac Mon Sep 17 00:00:00 2001 From: shedaniel Date: Fri, 4 Feb 2022 02:38:27 +0800 Subject: [PATCH] Introduce (Worldly)ContainerTransferHandler and SingleTransferHandler --- .../dev/architectury/fluid/FluidStack.java | 15 +-- .../hooks/item/ItemStackHooks.java | 7 +- .../transfer/TransferHandler.java | 1 + .../wrapper/CombinedFluidTransferHandler.java | 27 +++++ .../fluid/wrapper/FluidVariantView.java | 35 +++++++ .../wrapper/SingleFluidTransferHandler.java | 31 ++++++ .../transfer/item/ItemTransfer.java | 16 +-- .../wrapper/CombinedItemTransferHandler.java | 27 +++++ .../wrapper/ContainerTransferHandler.java | 92 +++++++++++++++++ .../item/wrapper/ItemVariantView.java | 36 +++++++ .../wrapper/SingleItemTransferHandler.java | 36 +++++++ .../WorldlyContainerTransferHandler.java | 51 ++++++++++ .../transfer/view/ExtractableView.java | 26 +++++ .../transfer/view/ModifiableView.java | 26 +++++ .../transfer/view/VariantView.java | 26 +++++ .../CombinedTransferHandler.java | 44 +++++++-- .../FilteringResourceView.java | 11 ++- .../FilteringTransferHandler.java | 9 +- .../ForwardingResourceView.java | 2 +- .../ForwardingTransferHandler.java | 2 +- .../wrapper/single/SingleTransferHandler.java | 99 +++++++++++++++++++ .../item/fabric/ItemTransferImpl.java | 13 --- .../transfer/item/forge/ItemTransferImpl.java | 45 +++------ 23 files changed, 600 insertions(+), 77 deletions(-) create mode 100644 common/src/main/java/dev/architectury/transfer/fluid/wrapper/CombinedFluidTransferHandler.java create mode 100644 common/src/main/java/dev/architectury/transfer/fluid/wrapper/FluidVariantView.java create mode 100644 common/src/main/java/dev/architectury/transfer/fluid/wrapper/SingleFluidTransferHandler.java create mode 100644 common/src/main/java/dev/architectury/transfer/item/wrapper/CombinedItemTransferHandler.java create mode 100644 common/src/main/java/dev/architectury/transfer/item/wrapper/ContainerTransferHandler.java create mode 100644 common/src/main/java/dev/architectury/transfer/item/wrapper/ItemVariantView.java create mode 100644 common/src/main/java/dev/architectury/transfer/item/wrapper/SingleItemTransferHandler.java create mode 100644 common/src/main/java/dev/architectury/transfer/item/wrapper/WorldlyContainerTransferHandler.java create mode 100644 common/src/main/java/dev/architectury/transfer/view/ExtractableView.java create mode 100644 common/src/main/java/dev/architectury/transfer/view/ModifiableView.java create mode 100644 common/src/main/java/dev/architectury/transfer/view/VariantView.java rename common/src/main/java/dev/architectury/transfer/{wrappers => wrapper}/CombinedTransferHandler.java (70%) rename common/src/main/java/dev/architectury/transfer/{wrappers => wrapper}/FilteringResourceView.java (83%) rename common/src/main/java/dev/architectury/transfer/{wrappers => wrapper}/FilteringTransferHandler.java (95%) rename common/src/main/java/dev/architectury/transfer/{wrappers => wrapper}/ForwardingResourceView.java (97%) rename common/src/main/java/dev/architectury/transfer/{wrappers => wrapper}/ForwardingTransferHandler.java (98%) create mode 100644 common/src/main/java/dev/architectury/transfer/wrapper/single/SingleTransferHandler.java diff --git a/common/src/main/java/dev/architectury/fluid/FluidStack.java b/common/src/main/java/dev/architectury/fluid/FluidStack.java index 982eca91..93bc9ab5 100644 --- a/common/src/main/java/dev/architectury/fluid/FluidStack.java +++ b/common/src/main/java/dev/architectury/fluid/FluidStack.java @@ -34,6 +34,7 @@ import net.minecraft.world.level.material.Fluids; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; +import java.util.Objects; import java.util.function.Function; import java.util.function.Supplier; @@ -111,16 +112,16 @@ public final class FluidStack { return FluidStackHooks.bucketAmount(); } - public final Fluid getFluid() { + public Fluid getFluid() { return isEmpty() ? Fluids.EMPTY : getRawFluid(); } @Nullable - public final Fluid getRawFluid() { + public Fluid getRawFluid() { return ADAPTER.getFluid(value); } - public final Supplier getRawFluidSupplier() { + public Supplier getRawFluidSupplier() { return ADAPTER.getRawFluidSupplier(value); } @@ -203,12 +204,12 @@ public final class FluidStack { } @Override - public final int hashCode() { + public int hashCode() { return ADAPTER.hashCode(value); } @Override - public final boolean equals(Object o) { + public boolean equals(Object o) { if (!(o instanceof FluidStack)) { return false; } @@ -223,10 +224,10 @@ public final class FluidStack { return getFluid() == other.getFluid(); } - private boolean isTagEqual(FluidStack other) { + public boolean isTagEqual(FluidStack other) { var tag = getTag(); var otherTag = other.getTag(); - return tag == null ? otherTag == null : otherTag != null && tag.equals(otherTag); + return Objects.equals(tag, otherTag); } public static FluidStack read(FriendlyByteBuf buf) { diff --git a/common/src/main/java/dev/architectury/hooks/item/ItemStackHooks.java b/common/src/main/java/dev/architectury/hooks/item/ItemStackHooks.java index 2e53fb8e..ac170d75 100644 --- a/common/src/main/java/dev/architectury/hooks/item/ItemStackHooks.java +++ b/common/src/main/java/dev/architectury/hooks/item/ItemStackHooks.java @@ -41,7 +41,7 @@ public final class ItemStackHooks { } public static void giveItem(ServerPlayer player, ItemStack stack) { - var inserted = ItemTransfer.wrap(player).insert(stack, TransferAction.ACT); + var inserted = ItemTransfer.container(player.getInventory(), null).insert(stack, TransferAction.ACT); var remaining = stack.getCount() - inserted; if (remaining > 0) { var entity = player.drop(stack, false); @@ -61,4 +61,9 @@ public final class ItemStackHooks { player.inventoryMenu.broadcastChanges(); } } + + public static boolean isStackable(ItemStack first, ItemStack second) { + // TODO check caps? + return ItemStack.matches(first, second); + } } diff --git a/common/src/main/java/dev/architectury/transfer/TransferHandler.java b/common/src/main/java/dev/architectury/transfer/TransferHandler.java index 32552ec9..666544f9 100644 --- a/common/src/main/java/dev/architectury/transfer/TransferHandler.java +++ b/common/src/main/java/dev/architectury/transfer/TransferHandler.java @@ -78,6 +78,7 @@ public interface TransferHandler extends TransferView { * * @param index the index of the resource * @return the resource in the given index + * @throws IndexOutOfBoundsException if the index is out of bounds */ @Deprecated ResourceView getContent(int index); diff --git a/common/src/main/java/dev/architectury/transfer/fluid/wrapper/CombinedFluidTransferHandler.java b/common/src/main/java/dev/architectury/transfer/fluid/wrapper/CombinedFluidTransferHandler.java new file mode 100644 index 00000000..78752232 --- /dev/null +++ b/common/src/main/java/dev/architectury/transfer/fluid/wrapper/CombinedFluidTransferHandler.java @@ -0,0 +1,27 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.transfer.fluid.wrapper; + +import dev.architectury.fluid.FluidStack; +import dev.architectury.transfer.fluid.FluidTransferHandler; +import dev.architectury.transfer.wrapper.CombinedTransferHandler; + +public interface CombinedFluidTransferHandler extends CombinedTransferHandler, FluidTransferHandler, FluidVariantView { +} diff --git a/common/src/main/java/dev/architectury/transfer/fluid/wrapper/FluidVariantView.java b/common/src/main/java/dev/architectury/transfer/fluid/wrapper/FluidVariantView.java new file mode 100644 index 00000000..3bab5297 --- /dev/null +++ b/common/src/main/java/dev/architectury/transfer/fluid/wrapper/FluidVariantView.java @@ -0,0 +1,35 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.transfer.fluid.wrapper; + +import dev.architectury.fluid.FluidStack; +import dev.architectury.transfer.view.VariantView; + +public interface FluidVariantView extends VariantView { + @Override + default long getAmount(FluidStack resource) { + return resource.getAmount(); + } + + @Override + default boolean isSameVariant(FluidStack first, FluidStack second) { + return first.isFluidEqual(second) && first.isTagEqual(second); + } +} diff --git a/common/src/main/java/dev/architectury/transfer/fluid/wrapper/SingleFluidTransferHandler.java b/common/src/main/java/dev/architectury/transfer/fluid/wrapper/SingleFluidTransferHandler.java new file mode 100644 index 00000000..2c3ceb7c --- /dev/null +++ b/common/src/main/java/dev/architectury/transfer/fluid/wrapper/SingleFluidTransferHandler.java @@ -0,0 +1,31 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.transfer.fluid.wrapper; + +import dev.architectury.fluid.FluidStack; +import dev.architectury.transfer.fluid.FluidTransferHandler; +import dev.architectury.transfer.wrapper.single.SingleTransferHandler; + +public interface SingleFluidTransferHandler extends SingleTransferHandler, FluidTransferHandler, FluidVariantView { + @Override + default FluidStack copy(FluidStack resource) { + return resource.copy(); + } +} diff --git a/common/src/main/java/dev/architectury/transfer/item/ItemTransfer.java b/common/src/main/java/dev/architectury/transfer/item/ItemTransfer.java index 46cd2e64..627ec0f6 100644 --- a/common/src/main/java/dev/architectury/transfer/item/ItemTransfer.java +++ b/common/src/main/java/dev/architectury/transfer/item/ItemTransfer.java @@ -22,9 +22,11 @@ package dev.architectury.transfer.item; import dev.architectury.injectables.annotations.ExpectPlatform; import dev.architectury.transfer.TransferHandler; import dev.architectury.transfer.access.BlockLookupAccess; +import dev.architectury.transfer.item.wrapper.ContainerTransferHandler; +import dev.architectury.transfer.item.wrapper.WorldlyContainerTransferHandler; import net.minecraft.core.Direction; import net.minecraft.world.Container; -import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.WorldlyContainer; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; @@ -55,13 +57,11 @@ public class ItemTransfer { throw new AssertionError(); } - @ExpectPlatform public static TransferHandler container(Container container, @Nullable Direction direction) { - throw new AssertionError(); - } - - @ExpectPlatform - public static TransferHandler playerInv(Inventory inventory) { - throw new AssertionError(); + if (container instanceof WorldlyContainer && direction != null) { + return new WorldlyContainerTransferHandler((WorldlyContainer) container, direction); + } + + return new ContainerTransferHandler(container); } } diff --git a/common/src/main/java/dev/architectury/transfer/item/wrapper/CombinedItemTransferHandler.java b/common/src/main/java/dev/architectury/transfer/item/wrapper/CombinedItemTransferHandler.java new file mode 100644 index 00000000..fdec00cf --- /dev/null +++ b/common/src/main/java/dev/architectury/transfer/item/wrapper/CombinedItemTransferHandler.java @@ -0,0 +1,27 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.transfer.item.wrapper; + +import dev.architectury.transfer.item.ItemTransferHandler; +import dev.architectury.transfer.wrapper.CombinedTransferHandler; +import net.minecraft.world.item.ItemStack; + +public interface CombinedItemTransferHandler extends CombinedTransferHandler, ItemTransferHandler, ItemVariantView { +} diff --git a/common/src/main/java/dev/architectury/transfer/item/wrapper/ContainerTransferHandler.java b/common/src/main/java/dev/architectury/transfer/item/wrapper/ContainerTransferHandler.java new file mode 100644 index 00000000..2ed828f8 --- /dev/null +++ b/common/src/main/java/dev/architectury/transfer/item/wrapper/ContainerTransferHandler.java @@ -0,0 +1,92 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.transfer.item.wrapper; + +import dev.architectury.transfer.TransferHandler; +import net.minecraft.world.Container; +import net.minecraft.world.item.ItemStack; + +import java.util.AbstractList; + +public class ContainerTransferHandler implements CombinedItemTransferHandler { + protected final Container container; + private Iterable> handlers = null; + + public ContainerTransferHandler(Container container) { + this.container = container; + } + + protected Iterable> createHandlers() { + return new Handlers(); + } + + @Override + public Iterable> getHandlers() { + if (handlers == null) { + handlers = createHandlers(); + } + + return handlers; + } + + protected class Handlers extends AbstractList> { + @Override + public TransferHandler get(int index) { + if (index < 0 || index >= size()) { + throw new IndexOutOfBoundsException("Index " + index + " is out of bounds for size " + size()); + } + return asTransfer(index); + } + + protected TransferHandler asTransfer(int index) { + return new SlotTransferHandler(container, index); + } + + @Override + public int size() { + return container.getContainerSize(); + } + } + + protected static class SlotTransferHandler implements SingleItemTransferHandler { + protected final Container container; + protected final int index; + + public SlotTransferHandler(Container container, int index) { + this.container = container; + this.index = index; + } + + @Override + public void setResource(ItemStack resource) { + container.setItem(index, resource); + } + + @Override + public ItemStack getResource() { + return container.getItem(index); + } + + @Override + public long getCapacity() { + return Math.min(container.getMaxStackSize(), getResource().getMaxStackSize()); + } + } +} diff --git a/common/src/main/java/dev/architectury/transfer/item/wrapper/ItemVariantView.java b/common/src/main/java/dev/architectury/transfer/item/wrapper/ItemVariantView.java new file mode 100644 index 00000000..405d31d3 --- /dev/null +++ b/common/src/main/java/dev/architectury/transfer/item/wrapper/ItemVariantView.java @@ -0,0 +1,36 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.transfer.item.wrapper; + +import dev.architectury.hooks.item.ItemStackHooks; +import dev.architectury.transfer.view.VariantView; +import net.minecraft.world.item.ItemStack; + +public interface ItemVariantView extends VariantView { + @Override + default long getAmount(ItemStack resource) { + return resource.getCount(); + } + + @Override + default boolean isSameVariant(ItemStack first, ItemStack second) { + return ItemStackHooks.isStackable(first, second); + } +} diff --git a/common/src/main/java/dev/architectury/transfer/item/wrapper/SingleItemTransferHandler.java b/common/src/main/java/dev/architectury/transfer/item/wrapper/SingleItemTransferHandler.java new file mode 100644 index 00000000..07aa2804 --- /dev/null +++ b/common/src/main/java/dev/architectury/transfer/item/wrapper/SingleItemTransferHandler.java @@ -0,0 +1,36 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.transfer.item.wrapper; + +import dev.architectury.transfer.item.ItemTransferHandler; +import dev.architectury.transfer.wrapper.single.SingleTransferHandler; +import net.minecraft.world.item.ItemStack; + +public interface SingleItemTransferHandler extends SingleTransferHandler, ItemTransferHandler, ItemVariantView { + @Override + default ItemStack copy(ItemStack resource) { + return resource.copy(); + } + + @Override + default long getCapacity(ItemStack resource) { + return resource.getMaxStackSize(); + } +} diff --git a/common/src/main/java/dev/architectury/transfer/item/wrapper/WorldlyContainerTransferHandler.java b/common/src/main/java/dev/architectury/transfer/item/wrapper/WorldlyContainerTransferHandler.java new file mode 100644 index 00000000..242872c9 --- /dev/null +++ b/common/src/main/java/dev/architectury/transfer/item/wrapper/WorldlyContainerTransferHandler.java @@ -0,0 +1,51 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.transfer.item.wrapper; + +import dev.architectury.transfer.TransferHandler; +import dev.architectury.transfer.wrapper.FilteringTransferHandler; +import net.minecraft.core.Direction; +import net.minecraft.world.WorldlyContainer; +import net.minecraft.world.item.ItemStack; + +import java.util.Arrays; + +public class WorldlyContainerTransferHandler extends ContainerTransferHandler { + protected final Direction direction; + + public WorldlyContainerTransferHandler(WorldlyContainer container, Direction direction) { + super(container); + this.direction = direction; + } + + @Override + protected Iterable> createHandlers() { + WorldlyContainer container = (WorldlyContainer) this.container; + int[] slots = container.getSlotsForFace(this.direction); + TransferHandler[] handlers = new TransferHandler[slots.length]; + for (int i = 0; i < slots.length; ++i) { + int index = i; + handlers[i] = FilteringTransferHandler.of(new SlotTransferHandler(container, slots[i]), + stack -> container.canPlaceItemThroughFace(index, stack, direction), + stack -> container.canTakeItemThroughFace(index, stack, direction)); + } + return Arrays.asList(handlers); + } +} diff --git a/common/src/main/java/dev/architectury/transfer/view/ExtractableView.java b/common/src/main/java/dev/architectury/transfer/view/ExtractableView.java new file mode 100644 index 00000000..4097e74f --- /dev/null +++ b/common/src/main/java/dev/architectury/transfer/view/ExtractableView.java @@ -0,0 +1,26 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.transfer.view; + +public interface ExtractableView { + default boolean canExtract(T toExtract) { + return true; + } +} diff --git a/common/src/main/java/dev/architectury/transfer/view/ModifiableView.java b/common/src/main/java/dev/architectury/transfer/view/ModifiableView.java new file mode 100644 index 00000000..197a292a --- /dev/null +++ b/common/src/main/java/dev/architectury/transfer/view/ModifiableView.java @@ -0,0 +1,26 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.transfer.view; + +public interface ModifiableView extends ExtractableView { + default boolean canInsert(T toInsert) { + return true; + } +} diff --git a/common/src/main/java/dev/architectury/transfer/view/VariantView.java b/common/src/main/java/dev/architectury/transfer/view/VariantView.java new file mode 100644 index 00000000..af2721a5 --- /dev/null +++ b/common/src/main/java/dev/architectury/transfer/view/VariantView.java @@ -0,0 +1,26 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package dev.architectury.transfer.view; + +public interface VariantView { + long getAmount(T resource); + + boolean isSameVariant(T first, T second); +} diff --git a/common/src/main/java/dev/architectury/transfer/wrappers/CombinedTransferHandler.java b/common/src/main/java/dev/architectury/transfer/wrapper/CombinedTransferHandler.java similarity index 70% rename from common/src/main/java/dev/architectury/transfer/wrappers/CombinedTransferHandler.java rename to common/src/main/java/dev/architectury/transfer/wrapper/CombinedTransferHandler.java index 1c2794d9..ded2059f 100644 --- a/common/src/main/java/dev/architectury/transfer/wrappers/CombinedTransferHandler.java +++ b/common/src/main/java/dev/architectury/transfer/wrapper/CombinedTransferHandler.java @@ -17,18 +17,19 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package dev.architectury.transfer.wrappers; +package dev.architectury.transfer.wrapper; import com.google.common.collect.Streams; import dev.architectury.transfer.ResourceView; import dev.architectury.transfer.TransferAction; import dev.architectury.transfer.TransferHandler; +import dev.architectury.transfer.view.VariantView; import java.util.Collection; import java.util.function.Predicate; import java.util.stream.Stream; -public interface CombinedTransferHandler extends TransferHandler { +public interface CombinedTransferHandler extends TransferHandler, VariantView { Iterable> getHandlers(); @Override @@ -76,18 +77,45 @@ public interface CombinedTransferHandler extends TransferHandler { @Override default T extract(T toExtract, TransferAction action) { - // TODO: Implement - throw new UnsupportedOperationException(); + long toExtractAmount = getAmount(toExtract); + if (toExtractAmount == 0) return blank(); + else if (toExtractAmount <= 0) + throw new IllegalArgumentException("Cannot extract negative amount, got " + toExtractAmount); + long extractedAmount = 0; + + for (TransferHandler part : getHandlers()) { + T extracted = part.extract(copyWithAmount(toExtract, toExtractAmount - extractedAmount), action); + extractedAmount += getAmount(extracted); + if (extractedAmount >= toExtractAmount) break; + } + + return copyWithAmount(toExtract, extractedAmount); } @Override default T extract(Predicate toExtract, long maxAmount, TransferAction action) { - // TODO: Implement - throw new UnsupportedOperationException(); + if (maxAmount == 0) return blank(); + else if (maxAmount <= 0) + throw new IllegalArgumentException("Cannot extract negative amount, got " + maxAmount); + long extractedAmount = 0; + T type = null; + + for (TransferHandler part : getHandlers()) { + T extracted; + + if (type == null) { + extracted = part.extract(toExtract, maxAmount - extractedAmount, action); + } else { + extracted = part.extract(copyWithAmount(type, maxAmount - extractedAmount), action); + } + + extractedAmount += getAmount(extracted); + if (extractedAmount >= maxAmount) break; + } + + return type == null ? blank() : copyWithAmount(type, extractedAmount); } - long getAmount(T resource); - @Override default Object saveState() { Iterable> handlers = getHandlers(); diff --git a/common/src/main/java/dev/architectury/transfer/wrappers/FilteringResourceView.java b/common/src/main/java/dev/architectury/transfer/wrapper/FilteringResourceView.java similarity index 83% rename from common/src/main/java/dev/architectury/transfer/wrappers/FilteringResourceView.java rename to common/src/main/java/dev/architectury/transfer/wrapper/FilteringResourceView.java index 1618a0b8..ac7e0f81 100644 --- a/common/src/main/java/dev/architectury/transfer/wrappers/FilteringResourceView.java +++ b/common/src/main/java/dev/architectury/transfer/wrapper/FilteringResourceView.java @@ -17,14 +17,20 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package dev.architectury.transfer.wrappers; +package dev.architectury.transfer.wrapper; +import com.google.common.base.Predicates; import dev.architectury.transfer.ResourceView; import dev.architectury.transfer.TransferAction; +import dev.architectury.transfer.view.ExtractableView; import java.util.function.Predicate; -public interface FilteringResourceView extends ForwardingResourceView { +public interface FilteringResourceView extends ForwardingResourceView, ExtractableView { + static FilteringResourceView unmodifiable(ResourceView delegate) { + return FilteringResourceView.of(delegate, Predicates.alwaysFalse()); + } + static FilteringResourceView of(ResourceView delegate, Predicate canExtract) { return new FilteringResourceView() { @Override @@ -39,6 +45,7 @@ public interface FilteringResourceView extends ForwardingResourceView { }; } + @Override boolean canExtract(T toExtract); @Override diff --git a/common/src/main/java/dev/architectury/transfer/wrappers/FilteringTransferHandler.java b/common/src/main/java/dev/architectury/transfer/wrapper/FilteringTransferHandler.java similarity index 95% rename from common/src/main/java/dev/architectury/transfer/wrappers/FilteringTransferHandler.java rename to common/src/main/java/dev/architectury/transfer/wrapper/FilteringTransferHandler.java index f1ef9f48..60ba5fca 100644 --- a/common/src/main/java/dev/architectury/transfer/wrappers/FilteringTransferHandler.java +++ b/common/src/main/java/dev/architectury/transfer/wrapper/FilteringTransferHandler.java @@ -17,16 +17,17 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package dev.architectury.transfer.wrappers; +package dev.architectury.transfer.wrapper; import com.google.common.base.Predicates; import dev.architectury.transfer.ResourceView; import dev.architectury.transfer.TransferAction; import dev.architectury.transfer.TransferHandler; +import dev.architectury.transfer.view.ModifiableView; import java.util.function.Predicate; -public interface FilteringTransferHandler extends ForwardingTransferHandler { +public interface FilteringTransferHandler extends ForwardingTransferHandler, ModifiableView { static FilteringTransferHandler unmodifiable(TransferHandler delegate) { return FilteringTransferHandler.of(delegate, Predicates.alwaysFalse(), Predicates.alwaysFalse()); } @@ -58,10 +59,6 @@ public interface FilteringTransferHandler extends ForwardingTransferHandler extends TransferHandler, ResourceView, ModifiableView, VariantView { + @Override + default Stream> getContents() { + return Stream.of(this); + } + + @Override + default int getContentsSize() { + return 1; + } + + @Override + default ResourceView getContent(int index) { + if (index != 0) throw new IndexOutOfBoundsException("Index must be 0, got " + index); + return this; + } + + @Override + default Object saveState() { + return copy(getResource()); + } + + @Override + default void loadState(Object state) { + setResource((T) state); + } + + void setResource(T resource); + + T copy(T resource); + + long getCapacity(T resource); + + @Override + default long insert(T toInsert, TransferAction action) { + T resource = getResource(); + long currentAmount = getAmount(resource); + boolean isEmpty = currentAmount <= 0; + if ((isEmpty || isSameVariant(resource, toInsert)) && canInsert(toInsert)) { + long slotSpace = isEmpty ? getCapacity(toInsert) : getCapacity() - currentAmount; + long inserted = Math.min(slotSpace, getAmount(toInsert)); + + if (inserted > 0) { + if (isEmpty) { + setResource(copyWithAmount(toInsert, inserted)); + } else { + setResource(copyWithAmount(resource, currentAmount + inserted)); + } + } + + return inserted; + } + + return 0; + } + + @Override + default T extract(T toExtract, TransferAction action) { + T resource = getResource(); + if (!isSameVariant(resource, toExtract)) return blank(); + long extracted = Math.min(getAmount(toExtract), getAmount(resource)); + if (extracted > 0) { + setResource(copyWithAmount(resource, getAmount(resource) - extracted)); + + return copyWithAmount(toExtract, extracted); + } + + return blank(); + } +} diff --git a/fabric/src/main/java/dev/architectury/transfer/item/fabric/ItemTransferImpl.java b/fabric/src/main/java/dev/architectury/transfer/item/fabric/ItemTransferImpl.java index 22e5afb8..c26d49ca 100644 --- a/fabric/src/main/java/dev/architectury/transfer/item/fabric/ItemTransferImpl.java +++ b/fabric/src/main/java/dev/architectury/transfer/item/fabric/ItemTransferImpl.java @@ -26,14 +26,9 @@ import dev.architectury.transfer.fabric.FabricBlockLookupRegistration; import dev.architectury.transfer.fabric.FabricStorageTransferHandler; import dev.architectury.transfer.fabric.TransferHandlerStorage; import dev.architectury.transfer.item.ItemTransfer; -import net.fabricmc.fabric.api.transfer.v1.item.InventoryStorage; import net.fabricmc.fabric.api.transfer.v1.item.ItemStorage; import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant; -import net.fabricmc.fabric.api.transfer.v1.item.PlayerInventoryStorage; import net.fabricmc.fabric.api.transfer.v1.storage.Storage; -import net.minecraft.core.Direction; -import net.minecraft.world.Container; -import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; @@ -64,14 +59,6 @@ public class ItemTransferImpl { } } - public static TransferHandler container(Container container, @Nullable Direction direction) { - return wrap(InventoryStorage.of(container, direction)); - } - - public static TransferHandler playerInv(Inventory inventory) { - return wrap(PlayerInventoryStorage.of(inventory)); - } - @Nullable public static Storage unwrap(@Nullable TransferHandler handler) { if (handler == null) return null; diff --git a/forge/src/main/java/dev/architectury/transfer/item/forge/ItemTransferImpl.java b/forge/src/main/java/dev/architectury/transfer/item/forge/ItemTransferImpl.java index fb3c30ea..0b020db7 100644 --- a/forge/src/main/java/dev/architectury/transfer/item/forge/ItemTransferImpl.java +++ b/forge/src/main/java/dev/architectury/transfer/item/forge/ItemTransferImpl.java @@ -30,9 +30,6 @@ import dev.architectury.transfer.item.ItemTransfer; import dev.architectury.transfer.item.ItemTransferHandler; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.world.Container; -import net.minecraft.world.WorldlyContainer; -import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; @@ -41,9 +38,6 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemHandlerHelper; -import net.minecraftforge.items.wrapper.InvWrapper; -import net.minecraftforge.items.wrapper.PlayerInvWrapper; -import net.minecraftforge.items.wrapper.SidedInvWrapper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -64,18 +58,6 @@ public class ItemTransferImpl { } } - public static TransferHandler container(Container container, @Nullable Direction direction) { - if (container instanceof WorldlyContainer) { - return wrap(new SidedInvWrapper((WorldlyContainer) container, direction)); - } else { - return wrap(new InvWrapper(container)); - } - } - - public static TransferHandler playerInv(Inventory inventory) { - return wrap(new PlayerInvWrapper(inventory)); - } - public static void init() { ItemTransfer.BLOCK.addQueryHandler(instantiateBlockLookup()); ItemTransfer.BLOCK.addRegistrationHandler(ForgeBlockLookupRegistration.create(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, @@ -182,43 +164,46 @@ public class ItemTransferImpl { @Override public ItemStack extract(ItemStack toExtract, TransferAction action) { - int toExtractCount = toExtract.getCount(); - int extractedCount = 0; + int toExtractAmount = toExtract.getCount(); + if (toExtractAmount == 0) return ItemStack.EMPTY; + int extractedAmount = 0; for (int i = 0; i < handler.getSlots(); i++) { ItemStack slot = handler.getStackInSlot(i); if (ItemHandlerHelper.canItemStacksStack(toExtract, slot)) { - ItemStack extracted = handler.extractItem(i, toExtractCount - extractedCount, action == TransferAction.SIMULATE); - extractedCount += extracted.getCount(); - if (extractedCount >= toExtractCount) { + ItemStack extracted = handler.extractItem(i, toExtractAmount - extractedAmount, action == TransferAction.SIMULATE); + extractedAmount += extracted.getCount(); + if (extractedAmount >= toExtractAmount) { break; } } } - return copyWithAmount(toExtract, extractedCount); + return copyWithAmount(toExtract, extractedAmount); } @Override public ItemStack extract(Predicate toExtract, long maxAmount, TransferAction action) { ItemStack type = null; - int extractedCount = 0; + int extractedAmount = 0; for (int i = 0; i < handler.getSlots(); i++) { ItemStack slot = handler.getStackInSlot(i); if (type == null ? toExtract.test(slot) : ItemHandlerHelper.canItemStacksStack(type, slot)) { - ItemStack extracted = handler.extractItem(i, (int) (maxAmount - extractedCount), action == TransferAction.SIMULATE); - type = extracted; - extractedCount += extracted.getCount(); - if (extractedCount >= maxAmount) { + ItemStack extracted = handler.extractItem(i, (int) (maxAmount - extractedAmount), action == TransferAction.SIMULATE); + if (type == null && !extracted.isEmpty()) { + type = extracted; + } + extractedAmount += extracted.getCount(); + if (extractedAmount >= maxAmount) { break; } } } - return type == null ? blank() : copyWithAmount(type, extractedCount); + return type == null ? blank() : copyWithAmount(type, extractedAmount); } @Override