Revert "Shift inventory management responsibility to World"

This reverts commit 40574be3336289a813fda403ee858fb372afe067.
This commit is contained in:
Dylan K. Taylor 2025-04-06 19:19:36 +01:00
parent d738207478
commit 01c7e2de53
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
9 changed files with 65 additions and 48 deletions

View File

@ -270,9 +270,6 @@ class Campfire extends Transparent{
$this->position->getWorld()->addSound($this->position, $furnaceType->getCookSound()); $this->position->getWorld()->addSound($this->position, $furnaceType->getCookSound());
} }
$this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, self::UPDATE_INTERVAL_TICKS); $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, self::UPDATE_INTERVAL_TICKS);
}else{
//make sure the visual state is updated when items are added
$this->position->getWorld()->setBlock($this->position, $this);
} }
} }

View File

@ -50,6 +50,13 @@ class Barrel extends Spawnable implements ContainerTile, Nameable{
$this->saveItems($nbt); $this->saveItems($nbt);
} }
public function close() : void{
if(!$this->closed){
$this->inventory->removeAllViewers();
parent::close();
}
}
public function getInventory() : Inventory{ public function getInventory() : Inventory{
return $this->inventory; return $this->inventory;
} }

View File

@ -27,6 +27,7 @@ use pocketmine\block\inventory\window\BrewingStandInventoryWindow;
use pocketmine\crafting\BrewingRecipe; use pocketmine\crafting\BrewingRecipe;
use pocketmine\event\block\BrewingFuelUseEvent; use pocketmine\event\block\BrewingFuelUseEvent;
use pocketmine\event\block\BrewItemEvent; use pocketmine\event\block\BrewItemEvent;
use pocketmine\inventory\CallbackInventoryListener;
use pocketmine\inventory\Inventory; use pocketmine\inventory\Inventory;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\item\Item; use pocketmine\item\Item;
@ -63,6 +64,9 @@ class BrewingStand extends Spawnable implements ContainerTile, Nameable{
public function __construct(World $world, Vector3 $pos){ public function __construct(World $world, Vector3 $pos){
parent::__construct($world, $pos); parent::__construct($world, $pos);
$this->inventory = new SimpleInventory(5); $this->inventory = new SimpleInventory(5);
$this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange(static function(Inventory $unused) use ($world, $pos) : void{
$world->scheduleDelayedBlockUpdate($pos, 1);
}));
} }
public function readSaveData(CompoundTag $nbt) : void{ public function readSaveData(CompoundTag $nbt) : void{
@ -101,6 +105,14 @@ class BrewingStand extends Spawnable implements ContainerTile, Nameable{
return "Brewing Stand"; return "Brewing Stand";
} }
public function close() : void{
if(!$this->closed){
$this->inventory->removeAllViewers();
parent::close();
}
}
public function getInventory() : Inventory{ public function getInventory() : Inventory{
return $this->inventory; return $this->inventory;
} }

View File

@ -23,6 +23,8 @@ declare(strict_types=1);
namespace pocketmine\block\tile; namespace pocketmine\block\tile;
use pocketmine\block\Campfire as BlockCampfire;
use pocketmine\inventory\CallbackInventoryListener;
use pocketmine\inventory\Inventory; use pocketmine\inventory\Inventory;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\item\Item; use pocketmine\item\Item;
@ -53,6 +55,14 @@ class Campfire extends Spawnable implements ContainerTile{
parent::__construct($world, $pos); parent::__construct($world, $pos);
$this->inventory = new SimpleInventory(4); $this->inventory = new SimpleInventory(4);
$this->inventory->setMaxStackSize(1); $this->inventory->setMaxStackSize(1);
$this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange(
static function(Inventory $unused) use ($world, $pos) : void{
$block = $world->getBlock($pos);
if($block instanceof BlockCampfire){
$world->setBlock($pos, $block);
}
})
);
} }
public function getInventory() : Inventory{ public function getInventory() : Inventory{

View File

@ -94,6 +94,8 @@ class Chest extends Spawnable implements ContainerTile, Nameable{
public function close() : void{ public function close() : void{
if(!$this->closed){ if(!$this->closed){
$this->inventory->removeAllViewers();
if($this->doubleInventory !== null){ if($this->doubleInventory !== null){
if($this->isPaired() && $this->position->getWorld()->isChunkLoaded($this->pairX >> Chunk::COORD_BIT_SIZE, $this->pairZ >> Chunk::COORD_BIT_SIZE)){ if($this->isPaired() && $this->position->getWorld()->isChunkLoaded($this->pairX >> Chunk::COORD_BIT_SIZE, $this->pairZ >> Chunk::COORD_BIT_SIZE)){
$this->doubleInventory->removeAllViewers(); $this->doubleInventory->removeAllViewers();

View File

@ -29,6 +29,7 @@ use pocketmine\crafting\FurnaceRecipe;
use pocketmine\crafting\FurnaceType; use pocketmine\crafting\FurnaceType;
use pocketmine\event\inventory\FurnaceBurnEvent; use pocketmine\event\inventory\FurnaceBurnEvent;
use pocketmine\event\inventory\FurnaceSmeltEvent; use pocketmine\event\inventory\FurnaceSmeltEvent;
use pocketmine\inventory\CallbackInventoryListener;
use pocketmine\inventory\Inventory; use pocketmine\inventory\Inventory;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\item\Item; use pocketmine\item\Item;
@ -56,6 +57,11 @@ abstract class Furnace extends Spawnable implements ContainerTile, Nameable{
public function __construct(World $world, Vector3 $pos){ public function __construct(World $world, Vector3 $pos){
parent::__construct($world, $pos); parent::__construct($world, $pos);
$this->inventory = new SimpleInventory(3); $this->inventory = new SimpleInventory(3);
$this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange(
static function(Inventory $unused) use ($world, $pos) : void{
$world->scheduleDelayedBlockUpdate($pos, 1);
})
);
} }
public function readSaveData(CompoundTag $nbt) : void{ public function readSaveData(CompoundTag $nbt) : void{
@ -73,6 +79,10 @@ abstract class Furnace extends Spawnable implements ContainerTile, Nameable{
$this->loadName($nbt); $this->loadName($nbt);
$this->loadItems($nbt); $this->loadItems($nbt);
if($this->remainingFuelTime > 0){
$this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, 1);
}
} }
protected function writeSaveData(CompoundTag $nbt) : void{ protected function writeSaveData(CompoundTag $nbt) : void{
@ -87,6 +97,14 @@ abstract class Furnace extends Spawnable implements ContainerTile, Nameable{
return "Furnace"; return "Furnace";
} }
public function close() : void{
if(!$this->closed){
$this->inventory->removeAllViewers();
parent::close();
}
}
public function getInventory() : Inventory{ public function getInventory() : Inventory{
return $this->inventory; return $this->inventory;
} }

View File

@ -58,6 +58,14 @@ class Hopper extends Spawnable implements ContainerTile, Nameable{
$nbt->setInt(self::TAG_TRANSFER_COOLDOWN, $this->transferCooldown); $nbt->setInt(self::TAG_TRANSFER_COOLDOWN, $this->transferCooldown);
} }
public function close() : void{
if(!$this->closed){
$this->inventory->removeAllViewers();
parent::close();
}
}
public function getDefaultName() : string{ public function getDefaultName() : string{
return "Hopper"; return "Hopper";
} }

View File

@ -80,6 +80,13 @@ class ShulkerBox extends Spawnable implements ContainerTile, Nameable{
} }
} }
public function close() : void{
if(!$this->closed){
$this->inventory->removeAllViewers();
parent::close();
}
}
protected function onBlockDestroyedHook() : void{ protected function onBlockDestroyedHook() : void{
//NOOP override of ContainerTrait - shulker boxes retain their contents when destroyed //NOOP override of ContainerTrait - shulker boxes retain their contents when destroyed
} }

View File

@ -30,7 +30,6 @@ use pocketmine\block\Air;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\block\BlockTypeIds; use pocketmine\block\BlockTypeIds;
use pocketmine\block\RuntimeBlockStateRegistry; use pocketmine\block\RuntimeBlockStateRegistry;
use pocketmine\block\tile\ContainerTile;
use pocketmine\block\tile\Spawnable; use pocketmine\block\tile\Spawnable;
use pocketmine\block\tile\Tile; use pocketmine\block\tile\Tile;
use pocketmine\block\tile\TileFactory; use pocketmine\block\tile\TileFactory;
@ -58,8 +57,6 @@ use pocketmine\event\world\WorldDisplayNameChangeEvent;
use pocketmine\event\world\WorldParticleEvent; use pocketmine\event\world\WorldParticleEvent;
use pocketmine\event\world\WorldSaveEvent; use pocketmine\event\world\WorldSaveEvent;
use pocketmine\event\world\WorldSoundEvent; use pocketmine\event\world\WorldSoundEvent;
use pocketmine\inventory\Inventory;
use pocketmine\inventory\InventoryListener;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\ItemUseResult; use pocketmine\item\ItemUseResult;
use pocketmine\item\LegacyStringToItemParser; use pocketmine\item\LegacyStringToItemParser;
@ -148,7 +145,7 @@ use const PHP_INT_MIN;
* @phpstan-type BlockPosHash int * @phpstan-type BlockPosHash int
* @phpstan-type ChunkBlockPosHash int * @phpstan-type ChunkBlockPosHash int
*/ */
class World implements ChunkManager, InventoryListener{ class World implements ChunkManager{
private static int $worldIdCounter = 1; private static int $worldIdCounter = 1;
@ -290,12 +287,6 @@ class World implements ChunkManager, InventoryListener{
*/ */
private array $chunks = []; private array $chunks = [];
/**
* @var Vector3[]|\WeakMap
* @phpstan-var \WeakMap<Inventory, Vector3>
*/
private \WeakMap $containerToBlockPositionMap;
/** /**
* @var Vector3[][] chunkHash => [relativeBlockHash => Vector3] * @var Vector3[][] chunkHash => [relativeBlockHash => Vector3]
* @phpstan-var array<ChunkPosHash, array<ChunkBlockPosHash, Vector3>> * @phpstan-var array<ChunkPosHash, array<ChunkBlockPosHash, Vector3>>
@ -523,8 +514,6 @@ class World implements ChunkManager, InventoryListener{
} }
}); });
$this->containerToBlockPositionMap = new \WeakMap();
$this->scheduledBlockUpdateQueue = new ReversePriorityQueue(); $this->scheduledBlockUpdateQueue = new ReversePriorityQueue();
$this->scheduledBlockUpdateQueue->setExtractFlags(\SplPriorityQueue::EXTR_BOTH); $this->scheduledBlockUpdateQueue->setExtractFlags(\SplPriorityQueue::EXTR_BOTH);
@ -2874,10 +2863,6 @@ class World implements ChunkManager, InventoryListener{
//delegate tile ticking to the corresponding block //delegate tile ticking to the corresponding block
$this->scheduleDelayedBlockUpdate($pos->asVector3(), 1); $this->scheduleDelayedBlockUpdate($pos->asVector3(), 1);
if($tile instanceof ContainerTile){
$tile->getInventory()->getListeners()->add($this);
$this->containerToBlockPositionMap[$tile->getInventory()] = $pos->asVector3();
}
} }
/** /**
@ -2896,40 +2881,11 @@ class World implements ChunkManager, InventoryListener{
if(isset($this->chunks[$hash = World::chunkHash($chunkX, $chunkZ)])){ if(isset($this->chunks[$hash = World::chunkHash($chunkX, $chunkZ)])){
$this->chunks[$hash]->removeTile($tile); $this->chunks[$hash]->removeTile($tile);
} }
if($tile instanceof ContainerTile){
$inventory = $tile->getInventory();
$inventory->removeAllViewers();
$inventory->getListeners()->remove($this);
unset($this->containerToBlockPositionMap[$inventory]);
}
foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){
$listener->onBlockChanged($pos->asVector3()); $listener->onBlockChanged($pos->asVector3());
} }
} }
private function notifyInventoryUpdate(Inventory $inventory) : void{
$blockPosition = $this->containerToBlockPositionMap[$inventory] ?? null;
if($blockPosition !== null){
$this->scheduleDelayedBlockUpdate($blockPosition, 1);
}
}
/**
* @internal
* @see InventoryListener
*/
public function onSlotChange(Inventory $inventory, int $slot, Item $oldItem) : void{
$this->notifyInventoryUpdate($inventory);
}
/**
* @internal
* @see InventoryListener
*/
public function onContentChange(Inventory $inventory, array $oldContents) : void{
$this->notifyInventoryUpdate($inventory);
}
public function isChunkInUse(int $x, int $z) : bool{ public function isChunkInUse(int $x, int $z) : bool{
return isset($this->chunkLoaders[$index = World::chunkHash($x, $z)]) && count($this->chunkLoaders[$index]) > 0; return isset($this->chunkLoaders[$index = World::chunkHash($x, $z)]) && count($this->chunkLoaders[$index]) > 0;
} }