-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Separate inventory holder info from container & player inventories #6533
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
this allows this functionality to be used with any type of inventory, and also makes it a little nicer to use in many cases.
we want viewers to be as close to decorative as possible, so that they provide useful information to plugins, but don't get in the way of other changes.
this unblocks a variety of changes, such as positionless tiles, enhanced APIs on Blocks for inventories, and also eliminates a bunch of cyclic references within the core code. linked to #5033
…tories it already needs to locate the correct pair anyway to know the left/right for DoubleChestInventoryWindow, so we might as well use this logic for initializing the DoubleChestInventory itself too. The old logic in tile/Chest didn't work correctly.
this is *probably* fine, but best avoided.
…y of AnimatedContainer interface this allows getting rid of several container window classes. we should probably look into adding more info to the BlockInventoryWindow to make the type easier to identify, though. now that holder is tracked by an ephemeral window, we can put whatever we like in there.
this really needs a shorter name
I have no real problem with the current implementation. It seems fine to me and is a first step towards a better inventory system. Another follow-up I would suggest concerns the viewers of the inventory. I can see the point of including viewers in this system but I still have a sticking point because we're including a reference to the player in the inventory interface. Wouldn't it be good after this to think of a system where we have classes that only contain storage logic / listeners and that's it ? |
Yeah, that's the ideal world. Unfortunately we need the Inventory to still track the viewers so that plugins can see all the viewers of an inventory, and also so that the inventory menus get closed when a block is deleted. I don't see another obvious solution to this problem. We could pull the viewer list out of |
Few issues remain with the PR:
|
Alright. I think I'm finally done with this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR eliminates cyclic references between inventories and their holders by introducing an InventoryWindow
abstraction layer that separates inventory holder information from the container and player inventories.
- Introduces
InventoryWindow
classes to wrap inventories with view-specific information for players - Replaces direct inventory access with window-based access for transactions and events
- Creates unified interfaces for blocks with menus (
MenuAccessor
) and containers (Container
) with associated traits
Reviewed Changes
Copilot reviewed 91 out of 91 changed files in this pull request and generated 5 comments.
Show a summary per file
File | Description |
---|---|
tests/phpunit/inventory/CombinedInventoryProxyTest.php |
Test file for new combined inventory proxy functionality |
src/player/TemporaryInventoryWindow.php |
Interface for temporary inventory windows |
src/player/SurvivalBlockBreakHandler.php |
Updates to use new main hand item access method |
src/player/PlayerInventoryWindow.php |
Window wrapper for player-owned inventories with type identification |
src/player/Player.php |
Major refactoring to use inventory windows instead of direct inventory references |
src/player/InventoryWindow.php |
Base class for inventory windows providing viewer-inventory abstraction |
Various network/mcpe handler files | Updates to handle inventory windows instead of raw inventories |
Various inventory files | Updates to support new window-based architecture |
Comments suppressed due to low confidence (1)
src/player/Player.php:1
- [nitpick] The TODO comment about a cyclic reference should be addressed or removed if the cyclic reference is acceptable in this context. Consider using a WeakReference if the cycle is problematic.
<?php
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
we don't technically need to do this, but I suppose it's nicer for people who don't use a static analyser.
In the interest of avoiding branch rot I'm going to get this merged, the final result won't look too different from this anyway. Pls let me know if there are issues found after the fact. |
This PR breaks the cyclic dependency between
Inventory
and its holder, which unblocks a lot of new developments.Related issues & PRs
Changes
API changes
Player->getCurrentWindow()
now returns?InventoryWindow
instead of?Inventory
Player->setCurrentWindow()
now accepts?InventoryWindow
instead of?Inventory
InventoryWindow
introduced, which is created for each player viewing the inventory, provides decorative information like holder info forInventoryTransactionEvent
, and is destroyed when the window is closed, eliminating cyclic referencesplayer\InventoryWindow
player\PlayerInventoryWindow
- wraps all permanent inventories of Player with type info for transactionsinventory\Hotbar
- replaces all hotbar usages inPlayerInventory
Human->getHotbar()
Human->getMainHandItem()
,Human->setMainHandItem()
,Human->getOffHandItem()
,Human->setOffHandItem()
block\utils\AnimatedContainerLike
&block\utils\AnimatedContainerLikeTrait
(for chests, shulkerboxes, etc)block\utils\Container
&block\utils\ContainerTrait
for blocks containing items (chests, etc)block\utils\MenuAccessor
implemented by all blocks that can open inventory menusblock\utils\MenuAccessorTrait
used by blocks with menus but without inventories (anvils, crafting tables etc)inventory\DelegateInventory
(only used for ender chests)inventory\PlayerInventory
,inventory\PlayerOffHandInventory
,inventory\PlayerCraftingInventory
,inventory\PlayerCursorInventory
- these have all been internally replaced bySimpleInventory
& they will appear asPlayerInventoryWindow
in transactions (checkgetType()
against thePlayerInventoryWindow::TYPE_*
constants to identify them)block\inventory\AnimatedBlockInventoryTrait
, (blocks now handle this logic directly usingAnimatedContainer
andAnimatedContainerTrait
)block\inventory\BlockInventoryTrait
,block\inventory\BlockInventory
BlockInventory
classes have been transitioned toInventoryWindow
wrappersSimpleInventory
internally (no cyclic references) except forChest
(which usesCombinedInventory
, without holder info)InventoryOpenEvent
andInventoryCloseEvent
now provideInventoryWindow
instead ofInventory
(to provide type information)InventoryTransaction
andSlotChangeAction
now provideInventoryWindow
instead ofInventory
TransactionBuilderInventory
toSlotChangeActionBuilder
TransactionBuilderInventory->getBuilder()
now acceptsInventoryWindow
instead ofInventory
DoubleChestInventory
superseded byCombinedInventory
- this new class allows combining any number of inventories behind a single object; mainly used for double chests but plugins could use it to do lots of fun thingsImpacts to plugins
Plugins can now do the following:
As compared to the old way:
Advantages
Behavioural changes
Inventories no longer keep permanent cyclic references to their holders.
Backwards compatibility
This makes significant BC breaks. However, all changes are able to be adapted to and the same amount of information is present on all APIs and events.
Follow-up
Tests
Briefly tested in-game.