mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-25 04:44:03 +00:00
Level: Queue all block updates until the end of tick
this allows deduplicating block updates when lots of adjacent blocks are set on a tick, which has beneficial effects on performance. It also fixes #2659. Future scope: - Use this mechanism to deal with explosions properly. - Don't execute block updates for air blocks.
This commit is contained in:
parent
d2768188e8
commit
82788774b0
@ -63,7 +63,6 @@ use pocketmine\level\particle\DestroyBlockParticle;
|
|||||||
use pocketmine\level\particle\Particle;
|
use pocketmine\level\particle\Particle;
|
||||||
use pocketmine\level\sound\Sound;
|
use pocketmine\level\sound\Sound;
|
||||||
use pocketmine\math\AxisAlignedBB;
|
use pocketmine\math\AxisAlignedBB;
|
||||||
use pocketmine\math\Facing;
|
|
||||||
use pocketmine\math\Vector2;
|
use pocketmine\math\Vector2;
|
||||||
use pocketmine\math\Vector3;
|
use pocketmine\math\Vector3;
|
||||||
use pocketmine\metadata\BlockMetadataStore;
|
use pocketmine\metadata\BlockMetadataStore;
|
||||||
@ -217,6 +216,8 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
|
|
||||||
/** @var \SplQueue */
|
/** @var \SplQueue */
|
||||||
private $neighbourBlockUpdateQueue;
|
private $neighbourBlockUpdateQueue;
|
||||||
|
/** @var bool[] blockhash => dummy */
|
||||||
|
private $neighbourBlockUpdateQueueIndex = [];
|
||||||
|
|
||||||
/** @var Player[][] */
|
/** @var Player[][] */
|
||||||
private $chunkSendQueue = [];
|
private $chunkSendQueue = [];
|
||||||
@ -759,8 +760,12 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
$ev = new BlockUpdateEvent($block);
|
$ev = new BlockUpdateEvent($block);
|
||||||
$ev->call();
|
$ev->call();
|
||||||
if(!$ev->isCancelled()){
|
if(!$ev->isCancelled()){
|
||||||
|
foreach($this->getNearbyEntities(AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)) as $entity){
|
||||||
|
$entity->onNearbyBlockChange();
|
||||||
|
}
|
||||||
$block->onNearbyBlockChange();
|
$block->onNearbyBlockChange();
|
||||||
}
|
}
|
||||||
|
unset($this->neighbourBlockUpdateQueueIndex[$index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->timings->doTickPending->stopTiming();
|
$this->timings->doTickPending->stopTiming();
|
||||||
@ -1081,19 +1086,12 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
$this->scheduledBlockUpdateQueue->insert(new Vector3((int) $pos->x, (int) $pos->y, (int) $pos->z), $delay + $this->server->getTick());
|
$this->scheduledBlockUpdateQueue->insert(new Vector3((int) $pos->x, (int) $pos->y, (int) $pos->z), $delay + $this->server->getTick());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private function tryAddToNeighbourUpdateQueue(Vector3 $pos) : void{
|
||||||
* Schedules the blocks around the specified position to be updated at the end of this tick.
|
if($this->isInWorld($pos->x, $pos->y, $pos->z)){
|
||||||
* Blocks will be updated with the normal update type.
|
$hash = Level::blockHash($pos->x, $pos->y, $pos->z);
|
||||||
*
|
if(!isset($this->neighbourBlockUpdateQueueIndex[$hash])){
|
||||||
* @param Vector3 $pos
|
$this->neighbourBlockUpdateQueue->enqueue($hash);
|
||||||
*/
|
$this->neighbourBlockUpdateQueueIndex[$hash] = true;
|
||||||
public function scheduleNeighbourBlockUpdates(Vector3 $pos){
|
|
||||||
$pos = $pos->floor();
|
|
||||||
|
|
||||||
foreach(Facing::ALL as $face){
|
|
||||||
$side = $pos->getSide($face);
|
|
||||||
if($this->isInWorld($side->x, $side->y, $side->z)){
|
|
||||||
$this->neighbourBlockUpdateQueue->enqueue(Level::blockHash($side->x, $side->y, $side->z));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1559,15 +1557,9 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
|
|
||||||
if($update){
|
if($update){
|
||||||
$this->updateAllLight($block);
|
$this->updateAllLight($block);
|
||||||
|
$this->tryAddToNeighbourUpdateQueue($block);
|
||||||
$ev = new BlockUpdateEvent($block);
|
foreach($block->sides() as $side){
|
||||||
$ev->call();
|
$this->tryAddToNeighbourUpdateQueue($side);
|
||||||
if(!$ev->isCancelled()){
|
|
||||||
foreach($this->getNearbyEntities(AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)->expand(1, 1, 1)) as $entity){
|
|
||||||
$entity->onNearbyBlockChange();
|
|
||||||
}
|
|
||||||
$ev->getBlock()->onNearbyBlockChange();
|
|
||||||
$this->scheduleNeighbourBlockUpdates($block);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user