User Tools

Site Tools


tutorial:transfer-api_item_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
tutorial:transfer-api_item_storage [2022/02/04 17:14] technici4ntutorial:transfer-api_item_storage [2022/02/04 17:37] (current) – external edit 127.0.0.1
Line 1: Line 1:
-====== Fabric Transfer API: Understanding Storage<ItemVariant> ======+====== Fabric Transfer API: Item transfer with Storage<ItemVariant> ======
 //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 63: Line 63:
 To learn how to use ''Storage'', please refer to the [[tutorial:transfer-api/storage|Storage<FluidVariant> tutorial]] since the methods are exactly the same. To learn how to use ''Storage'', please refer to the [[tutorial:transfer-api/storage|Storage<FluidVariant> tutorial]] since the methods are exactly the same.
  
-===== Dealing with Inventory/SidedInventory and PlayerInventory =====+==== Dealing with Inventory/SidedInventory and PlayerInventory ====
 Sometimes, it is necessary to convert some ''Inventory'' to a ''Storage<ItemVariant>''. For that purpose, [[https://github.com/FabricMC/fabric/blob/f66f2be7b6a29a764f78cf9762171bf0c0ef097e/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/item/InventoryStorage.java#L63|InventoryStorage.of(inventory, side)]] can be used. Sometimes, it is necessary to convert some ''Inventory'' to a ''Storage<ItemVariant>''. For that purpose, [[https://github.com/FabricMC/fabric/blob/f66f2be7b6a29a764f78cf9762171bf0c0ef097e/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/item/InventoryStorage.java#L63|InventoryStorage.of(inventory, side)]] can be used.
 ''InventoryStorage'' also allows recovering each slot separately through the ''getSlot'' and ''getSlots'' functions. ''InventoryStorage'' also allows recovering each slot separately through the ''getSlot'' and ''getSlots'' functions.
Line 69: Line 69:
  
 [[https://github.com/FabricMC/fabric/blob/1.18/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/item/PlayerInventoryStorage.java|PlayerInventoryStorage]] serves a similar purpose, but for player inventories. Make sure to read its documentation, it contains very useful functions such as ''offerOrDrop''. [[https://github.com/FabricMC/fabric/blob/1.18/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/item/PlayerInventoryStorage.java|PlayerInventoryStorage]] serves a similar purpose, but for player inventories. Make sure to read its documentation, it contains very useful functions such as ''offerOrDrop''.
 +
 +**A word of caution**: To be able to support transactions, ''ItemStorage.of'' assumes that each slot in the inventory is independent of other slots, and of other inventories. Do NOT use it if that is not the case for your inventory.
  
 ===== How to implement Storage<ItemVariant> ===== ===== How to implement Storage<ItemVariant> =====
Line 74: Line 76:
  
 ==== SingleVariantStorage, FilteringStorage, CombinedStorage ==== ==== SingleVariantStorage, FilteringStorage, CombinedStorage ====
-The helpers described on the [[transfer-api/fluid_implementation|fluid implementation page]] can be used just fine for item transfer. However, screen handler interactions make heavy use of mutable ''ItemStack''s. So **if you are implementing an item-containing block with GUI slots, you should avoid ''SingleVariantStorage''** and look at the other solutions below instead. However, ''FilteringStorage'' and ''CombinedStorage'' might still be useful to you.+The helpers described on the [[transfer-api/fluid_implementation|fluid implementation page]] can be used just fine for item transfer. However, screen handler interactions make heavy use of mutable ''ItemStack''s. So **if you are implementing an item-containing block with GUI slots, you should avoid ''SingleVariantStorage''** and look at the other solutions below instead. 
 + 
 +''FilteringStorage'' and ''CombinedStorage'' might still be useful to you.
  
 ==== Use SimpleInventory ==== ==== Use SimpleInventory ====
Line 121: Line 125:
   * Multiple ''SimpleInventory'''s can be created, for example if the block has a "main inventory" with a stack limit of 64, and an "upgrade inventory" with a stack limit of 1. They can be combined into one ''Storage<ItemVariant>'' with ''CombinedStorage''.   * Multiple ''SimpleInventory'''s can be created, for example if the block has a "main inventory" with a stack limit of 64, and an "upgrade inventory" with a stack limit of 1. They can be combined into one ''Storage<ItemVariant>'' with ''CombinedStorage''.
   * (Advanced) You can have your ''SimpleInventory'' subclass implement ''SidedInventory'', and wrappers queried with a side via ''InventoryStorage.of(sidedSimpleInv, side)'' will check ''canInsert'' and ''canExtract''.   * (Advanced) You can have your ''SimpleInventory'' subclass implement ''SidedInventory'', and wrappers queried with a side via ''InventoryStorage.of(sidedSimpleInv, side)'' will check ''canInsert'' and ''canExtract''.
 +
 +==== Use SingleStackStorage ====
 +Another (more complicated) option is to store a stack or a list of stacks somewhere, and also a [[https://github.com/FabricMC/fabric/blob/1.18/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/item/base/SingleStackStorage.java|SingleStackStorage]]. Please have a look at the javadoc if you wish to go down this path.
 +
 +==== (Discouraged) Directly implement Inventory or SidedInventory ====
 +For compatibility with existing vanilla inventories, the Transfer API will automatically wrap any block entity implementing ''Inventory'' or its subinterface ''SidedInventory'' as a ''Storage<ItemVariant>''. It will also wrap ''SidedInventory'''s returned by blocks implementing ''InventoryProvider'' if they return the same inventory multiple times. This means that implementing ''Inventory''/''SidedInventory'' on your block entity class will correctly allow other mods to use it. However, this approach is **discouraged** for the following reasons:
 +  * Performance: ''InventoryStorage.of'' is called every time, and it can be an expensive function to call.
 +  * Code size: this will require more code than using ''SimpleInventory'' as described above.
 +  * Flexibility: this is less flexible than ''SimpleInventory''.
 +  * Correctness: correctly implementing ''Inventory'' is harder than reusing the implementation that already exists in Minecraft itself.
tutorial/transfer-api_item_storage.1643994899.txt.gz · Last modified: 2022/02/04 17:14 by technici4n