Implement most of it

This commit is contained in:
shedaniel
2021-12-06 15:28:37 +08:00
parent 3e605d90fa
commit fadc321034
32 changed files with 1449 additions and 245 deletions

View File

@@ -20,6 +20,7 @@
package dev.architectury.fluid;
import dev.architectury.hooks.fluid.FluidStackHooks;
import dev.architectury.injectables.annotations.ExpectPlatform;
import dev.architectury.utils.NbtType;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@@ -30,22 +31,56 @@ import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.material.Fluid;
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;
public final class FluidStack {
private static final FluidStack EMPTY = create(Fluids.EMPTY, 0);
private long amount;
@Nullable
private CompoundTag tag;
private Supplier<Fluid> fluid;
private static final FluidStackAdapter ADAPTER = adapt(FluidStack::getValue, FluidStack::new);
private Object value;
private FluidStack(Supplier<Fluid> fluid, long amount, CompoundTag tag) {
this.fluid = Objects.requireNonNull(fluid);
this.amount = amount;
this.tag = tag == null ? null : tag.copy();
this(ADAPTER.create(fluid, amount, tag));
}
private FluidStack(Object value) {
this.value = value;
}
private Object getValue() {
return value;
}
@ExpectPlatform
private static FluidStackAdapter adapt(Function<FluidStack, Object> toValue, Function<Object, FluidStack> fromValue) {
throw new AssertionError();
}
@ApiStatus.Internal
public interface FluidStackAdapter {
Object create(Supplier<Fluid> fluid, long amount, CompoundTag tag);
void check(Object object);
Supplier<Fluid> getRawFluidSupplier(Object object);
Fluid getFluid(Object object);
long getAmount(Object object);
void setAmount(Object object, long amount);
CompoundTag getTag(Object value);
void setTag(Object value, CompoundTag tag);
Object copy(Object value);
int hashCode(Object value);
}
public static FluidStack empty() {
@@ -82,61 +117,66 @@ public final class FluidStack {
@Nullable
public final Fluid getRawFluid() {
return fluid.get();
return ADAPTER.getFluid(value);
}
public final Supplier<Fluid> getRawFluidSupplier() {
return fluid;
return ADAPTER.getRawFluidSupplier(value);
}
public boolean isEmpty() {
return getRawFluid() == Fluids.EMPTY || amount <= 0;
return getRawFluid() == Fluids.EMPTY || ADAPTER.getAmount(value) <= 0;
}
public long getAmount() {
return isEmpty() ? 0 : amount;
return isEmpty() ? 0 : ADAPTER.getAmount(value);
}
public void setAmount(long amount) {
this.amount = amount;
ADAPTER.setAmount(value, amount);
}
public void grow(long amount) {
setAmount(this.amount + amount);
setAmount(getAmount() + amount);
}
public void shrink(long amount) {
setAmount(this.amount - amount);
setAmount(getAmount() - amount);
}
public boolean hasTag() {
return tag != null;
return getTag() != null;
}
@Nullable
public CompoundTag getTag() {
return tag;
return ADAPTER.getTag(value);
}
public void setTag(@Nullable CompoundTag tag) {
this.tag = tag;
ADAPTER.setTag(value, tag);
}
public CompoundTag getOrCreateTag() {
if (tag == null)
setTag(new CompoundTag());
CompoundTag tag = getTag();
if (tag == null) {
tag = new CompoundTag();
setTag(tag);
return tag;
}
return tag;
}
@Nullable
public CompoundTag getChildTag(String childName) {
CompoundTag tag = getTag();
if (tag == null)
return null;
return tag.getCompound(childName);
}
public CompoundTag getOrCreateChildTag(String childName) {
getOrCreateTag();
CompoundTag tag = getOrCreateTag();
var child = tag.getCompound(childName);
if (!tag.contains(childName, Tag.TAG_COMPOUND)) {
tag.put(childName, child);
@@ -145,6 +185,7 @@ public final class FluidStack {
}
public void removeChildTag(String childName) {
CompoundTag tag = getTag();
if (tag != null)
tag.remove(childName);
}
@@ -158,17 +199,12 @@ public final class FluidStack {
}
public FluidStack copy() {
return new FluidStack(fluid, amount, tag);
return new FluidStack(ADAPTER.copy(value));
}
@Override
public final int hashCode() {
var code = 1;
code = 31 * code + getFluid().hashCode();
code = 31 * code + Long.hashCode(amount);
if (tag != null)
code = 31 * code + tag.hashCode();
return code;
return ADAPTER.hashCode(value);
}
@Override
@@ -188,7 +224,9 @@ public final class FluidStack {
}
private boolean isTagEqual(FluidStack other) {
return tag == null ? other.tag == null : other.tag != null && tag.equals(other.tag);
var tag = getTag();
var otherTag = other.getTag();
return tag == null ? otherTag == null : otherTag != null && tag.equals(otherTag);
}
public static FluidStack read(FriendlyByteBuf buf) {
@@ -209,7 +247,7 @@ public final class FluidStack {
public FluidStack copyWithAmount(long amount) {
if (isEmpty()) return this;
return new FluidStack(fluid, amount, tag);
return new FluidStack(getRawFluidSupplier(), amount, getTag());
}
@Environment(EnvType.CLIENT)

View File

@@ -0,0 +1,121 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021 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.impl.transfer.access;
import dev.architectury.transfer.access.BlockLookup;
import dev.architectury.transfer.access.BlockLookupAccess;
import dev.architectury.transfer.access.BlockLookupRegistration;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public class BlockLookupAccessImpl<T, C> implements BlockLookupAccess<T, C> {
private final List<BlockLookup<T, C>> lookups = new ArrayList<>();
private final List<BlockLookupRegistration<T, C>> registrationHandlers = new ArrayList<>();
@Override
public void addQueryHandler(BlockLookup<T, C> handler) {
this.lookups.add(0, handler);
}
@Override
public void addRegistrationHandler(BlockLookupRegistration<T, C> registration) {
this.registrationHandlers.add(0, registration);
}
@Override
@Nullable
public T get(Level level, BlockPos pos, C context) {
for (BlockLookup<T, C> handler : lookups) {
T result = handler.get(level, pos, context);
if (result != null) {
return result;
}
}
return null;
}
@Override
@Nullable
public T get(Level level, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, C context) {
for (BlockLookup<T, C> handler : lookups) {
T result = handler.get(level, pos, state, blockEntity, context);
if (result != null) {
return result;
}
}
return null;
}
@Override
public boolean register(ResourceLocation id, BlockAccessProvider<Function<C, T>, @Nullable BlockEntity> provider) {
for (BlockLookupRegistration<T, C> handler : registrationHandlers) {
if (handler.register(id, provider)) {
return true;
}
}
return false;
}
@Override
public boolean registerForBlocks(ResourceLocation id, BlockAccessProvider<Function<C, T>, @Nullable BlockEntity> provider, Block... blocks) {
for (BlockLookupRegistration<T, C> handler : registrationHandlers) {
if (handler.registerForBlocks(id, provider, blocks)) {
return true;
}
}
return false;
}
@Override
public <B extends BlockEntity> boolean registerForBlockEntities(ResourceLocation id, BlockAccessProvider<Function<C, T>, B> provider, BlockEntityType<B>... blockEntityTypes) {
for (BlockLookupRegistration<T, C> handler : registrationHandlers) {
if (handler.registerForBlockEntities(id, provider, blockEntityTypes)) {
return true;
}
}
return false;
}
@Override
public <B extends BlockEntity> boolean registerForSelf(ResourceLocation id, BlockEntityType<B>... blockEntityTypes) {
for (BlockLookupRegistration<T, C> handler : registrationHandlers) {
if (handler.registerForSelf(id, blockEntityTypes)) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,70 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021 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.impl.transfer.access;
import dev.architectury.transfer.access.ItemLookup;
import dev.architectury.transfer.access.ItemLookupAccess;
import dev.architectury.transfer.access.ItemLookupRegistration;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public class ItemLookupAccessImpl<T, C> implements ItemLookupAccess<T, C> {
private final List<ItemLookup<T, C>> lookups = new ArrayList<>();
private final List<ItemLookupRegistration<T, C>> registrationHandlers = new ArrayList<>();
@Override
public void addQueryHandler(ItemLookup<T, C> handler) {
this.lookups.add(handler);
}
@Override
public void addRegistrationHandler(ItemLookupRegistration<T, C> registration) {
this.registrationHandlers.add(registration);
}
@Override
@Nullable
public T get(ItemStack stack, C context) {
for (ItemLookup<T, C> handler : lookups) {
T result = handler.get(stack, context);
if (result != null) {
return result;
}
}
return null;
}
@Override
public boolean register(ResourceLocation id, ItemAccessProvider<Function<C, T>> provider) {
for (ItemLookupRegistration<T, C> handler : registrationHandlers) {
if (handler.register(id, provider)) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,48 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021 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;
/**
* The base interface for all lookup accesses.
*
* @param <T> the type of the API
* @param <H> the type of the query handler
* @param <R> the type of the registration handler
*/
public interface ApiLookupAccess<T, H, R> {
/**
* Adds a handler for querying the api, this will
* only be called by architectury mods.
* <p>
* For adding interop with platform APIs, use the
* register methods for linking and attaching to fabric's
* api lookup or forge's capability system.
*
* @param handler the query handler to add
*/
void addQueryHandler(H handler);
/**
* Adds a lookup registration.
*
* @param registration the registration handler to add
*/
void addRegistrationHandler(R registration);
}

View File

@@ -69,4 +69,14 @@ class EmptyTransferHandler<T> implements TransferHandler<T> {
public T blank() {
return blank.get();
}
@Override
public Object saveState() {
throw new UnsupportedOperationException();
}
@Override
public void loadState(Object state) {
throw new UnsupportedOperationException();
}
}

View File

@@ -19,13 +19,44 @@
package dev.architectury.transfer;
import java.util.function.Predicate;
/**
* Represents an <b>immutable</b> view of a resource.
*
* @param <T> the type of resource
*/
public interface ResourceView<T> {
public interface ResourceView<T> extends TransferView<T> {
/**
* Returns the resource that this view represents.
* The returned resource is <b>immutable</b>.
*
* @return the resource
*/
T getResource();
/**
* Returns the capacity of this view.
*
* @return the capacity
*/
long getCapacity();
/**
* Returns a copy of a resource with the given amount.
*
* @param resource the resource to copy
* @param amount the amount to copy
* @return the copy
*/
T copyWithAmount(T resource, long amount);
@Override
default T extract(Predicate<T> toExtract, long maxAmount, TransferAction action) {
if (toExtract.test(getResource())) {
return extract(copyWithAmount(getResource(), maxAmount), action);
}
return blank();
}
}

View File

@@ -23,7 +23,6 @@ import dev.architectury.fluid.FluidStack;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
@@ -36,7 +35,7 @@ import java.util.stream.Stream;
* @param <T> the type of resource
*/
@ApiStatus.NonExtendable
public interface TransferHandler<T> {
public interface TransferHandler<T> extends TransferView<T> {
/**
* Returns an empty item transfer handler, which does nothing.
*
@@ -91,29 +90,4 @@ public interface TransferHandler<T> {
* @return the amount that was inserted
*/
long insert(T toInsert, TransferAction action);
/**
* Extracts the given resource from the handler, returning the stack that was extracted.
*
* @param toExtract the resource to extract
* @param action whether to simulate or actually extract the resource
* @return the stack that was extracted
*/
T extract(T toExtract, TransferAction action);
/**
* Extracts the given resource from the handler, returning the stack that was extracted.
*
* @param toExtract the predicates to use to filter the resources to extract
* @param action whether to simulate or actually extract the resource
* @return the stack that was extracted
*/
T extract(Predicate<T> toExtract, long maxAmount, TransferAction action);
/**
* Returns a blank resource.
*
* @return a blank resource
*/
T blank();
}

View File

@@ -0,0 +1,74 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021 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;
import org.jetbrains.annotations.ApiStatus;
import java.util.function.Predicate;
public interface TransferView<T> {
/**
* Extracts the given resource from the handler, returning the stack that was extracted.
*
* @param toExtract the resource to extract
* @param action whether to simulate or actually extract the resource
* @return the stack that was extracted
*/
T extract(T toExtract, TransferAction action);
/**
* Extracts the given resource from the handler, returning the stack that was extracted.
*
* @param toExtract the predicates to use to filter the resources to extract
* @param maxAmount the maximum amount of resources to extract
* @param action whether to simulate or actually extract the resource
* @return the stack that was extracted
*/
T extract(Predicate<T> toExtract, long maxAmount, TransferAction action);
/**
* Returns a blank resource.
*
* @return a blank resource
*/
T blank();
/**
* Returns the saved state of the handler, this method must not be called by the implementation.
* This method is used to provide support for transactions, which is only used if the handler is
* registered with the lookup.
*
* @return the saved state of the handler
* @throws UnsupportedOperationException if the handler is provided by the platform
*/
@ApiStatus.OverrideOnly
Object saveState();
/**
* Loads the saved state of the handler, this method must not be called by the implementation.
* This method is used to provide support for transactions, which is only used if the handler is
* registered with the lookup.
*
* @param state the saved state of the handler
* @throws UnsupportedOperationException if the handler is provided by the platform
*/
@ApiStatus.OverrideOnly
void loadState(Object state);
}

View File

@@ -0,0 +1,54 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021 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.access;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.Nullable;
public interface BlockLookup<T, Context> {
/**
* Queries the api for the given block.
* If you need the block state or block entity, you must query it yourself,
* as this method will not do it for you.
*
* @param level the level
* @param pos the position of the block
* @param context the context
* @return the transfer handler, or null if none was found
*/
@Nullable
T get(Level level, BlockPos pos, Context context);
/**
* Queries the api for the given block.
*
* @param level the level
* @param pos the position of the block
* @param state the state of the block
* @param blockEntity the block entity, or null if none
* @param context the context
* @return the transfer handler, or null if none was found
*/
@Nullable
T get(Level level, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, Context context);
}

View File

@@ -0,0 +1,35 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021 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.access;
import dev.architectury.impl.transfer.access.BlockLookupAccessImpl;
import dev.architectury.transfer.ApiLookupAccess;
/**
* An API lookup for blocks.
*
* @param <T> the type of the API
* @param <Context> the type of the context
*/
public interface BlockLookupAccess<T, Context> extends ApiLookupAccess<T, BlockLookup<T, Context>, BlockLookupRegistration<T, Context>>, BlockLookup<T, Context>, BlockLookupRegistration<T, Context> {
static <T, Context> BlockLookupAccess<T, Context> create() {
return new BlockLookupAccessImpl<>();
}
}

View File

@@ -0,0 +1,55 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021 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.access;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
public interface BlockLookupRegistration<T, Context> {
/**
* Registers a lookup registration handler, this is used to provide
* interop with platform apis.
*
* @param id the id of the lookup registration handler
* @param provider the provider of the lookup registration handler
* @return true if the registration was successful
*/
boolean register(ResourceLocation id, BlockAccessProvider<Function<Context, T>, @Nullable BlockEntity> provider);
boolean registerForBlocks(ResourceLocation id, BlockAccessProvider<Function<Context, T>, @Nullable BlockEntity> provider, Block... blocks);
<B extends BlockEntity> boolean registerForBlockEntities(ResourceLocation id, BlockAccessProvider<Function<Context, T>, B> provider, BlockEntityType<B>... blockEntityTypes);
<B extends BlockEntity> boolean registerForSelf(ResourceLocation id, BlockEntityType<B>... blockEntityTypes);
@FunctionalInterface
interface BlockAccessProvider<R, B extends BlockEntity> {
@Nullable
R get(Level level, BlockPos pos, BlockState state, B blockEntity);
}
}

View File

@@ -19,12 +19,17 @@
package dev.architectury.transfer.access;
import dev.architectury.transfer.TransferAccess;
import dev.architectury.transfer.TransferHandler;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.Nullable;
public interface ItemTransferAccess<T, C> extends TransferAccess<T> {
public interface ItemLookup<T, Context> {
/**
* Queries the api for the given item stack.
*
* @param stack the item stack
* @param context the context
* @return the transfer handler, or null if none was found
*/
@Nullable
T get(ItemStack stack, C context);
}
T get(ItemStack stack, Context context);
}

View File

@@ -17,7 +17,13 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package dev.architectury.transfer;
package dev.architectury.transfer.access;
public interface TransferAccess<T> {
import dev.architectury.impl.transfer.access.ItemLookupAccessImpl;
import dev.architectury.transfer.ApiLookupAccess;
public interface ItemLookupAccess<T, Context> extends ApiLookupAccess<T, ItemLookup<T, Context>, ItemLookupRegistration<T, Context>>, ItemLookup<T, Context>, ItemLookupRegistration<T, Context> {
static <T, Context> ItemLookupAccess<T, Context> create() {
return new ItemLookupAccessImpl<>();
}
}

View File

@@ -19,28 +19,18 @@
package dev.architectury.transfer.access;
import dev.architectury.transfer.TransferAccess;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
public interface BlockTransferAccess<T, C> extends TransferAccess<T> {
@Nullable
T get(Level level, BlockPos pos, C context);
@Nullable
T get(Level level, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, C context);
void register(ResourceLocation id, BlockAccessProvider<T, C> provider);
public interface ItemLookupRegistration<T, Context> {
boolean register(ResourceLocation id, ItemAccessProvider<Function<Context, T>> provider);
@FunctionalInterface
interface BlockAccessProvider<T, C> {
interface ItemAccessProvider<R> {
@Nullable
Function<C, T> get(Level level, BlockPos pos, BlockState state, BlockEntity blockEntity);
R get(ItemStack stack);
}
}

View File

@@ -22,8 +22,8 @@ package dev.architectury.transfer.fluid;
import dev.architectury.fluid.FluidStack;
import dev.architectury.injectables.annotations.ExpectPlatform;
import dev.architectury.transfer.TransferHandler;
import dev.architectury.transfer.access.BlockTransferAccess;
import dev.architectury.transfer.access.ItemTransferAccess;
import dev.architectury.transfer.access.BlockLookupAccess;
import dev.architectury.transfer.access.ItemLookupAccess;
import net.minecraft.core.Direction;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.Nullable;
@@ -32,16 +32,25 @@ public class FluidTransfer {
private FluidTransfer() {
}
public static final BlockTransferAccess<TransferHandler<FluidStack>, Direction> BLOCK = instantiateBlockAccess();
public static final ItemTransferAccess<TransferHandler<FluidStack>, TransferHandler<ItemStack>> ITEM = instantiateItemAccess();
/**
* A lookup access for fluid transfer handlers, the direction context is
* only required on fabric.
* <p>
* This is the equivalent to getting the fluid transfer handler for a
* block entity on Forge, or the storage with the lookup api on Fabric.
* <p>
* There are performance implications for using the architectury lookups,
* please keep your implementations as simple as possible.
*/
public static final BlockLookupAccess<TransferHandler<FluidStack>, Direction> BLOCK = BlockLookupAccess.create();
// public static final ItemLookupAccess<TransferHandler<FluidStack>, TransferHandler<ItemStack>> ITEM = ItemLookupAccess.create();
@ExpectPlatform
private static BlockTransferAccess<TransferHandler<FluidStack>, Direction> instantiateBlockAccess() {
throw new AssertionError();
static {
init();
}
@ExpectPlatform
private static ItemTransferAccess<TransferHandler<FluidStack>, TransferHandler<ItemStack>> instantiateItemAccess() {
private static void init() {
throw new AssertionError();
}

View File

@@ -21,16 +21,20 @@ package dev.architectury.transfer.item;
import dev.architectury.injectables.annotations.ExpectPlatform;
import dev.architectury.transfer.TransferHandler;
import dev.architectury.transfer.access.BlockTransferAccess;
import dev.architectury.transfer.access.BlockLookupAccess;
import net.minecraft.core.Direction;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.Nullable;
public class ItemTransfer {
public static final BlockTransferAccess<TransferHandler<ItemStack>, Direction> BLOCK = instantiateBlockAccess();
public static final BlockLookupAccess<TransferHandler<ItemStack>, Direction> BLOCK = BlockLookupAccess.create();
static {
init();
}
@ExpectPlatform
private static BlockTransferAccess<TransferHandler<ItemStack>, Direction> instantiateBlockAccess() {
private static void init() {
throw new AssertionError();
}