Added cache for tile spawn compounds

avoids expensive repetetive NBT writes on chunk sends when the tile hasn't been changed
This commit is contained in:
Dylan K. Taylor
2017-10-27 10:23:37 +01:00
parent 52d0ad8a61
commit 48fefae920
3 changed files with 33 additions and 17 deletions

View File

@ -30,15 +30,17 @@ use pocketmine\network\mcpe\protocol\BlockEntityDataPacket;
use pocketmine\Player;
abstract class Spawnable extends Tile{
/** @var string|null */
private $spawnCompoundCache = null;
/** @var NBT|null */
private static $nbtWriter = null;
public function createSpawnPacket() : BlockEntityDataPacket{
$nbt = new NBT(NBT::LITTLE_ENDIAN);
$nbt->setData($this->getSpawnCompound());
$pk = new BlockEntityDataPacket();
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->namedtag = $nbt->write(true);
$pk->namedtag = $this->getSerializedSpawnCompound();
return $pk;
}
@ -67,7 +69,12 @@ abstract class Spawnable extends Tile{
$this->level->addChunkPacket($this->chunk->getX(), $this->chunk->getZ(), $pk);
}
/**
* Performs actions needed when the tile is modified, such as clearing caches and respawning the tile to players.
* WARNING: This MUST be called to clear spawn-compound and chunk caches when the tile's spawn compound has changed!
*/
protected function onChanged() : void{
$this->spawnCompoundCache = null;
$this->spawnToAll();
if($this->chunk !== null){
@ -76,6 +83,25 @@ abstract class Spawnable extends Tile{
}
}
/**
* Returns encoded NBT (varint, little-endian) used to spawn this tile to clients. Uses cache where possible,
* populates cache if it is null.
*
* @return string encoded NBT
*/
final public function getSerializedSpawnCompound() : string{
if($this->spawnCompoundCache === null){
if(self::$nbtWriter === null){
self::$nbtWriter = new NBT(NBT::LITTLE_ENDIAN);
}
self::$nbtWriter->setData($this->getSpawnCompound());
$this->spawnCompoundCache = self::$nbtWriter->write(true);
}
return $this->spawnCompoundCache;
}
/**
* @return CompoundTag
*/