User Tools

Site Tools


tutorial:transfer-api_storage

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
tutorial:transfer-api_storage [2021/10/30 09:57] – [What you can do with a Storage<FluidVariant>] technici4ntutorial:transfer-api_storage [2021/10/30 10:25] technici4n
Line 1: Line 1:
-===== Fabric Transfer API: Understanding Storage<T> =====+===== Fabric Transfer API: Understanding Storage<FluidVariant> =====
 //This article is part of a series on the Fabric Transfer API. [[tutorial:transfer-api|Link to the home page of the series]].// //This article is part of a series on the Fabric Transfer API. [[tutorial:transfer-api|Link to the home page of the series]].//
  
Line 27: Line 27:
 </code> </code>
  
-==== What you can do with a Storage<FluidVariant> ==== +==== A look at Storage<T> ====
-=== A look at Storage<T> ===+
 Let's have a look at ''Storage.java'': Let's have a look at ''Storage.java'':
 <code java> <code java>
Line 44: Line 43:
 This interface allows us to insert into a storage, extract from it, and read its contents. This interface allows us to insert into a storage, extract from it, and read its contents.
  
-=== First example: how to insert exactly one bucket of water into a storage ===+==== First example: how to insert exactly one bucket of water into a storage ====
 <code java> <code java>
 Storage<FluidVariant> storage = ...; Storage<FluidVariant> storage = ...;
Line 64: Line 63:
 </code> </code>
  
-=== Second example: move exactly one bucket of lava from a storage to another storage ===+==== Second example: move exactly one bucket of lava from a storage to another storage ====
 <code java> <code java>
 import static net.fabricmc.fabric.api.transfer.v1.fluid.FluidConstants.BUCKET; // a bit shorter to type :) import static net.fabricmc.fabric.api.transfer.v1.fluid.FluidConstants.BUCKET; // a bit shorter to type :)
Line 78: Line 77:
 </code> </code>
 Hopefully you understand why this works, and why this will never duplicate or void fluid. Hopefully you understand why this works, and why this will never duplicate or void fluid.
 +
 +==== A more complicated example: Extracting the contents of a storage ====
 +In the previous example, we knew that we wanted to move water or lava. But what if we don't know what to extract? The answer is: iterate over the contents!
 +This example also introduces the concept of nested transactions.
 +<code java>
 +Storage<FluidVariant> storage;
 +Predicate<FluidVariant> filter = fv -> fv.isOf(Fluids.WATER); // What we want to extract, in this example let's say we want to extract any water, regardless of its NBT tag.
 +long totalExtracted = 0;
 +
 +// Open a transaction, as before.
 +try (Transaction transaction = Transaction.openOuter()) {
 + // Loop over the contents! Each StorageView<T> can contain at most one resource. You can think of a StorageView as an inventory slot.
 + for (StorageView<FluidVariant> view : storage.iterable(transaction)) {
 + if (view.isResourceBlank()) continue; // This means that the view contains no resource, represented by FluidVariant.blank().
 + FluidVariant storedResource = view.getResource(); // Current resource
 + if (!filter.test(storedResource)) continue; // The filter rejected this resource, skip it.
 +
 + // If you want to extract any amount <= view.getAmount(), do this.
 + totalExtracted += view.extract(storedResource, view.getAmount(), transaction);
 +
 + // If you want to extract either the exact amount or nothing, you can use a nested transaction!
 + try (Transaction nestedTransaction = transaction.openNested()) {
 + long amount = view.getAmount(); // The amount will change after the call to extract, so make sure to save it first.
 + long extracted = view.extract(storedResource, amount, nestedTransaction);
 + if (extracted == amount) {
 + totalExtracted += amount;
 + nestedTransaction.commit(); // Validate the nestedTransaction: the outer one will have to committed as well to validate this change.
 + } else {
 + // If we do nothing, the extraction is cancelled immediately when nestedTransaction is closed at the end of the try { ... } block.
 + }
 + }
 + }
 + transaction.commit(); // Don't forget to commit, or all of the extraction will be cancelled!
 +}
 +</code>
 +
 +==== Conclusion ====
 +You should now be able to use ''Storage''s and ''StorageView''s. They can be a bit challenging in the beginning, but once you're used to them they are very easy to work with.
 +
 +You should also have a look at ''StorageUtil'': it already contains functions that perform common transfer operations. In particular, [[https://maven.fabricmc.net/docs/fabric-api-0.41.0+1.17/net/fabricmc/fabric/api/transfer/v1/storage/StorageUtil.html#move(net.fabricmc.fabric.api.transfer.v1.storage.Storage,net.fabricmc.fabric.api.transfer.v1.storage.Storage,java.util.function.Predicate,long,net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext)|move]] is very useful if you just want to move resources between two storages.
 +
tutorial/transfer-api_storage.txt · Last modified: 2021/10/30 10:25 by 127.0.0.1