diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index c1b16ce08..fe8d53774 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -26,6 +26,7 @@ declare(strict_types=1); */ namespace pocketmine\block; +use pocketmine\block\tile\Spawnable; use pocketmine\block\tile\Tile; use pocketmine\block\tile\TileFactory; use pocketmine\block\utils\InvalidBlockStateException; @@ -184,9 +185,13 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ $tileType = $this->idInfo->getTileClass(); $oldTile = $this->world->getTile($this); - if($oldTile !== null and ($tileType === null or !($oldTile instanceof $tileType))){ - $oldTile->close(); - $oldTile = null; + if($oldTile !== null){ + if($tileType === null or !($oldTile instanceof $tileType)){ + $oldTile->close(); + $oldTile = null; + }elseif($oldTile instanceof Spawnable){ + $oldTile->setDirty(); //destroy old network cache + } } if($oldTile === null and $tileType !== null){ $this->world->addTile(TileFactory::create($tileType, $this->world, $this->asVector3())); diff --git a/src/pocketmine/block/BrewingStand.php b/src/pocketmine/block/BrewingStand.php index a4c47710a..67408f0b6 100644 --- a/src/pocketmine/block/BrewingStand.php +++ b/src/pocketmine/block/BrewingStand.php @@ -69,5 +69,7 @@ class BrewingStand extends Transparent{ return true; } - //TODO + public function onScheduledUpdate() : void{ + //TODO + } } diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index a936ec24e..2d85e898b 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -89,5 +89,7 @@ class DaylightSensor extends Transparent{ return true; } - //TODO + public function onScheduledUpdate() : void{ + //TODO + } } diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index fd0a4218f..9e6e76507 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -97,4 +97,11 @@ class Furnace extends Solid{ return true; } + + public function onScheduledUpdate() : void{ + $furnace = $this->getWorld()->getTile($this); + if($furnace instanceof TileFurnace and $furnace->onUpdate()){ + $this->world->scheduleDelayedBlockUpdate($this, 1); //TODO: check this + } + } } diff --git a/src/pocketmine/block/Hopper.php b/src/pocketmine/block/Hopper.php index d626534f2..8d5eb0bc4 100644 --- a/src/pocketmine/block/Hopper.php +++ b/src/pocketmine/block/Hopper.php @@ -84,5 +84,9 @@ class Hopper extends Transparent{ return false; } + public function onScheduledUpdate() : void{ + //TODO + } + //TODO: redstone logic, sucking logic } diff --git a/src/pocketmine/block/MonsterSpawner.php b/src/pocketmine/block/MonsterSpawner.php index e8b44b9db..ca38aae65 100644 --- a/src/pocketmine/block/MonsterSpawner.php +++ b/src/pocketmine/block/MonsterSpawner.php @@ -44,4 +44,8 @@ class MonsterSpawner extends Transparent{ protected function getXpDropAmount() : int{ return mt_rand(15, 43); } + + public function onScheduledUpdate() : void{ + //TODO + } } diff --git a/src/pocketmine/block/tile/Banner.php b/src/pocketmine/block/tile/Banner.php index 58163ebba..2c3792870 100644 --- a/src/pocketmine/block/tile/Banner.php +++ b/src/pocketmine/block/tile/Banner.php @@ -109,7 +109,6 @@ class Banner extends Spawnable{ */ public function setBaseColor(DyeColor $color) : void{ $this->baseColor = $color; - $this->onChanged(); } /** @@ -124,7 +123,6 @@ class Banner extends Spawnable{ */ public function setPatterns(Deque $patterns) : void{ $this->patterns = $patterns; - $this->onChanged(); } public function getDefaultName() : string{ diff --git a/src/pocketmine/block/tile/Bed.php b/src/pocketmine/block/tile/Bed.php index 2f8b3f2bd..28b68ee62 100644 --- a/src/pocketmine/block/tile/Bed.php +++ b/src/pocketmine/block/tile/Bed.php @@ -45,7 +45,6 @@ class Bed extends Spawnable{ public function setColor(DyeColor $color) : void{ $this->color = $color; - $this->onChanged(); } public function readSaveData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/block/tile/BrewingStand.php b/src/pocketmine/block/tile/BrewingStand.php index bf4de785c..2d336cad4 100644 --- a/src/pocketmine/block/tile/BrewingStand.php +++ b/src/pocketmine/block/tile/BrewingStand.php @@ -55,7 +55,7 @@ class BrewingStand extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ $this->inventory = new BrewingStandInventory($this); $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange(function(Inventory $unused){ - $this->world->scheduleDelayedBlockUpdate($this->getBlock(), 0); + $this->world->scheduleDelayedBlockUpdate($this->getBlock(), 1); })); parent::__construct($world, $pos); } @@ -110,9 +110,4 @@ class BrewingStand extends Spawnable implements Container, Nameable{ public function getRealInventory(){ return $this->inventory; } - - public function onUpdate() : bool{ - return false; //TODO - } - } diff --git a/src/pocketmine/block/tile/Chest.php b/src/pocketmine/block/tile/Chest.php index a8ca4dff0..98b654614 100644 --- a/src/pocketmine/block/tile/Chest.php +++ b/src/pocketmine/block/tile/Chest.php @@ -196,8 +196,8 @@ class Chest extends Spawnable implements Container, Nameable{ $this->createPair($tile); - $this->onChanged(); - $tile->onChanged(); + $this->setDirty(); + $tile->setDirty(); $this->checkPairing(); return true; @@ -219,12 +219,12 @@ class Chest extends Spawnable implements Container, Nameable{ $tile = $this->getPair(); $this->pairX = $this->pairZ = null; - $this->onChanged(); + $this->setDirty(); if($tile instanceof Chest){ $tile->pairX = $tile->pairZ = null; $tile->checkPairing(); - $tile->onChanged(); + $tile->setDirty(); } $this->checkPairing(); diff --git a/src/pocketmine/block/tile/DaylightSensor.php b/src/pocketmine/block/tile/DaylightSensor.php index d06201654..8776d1ca5 100644 --- a/src/pocketmine/block/tile/DaylightSensor.php +++ b/src/pocketmine/block/tile/DaylightSensor.php @@ -41,8 +41,4 @@ class DaylightSensor extends Tile{ protected function writeSaveData(CompoundTag $nbt) : void{ } - - public function onUpdate() : bool{ - return false; //TODO: we'll need this for implementing daylight sensor until https://github.com/pmmp/PocketMine-MP/issues/2099 is fixed - } } diff --git a/src/pocketmine/block/tile/FlowerPot.php b/src/pocketmine/block/tile/FlowerPot.php index 0c626bb33..db9bb28eb 100644 --- a/src/pocketmine/block/tile/FlowerPot.php +++ b/src/pocketmine/block/tile/FlowerPot.php @@ -69,7 +69,6 @@ class FlowerPot extends Spawnable{ }else{ $this->plant = clone $plant; } - $this->onChanged(); } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/block/tile/Furnace.php b/src/pocketmine/block/tile/Furnace.php index 5dd5b7fee..7d7f402bd 100644 --- a/src/pocketmine/block/tile/Furnace.php +++ b/src/pocketmine/block/tile/Furnace.php @@ -59,7 +59,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $this->inventory = new FurnaceInventory($this); $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange( function(Inventory $unused) : void{ - $this->scheduleUpdate(); + $this->world->scheduleDelayedBlockUpdate($this->asVector3(), 1); }) ); @@ -143,6 +143,7 @@ class Furnace extends Spawnable implements Container, Nameable{ } public function onUpdate() : bool{ + //TODO: move this to Block if($this->closed){ return false; } diff --git a/src/pocketmine/block/tile/Hopper.php b/src/pocketmine/block/tile/Hopper.php index bc8018ee4..4aa2d89e2 100644 --- a/src/pocketmine/block/tile/Hopper.php +++ b/src/pocketmine/block/tile/Hopper.php @@ -86,8 +86,4 @@ class Hopper extends Spawnable implements Container, Nameable{ public function getRealInventory(){ return $this->inventory; } - - public function onUpdate() : bool{ - return false; //TODO - } } diff --git a/src/pocketmine/block/tile/ItemFrame.php b/src/pocketmine/block/tile/ItemFrame.php index e042c049d..a3910046f 100644 --- a/src/pocketmine/block/tile/ItemFrame.php +++ b/src/pocketmine/block/tile/ItemFrame.php @@ -78,7 +78,6 @@ class ItemFrame extends Spawnable{ }else{ $this->item = ItemFactory::air(); } - $this->onChanged(); } public function getItemRotation() : int{ @@ -87,7 +86,6 @@ class ItemFrame extends Spawnable{ public function setItemRotation(int $rotation) : void{ $this->itemRotation = $rotation; - $this->onChanged(); } public function getItemDropChance() : float{ @@ -96,7 +94,6 @@ class ItemFrame extends Spawnable{ public function setItemDropChance(float $chance) : void{ $this->itemDropChance = $chance; - $this->onChanged(); } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/block/tile/MonsterSpawner.php b/src/pocketmine/block/tile/MonsterSpawner.php index e698b2c07..dba2f2938 100644 --- a/src/pocketmine/block/tile/MonsterSpawner.php +++ b/src/pocketmine/block/tile/MonsterSpawner.php @@ -149,8 +149,4 @@ class MonsterSpawner extends Spawnable{ $nbt->setFloat(self::TAG_ENTITY_SCALE, $this->displayEntityScale); } - - public function onUpdate() : bool{ - return false; //TODO - } } diff --git a/src/pocketmine/block/tile/Sign.php b/src/pocketmine/block/tile/Sign.php index a53f5cfa6..e625448c9 100644 --- a/src/pocketmine/block/tile/Sign.php +++ b/src/pocketmine/block/tile/Sign.php @@ -90,7 +90,6 @@ class Sign extends Spawnable{ */ public function setText(SignText $text) : void{ $this->text = $text; - $this->onChanged(); } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/block/tile/Skull.php b/src/pocketmine/block/tile/Skull.php index d4ede3ba9..fe0fe062c 100644 --- a/src/pocketmine/block/tile/Skull.php +++ b/src/pocketmine/block/tile/Skull.php @@ -71,7 +71,6 @@ class Skull extends Spawnable{ public function setSkullType(SkullType $type) : void{ $this->skullType = $type; - $this->onChanged(); } public function getSkullType() : SkullType{ @@ -84,7 +83,6 @@ class Skull extends Spawnable{ public function setRotation(int $rotation) : void{ $this->skullRotation = $rotation; - $this->onChanged(); } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/block/tile/Spawnable.php b/src/pocketmine/block/tile/Spawnable.php index 6568ad6c4..226a15412 100644 --- a/src/pocketmine/block/tile/Spawnable.php +++ b/src/pocketmine/block/tile/Spawnable.php @@ -37,16 +37,6 @@ abstract class Spawnable extends Tile{ /** @var NetworkNbtSerializer|null */ private static $nbtWriter = null; - /** - * Flags the tile as modified, so that updates will be broadcasted at the next available opportunity. - * This MUST be called any time a change is made that players must be able to see. - */ - protected function onChanged() : void{ - $this->spawnCompoundCache = null; - $this->dirty = true; - $this->scheduleUpdate(); - } - /** * Returns whether the tile needs to be respawned to viewers. * @@ -60,6 +50,9 @@ abstract class Spawnable extends Tile{ * @param bool $dirty */ public function setDirty(bool $dirty = true) : void{ + if($dirty){ + $this->spawnCompoundCache = null; + } $this->dirty = $dirty; } diff --git a/src/pocketmine/block/tile/Tile.php b/src/pocketmine/block/tile/Tile.php index fbdece662..1ff97a656 100644 --- a/src/pocketmine/block/tile/Tile.php +++ b/src/pocketmine/block/tile/Tile.php @@ -107,20 +107,6 @@ abstract class Tile extends Position{ return $this->world->getBlockAt($this->x, $this->y, $this->z); } - /** - * @return bool - */ - public function onUpdate() : bool{ - return false; - } - - final public function scheduleUpdate() : void{ - if($this->closed){ - throw new \InvalidStateException("Cannot schedule update on garbage tile " . get_class($this)); - } - $this->world->updateTiles[World::blockHash($this->x, $this->y, $this->z)] = $this; - } - public function isClosed() : bool{ return $this->closed; } diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 9183e525a..58d273fb0 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -143,8 +143,6 @@ class World implements ChunkManager, Metadatable{ /** @var Entity[] */ public $updateEntities = []; - /** @var Tile[] */ - public $updateTiles = []; /** @var Block[][] */ private $blockCache = []; @@ -818,26 +816,6 @@ class World implements ChunkManager, Metadatable{ Timings::$tickEntityTimer->stopTiming(); $this->timings->entityTick->stopTiming(); - $this->timings->tileEntityTick->startTiming(); - Timings::$tickTileEntityTimer->startTiming(); - //Update tiles that need update - foreach($this->updateTiles as $blockHash => $tile){ - if(!$tile->onUpdate()){ - unset($this->updateTiles[$blockHash]); - } - if(!$tile->isClosed() and $tile instanceof Spawnable and $tile->isDirty()){ - $chunkHash = World::chunkHash($tile->getFloorX() >> 4, $tile->getFloorZ() >> 4); - if(!isset($this->changedBlocks[$chunkHash])){ - $this->changedBlocks[$chunkHash] = [$blockHash => $tile]; - }else{ - $this->changedBlocks[$chunkHash][$blockHash] = $tile; - } - $tile->setDirty(false); - } - } - Timings::$tickTileEntityTimer->stopTiming(); - $this->timings->tileEntityTick->stopTiming(); - $this->timings->doTickTiles->startTiming(); $this->tickChunks(); $this->timings->doTickTiles->stopTiming(); @@ -2460,7 +2438,8 @@ class World implements ChunkManager, Metadatable{ throw new \InvalidStateException("Attempted to create tile " . get_class($tile) . " in unloaded chunk $chunkX $chunkZ"); } - $tile->scheduleUpdate(); + //delegate tile ticking to the corresponding block + $this->scheduleDelayedBlockUpdate($tile->asVector3(), 1); } /** @@ -2473,8 +2452,6 @@ class World implements ChunkManager, Metadatable{ throw new \InvalidArgumentException("Invalid Tile world"); } - unset($this->updateTiles[World::blockHash($tile->x, $tile->y, $tile->z)]); - $chunkX = $tile->getFloorX() >> 4; $chunkZ = $tile->getFloorZ() >> 4; diff --git a/src/pocketmine/world/WorldTimings.php b/src/pocketmine/world/WorldTimings.php index c79f48d7e..ab8c2d30c 100644 --- a/src/pocketmine/world/WorldTimings.php +++ b/src/pocketmine/world/WorldTimings.php @@ -46,8 +46,6 @@ class WorldTimings{ /** @var TimingsHandler */ public $entityTick; /** @var TimingsHandler */ - public $tileEntityTick; - /** @var TimingsHandler */ public $doTick; /** @var TimingsHandler */ @@ -78,7 +76,6 @@ class WorldTimings{ $this->doTickTiles = new TimingsHandler("** " . $name . "doTickTiles"); $this->doChunkGC = new TimingsHandler("** " . $name . "doChunkGC"); $this->entityTick = new TimingsHandler("** " . $name . "entityTick"); - $this->tileEntityTick = new TimingsHandler("** " . $name . "tileEntityTick"); $this->syncChunkSendTimer = new TimingsHandler("** " . $name . "syncChunkSend"); $this->syncChunkSendPrepareTimer = new TimingsHandler("** " . $name . "syncChunkSendPrepare");