Extract a DelegateInventory from EnderChestInventory

This commit is contained in:
Dylan K. Taylor 2021-06-26 20:56:04 +01:00
parent 8cd7cc7c00
commit 9b30c2feda
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
2 changed files with 81 additions and 39 deletions

View File

@ -24,12 +24,9 @@ declare(strict_types=1);
namespace pocketmine\block\inventory;
use pocketmine\block\tile\EnderChest;
use pocketmine\inventory\BaseInventory;
use pocketmine\inventory\CallbackInventoryListener;
use pocketmine\inventory\DelegateInventory;
use pocketmine\inventory\Inventory;
use pocketmine\inventory\InventoryListener;
use pocketmine\inventory\PlayerEnderInventory;
use pocketmine\item\Item;
use pocketmine\network\mcpe\protocol\BlockEventPacket;
use pocketmine\player\Player;
use pocketmine\world\Position;
@ -40,52 +37,23 @@ use pocketmine\world\sound\Sound;
/**
* EnderChestInventory is not a real inventory; it's just a gateway to the player's ender inventory.
*/
class EnderChestInventory extends BaseInventory implements BlockInventory{
class EnderChestInventory extends DelegateInventory implements BlockInventory{
use AnimatedBlockInventoryTrait {
onClose as animatedBlockInventoryTrait_onClose;
}
private PlayerEnderInventory $inventory;
private InventoryListener $inventoryListener;
public function __construct(Position $holder, PlayerEnderInventory $inventory){
parent::__construct();
parent::__construct($inventory);
$this->holder = $holder;
$this->inventory = $inventory;
$this->inventory->getListeners()->add($this->inventoryListener = new CallbackInventoryListener(
function(Inventory $unused, int $slot, Item $oldItem) : void{
$this->onSlotChange($slot, $oldItem);
},
function(Inventory $unused, array $oldContents) : void{
$this->onContentChange($oldContents);
}
));
}
public function getEnderInventory() : PlayerEnderInventory{
return $this->inventory;
}
public function getSize() : int{
return $this->inventory->getSize();
}
public function getItem(int $index) : Item{
return $this->inventory->getItem($index);
}
protected function internalSetItem(int $index, Item $item) : void{
$this->inventory->setItem($index, $item);
}
public function getContents(bool $includeEmpty = false) : array{
return $this->inventory->getContents($includeEmpty);
}
protected function internalSetContents(array $items) : void{
$this->inventory->setContents($items);
}
public function getViewerCount() : int{
$enderChest = $this->getHolder()->getWorld()->getTile($this->getHolder());
if(!$enderChest instanceof EnderChest){
@ -115,9 +83,5 @@ class EnderChestInventory extends BaseInventory implements BlockInventory{
if($enderChest instanceof EnderChest){
$enderChest->setViewerCount($enderChest->getViewerCount() - 1);
}
if($who === $this->inventory->getHolder()){
$this->inventory->getListeners()->remove($this->inventoryListener);
$this->inventoryListener = CallbackInventoryListener::onAnyChange(static function() : void{}); //break cyclic reference
}
}
}

View File

@ -0,0 +1,78 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\inventory;
use pocketmine\item\Item;
use pocketmine\player\Player;
use function count;
/**
* An inventory which is backed by another inventory, and acts as a proxy to that inventory.
*/
class DelegateInventory extends BaseInventory{
private Inventory $backingInventory;
private InventoryListener $inventoryListener;
public function __construct(Inventory $backingInventory){
parent::__construct();
$this->backingInventory = $backingInventory;
$this->backingInventory->getListeners()->add($this->inventoryListener = new CallbackInventoryListener(
function(Inventory $unused, int $slot, Item $oldItem) : void{
$this->onSlotChange($slot, $oldItem);
},
function(Inventory $unused, array $oldContents) : void{
$this->onContentChange($oldContents);
}
));
}
public function getSize() : int{
return $this->backingInventory->getSize();
}
public function getItem(int $index) : Item{
return $this->backingInventory->getItem($index);
}
protected function internalSetItem(int $index, Item $item) : void{
$this->backingInventory->setItem($index, $item);
}
public function getContents(bool $includeEmpty = false) : array{
return $this->backingInventory->getContents($includeEmpty);
}
protected function internalSetContents(array $items) : void{
$this->backingInventory->setContents($items);
}
public function onClose(Player $who) : void{
parent::onClose($who);
if(count($this->getViewers()) === 0 && count($this->getListeners()->toArray()) === 1){
$this->backingInventory->getListeners()->remove($this->inventoryListener);
$this->inventoryListener = CallbackInventoryListener::onAnyChange(static function() : void{}); //break cyclic reference
}
}
}