Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
import org.jetbrains.annotations.NotNull;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;

public class FluidStorageFluidHandler implements IFluidHandler {
private final Storage<FluidVariant> storage;
private final Int2ObjectMap<StorageView<FluidVariant>> slots;
Expand Down Expand Up @@ -44,46 +50,71 @@ public int getTankCapacity(int tank) {
public boolean isFluidValid(int tank, @NotNull FluidStack stack) {
return StorageUtil.simulateInsert(storage, NeoCompatUtil.toFluidStorageView(stack), NeoCompatUtil.toFabricBucket(stack.getAmount()), null) > 0;
}

@Override
public int fill(FluidStack resource, FluidAction action) {
try (Transaction transaction = Transaction.openOuter()) {
FluidVariant variant = NeoCompatUtil.toFluidStorageView(resource);
int filled = (int) storage.insert(variant, NeoCompatUtil.toFabricBucket(resource.getAmount()), transaction);
if (action.execute()) {
transaction.commit();
// if a transaction from a fabric context causes a neoforge mod to create a new transaction to a fabric context as part of that first call we need to do so in a new thread
private <T> T executeWithTransactionHandling(Supplier<T> operation, T defaultValue) {
if (Transaction.isOpen()) {
try {
return CompletableFuture.supplyAsync(operation).get(10, TimeUnit.MICROSECONDS);
} catch (InterruptedException | TimeoutException | ExecutionException e) {
return defaultValue;
}
return NeoCompatUtil.toForgeBucket(filled);
} else {
return operation.get();
}
}

@Override
public @NotNull FluidStack drain(FluidStack resource, FluidAction action) {
if (!resource.isEmpty()) {
public int fill(FluidStack resource, @NotNull FluidAction action) {

// because moving blank/empty fluid resources is a thing in neoforge for some reason? (See https://github.com/AztechMC/Modern-Industrialization/issues/1029)
if (resource.isEmpty()) return 0;

return executeWithTransactionHandling(() -> {
try (Transaction transaction = Transaction.openOuter()) {
FluidVariant variant = NeoCompatUtil.toFluidStorageView(resource);
int drained = (int) storage.extract(variant, NeoCompatUtil.toFabricBucket(resource.getAmount()), transaction);
int filled = (int) storage.insert(variant, NeoCompatUtil.toFabricBucket(resource.getAmount()), transaction);
if (action.execute()) {
transaction.commit();
}
return NeoCompatUtil.toForgeFluidStack(variant, drained);
return NeoCompatUtil.toForgeBucket(filled);
}
}
return FluidStack.EMPTY;
}, 0);
}

@Override
public @NotNull FluidStack drain(int maxDrain, FluidAction action) {
for (StorageView<FluidVariant> view : storage.nonEmptyViews()) {
public @NotNull FluidStack drain(FluidStack resource, @NotNull FluidAction action) {

if (resource.isEmpty()) {
return FluidStack.EMPTY;
}

return executeWithTransactionHandling(() -> {
try (Transaction transaction = Transaction.openOuter()) {
FluidVariant resource = view.getResource();
int drained = (int) storage.extract(resource, NeoCompatUtil.toFabricBucket(maxDrain), transaction);
FluidVariant variant = NeoCompatUtil.toFluidStorageView(resource);
int drained = (int) storage.extract(variant, NeoCompatUtil.toFabricBucket(resource.getAmount()), transaction);
if (action.execute()) {
transaction.commit();
}
return NeoCompatUtil.toForgeFluidStack(resource, drained);
return NeoCompatUtil.toForgeFluidStack(variant, drained);
}
}
return FluidStack.EMPTY;
}, FluidStack.EMPTY);
}

@Override
public @NotNull FluidStack drain(int maxDrain, @NotNull FluidAction action) {
return executeWithTransactionHandling(() -> {
for (StorageView<FluidVariant> view : storage.nonEmptyViews()) {
try (Transaction transaction = Transaction.openOuter()) {
FluidVariant resource = view.getResource();
int drained = (int) storage.extract(resource, NeoCompatUtil.toFabricBucket(maxDrain), transaction);
if (action.execute()) {
transaction.commit();
}
return NeoCompatUtil.toForgeFluidStack(resource, drained);
}
}
return FluidStack.EMPTY;
}, FluidStack.EMPTY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public int getSlots() {
public @NotNull ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) {
try (Transaction transaction = Transaction.openOuter()) {
ItemVariant resource = ItemVariant.of(stack);
if (resource.isBlank()) return ItemStack.EMPTY;
int inserted = (int) storage.insert(resource, stack.getCount(), transaction);
if (!simulate) {
transaction.commit();
Expand Down
Loading