Interface Storage<T>
- Type Parameters:
T
- The type of the stored resources.
- All Superinterfaces:
Iterable<StorageView<T>>
- All Known Subinterfaces:
ExtractionOnlyStorage<T>
,InsertionOnlyStorage<T>
,InventoryStorage
,PlayerInventoryStorage
,SingleSlotStorage<T>
,SlottedStorage<T>
- All Known Implementing Classes:
CombinedSlottedStorage
,CombinedStorage
,EmptyItemFluidStorage
,FilteringStorage
,FullItemFluidStorage
,SingleFluidStorage
,SingleItemStorage
,SingleStackStorage
,SingleVariantItemStorage
,SingleVariantStorage
Most of the documentation that follows is quite technical. For an easier introduction to the API, see the wiki page.
supportsInsertion()
andsupportsExtraction()
can be used to tell if insertion and extraction functionality are possibly supported by this storage.insert(T, long, net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext)
andextract(T, long, net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext)
can be used to insert or extract resources from this storage.iterator()
can be used to inspect the contents of this storage.getVersion()
can be used to quickly check if a storage has changed, without having to rescan its contents.
Users that wish to implement this interface can use the helpers in the base
package:
CombinedStorage
can be used to combine multiple instances, for example to combine multiple "slots" in one big storage.ExtractionOnlyStorage
andInsertionOnlyStorage
can be used when only extraction or insertion is needed.- Resource-specific base implementations may also be available.
For example, Fabric API provides
SingleVariantStorage
to accelerate implementations of transfer variant storages.
Important note: Unless otherwise specified, all transfer functions take a non-blank resource
and a non-negative maximum amount as parameters.
Implementations are encouraged to throw an exception if these preconditions are violated.
StoragePreconditions
can be used for these checks.
For transfer functions, the returned amount must be non-negative, and smaller than the passed maximum amount. Consumers of these functions are encourage to throw an exception if these postconditions are violated.
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptionasClass()
Return a class instance of this interface with the desired generic type, to be used for easier registration with API lookups.static <T> Storage
<T> empty()
Return an empty storage.long
extract
(T resource, long maxAmount, TransactionContext transaction) Try to extract up to some amount of a resource from this storage.default long
Return an integer representing the current version of this storage instance to allow for fast change detection: if the version hasn't changed since the last time, and the storage instance is the same, the storage has the same contents.long
insert
(T resource, long maxAmount, TransactionContext transaction) Try to insert up to some amount of a resource into this storage.iterator()
Iterate through the contents of this storage.default Iterator
<StorageView<T>> Same asiterator()
, but the iterator is guaranteed to skip over empty views, i.e.default Iterable
<StorageView<T>> Convenient helper to get anIterable
over the non-empty views of this storage, for use in for-each loops.default boolean
Return false if callingextract(T, long, net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext)
will absolutely always return 0, or true otherwise or in doubt.default boolean
Return false if callinginsert(T, long, net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext)
will absolutely always return 0, or true otherwise or in doubt.Methods inherited from interface java.lang.Iterable
forEach, spliterator
-
Method Details
-
empty
Return an empty storage. -
supportsInsertion
default boolean supportsInsertion()Return false if callinginsert(T, long, net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext)
will absolutely always return 0, or true otherwise or in doubt.Note: This function is meant to be used by pipes or other devices that can transfer resources to know if they should interact with this storage at all.
-
insert
Try to insert up to some amount of a resource into this storage.- Parameters:
resource
- The resource to insert. May not be blank.maxAmount
- The maximum amount of resource to insert. May not be negative.transaction
- The transaction this operation is part of.- Returns:
- A non-negative integer not greater than maxAmount: the amount that was inserted.
-
supportsExtraction
default boolean supportsExtraction()Return false if callingextract(T, long, net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext)
will absolutely always return 0, or true otherwise or in doubt.Note: This function is meant to be used by pipes or other devices that can transfer resources to know if they should interact with this storage at all.
-
extract
Try to extract up to some amount of a resource from this storage.- Parameters:
resource
- The resource to extract. May not be blank.maxAmount
- The maximum amount of resource to extract. May not be negative.transaction
- The transaction this operation is part of.- Returns:
- A non-negative integer not greater than maxAmount: the amount that was extracted.
-
iterator
Iterator<StorageView<T>> iterator()Iterate through the contents of this storage. Every visitedStorageView
represents a stored resource and an amount. The iterator doesn't guarantee that a single resource only occurs once during an iteration. Calling remove on the iterator is not allowed.insert(T, long, net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext)
andextract(T, long, net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext)
may be called safely during iteration. Extractions should be visible to an open iterator, but insertions are not required to. In particular, inventories with a fixed amount of slots may wish to make insertions visible to iterators, but inventories with a dynamic or very large amount of slots should not do that to ensure timely termination of the iteration.If a modification is made to the storage during iteration, the iterator might become invalid at the end of the outermost transaction. In particular, if multiple storage views are extracted from, the entire iteration should be wrapped in a transaction.
-
nonEmptyIterator
Same asiterator()
, but the iterator is guaranteed to skip over empty views, i.e. views that contain blank resources or have a zero amount.This can provide a large performance benefit over
iterator()
if the caller is only interested in non-empty views, for example because it is trying to extract resources from the storage.This function should only be overridden if the storage is able to provide an optimized iterator over non-empty views, for example because it is keeping an index of non-empty views. Otherwise, the default implementation simply calls
iterator()
and filters out empty views.When implementing this function, note that the guarantees of
iterator()
still apply. In particular,insert(T, long, net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext)
andextract(T, long, net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext)
may be called safely during iteration.- Returns:
- An iterator over the non-empty views of this storage. Calling remove on the iterator is not allowed.
-
nonEmptyViews
Convenient helper to get anIterable
over the non-empty views of this storage, for use in for-each loops.for (StorageView<T> view : storage.nonEmptyViews()) { // Do something with the view }
-
getVersion
default long getVersion()Return an integer representing the current version of this storage instance to allow for fast change detection: if the version hasn't changed since the last time, and the storage instance is the same, the storage has the same contents. This can be used to avoid re-scanning the contents of the storage, which could be an expensive operation. It may be used like that:// Store storage and version: Storage<?> firstStorage = // ... long firstVersion = firstStorage.getVersion(); // Later, check if the secondStorage is the unchanged firstStorage: Storage<?> secondStorage = // ... long secondVersion = secondStorage.getVersion(); // We must check firstStorage == secondStorage first, otherwise versions may not be compared. if (firstStorage == secondStorage && firstVersion == secondVersion) { // storage contents are the same. } else { // storage contents might have changed. }
The version must change if the state of the storage has changed, generally after a direct modification, or at the end of a modifying transaction. The version may also change even if the state of the storage hasn't changed.
It is not valid to call this during a transaction, and implementations are encouraged to throw an exception if that happens.
-
asClass
Return a class instance of this interface with the desired generic type, to be used for easier registration with API lookups.
-