Chunk: added modification counter

this is independent from the terrain dirty flags (which are specifically used to track state of chunks needing to be saved).
This commit is contained in:
Dylan K. Taylor 2021-10-25 20:53:11 +01:00
parent baba25953f
commit a5418a019d
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
2 changed files with 19 additions and 2 deletions

View File

@ -42,6 +42,8 @@ class Chunk{
public const COORD_BIT_SIZE = SubChunk::COORD_BIT_SIZE; public const COORD_BIT_SIZE = SubChunk::COORD_BIT_SIZE;
public const COORD_MASK = SubChunk::COORD_MASK; public const COORD_MASK = SubChunk::COORD_MASK;
private int $modificationCount;
/** @var int */ /** @var int */
private $terrainDirtyFlags = 0; private $terrainDirtyFlags = 0;
@ -68,7 +70,7 @@ class Chunk{
/** /**
* @param SubChunk[] $subChunks * @param SubChunk[] $subChunks
*/ */
public function __construct(array $subChunks, BiomeArray $biomeIds, bool $terrainPopulated){ public function __construct(array $subChunks, BiomeArray $biomeIds, bool $terrainPopulated, int $modificationCount = 0){
$this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS); $this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS);
foreach($this->subChunks as $y => $null){ foreach($this->subChunks as $y => $null){
@ -80,6 +82,7 @@ class Chunk{
$this->biomeIds = $biomeIds; $this->biomeIds = $biomeIds;
$this->terrainPopulated = $terrainPopulated; $this->terrainPopulated = $terrainPopulated;
$this->modificationCount = $modificationCount;
} }
/** /**
@ -108,6 +111,7 @@ class Chunk{
public function setFullBlock(int $x, int $y, int $z, int $block) : void{ public function setFullBlock(int $x, int $y, int $z, int $block) : void{
$this->getSubChunk($y >> SubChunk::COORD_BIT_SIZE)->setFullBlock($x, $y & SubChunk::COORD_MASK, $z, $block); $this->getSubChunk($y >> SubChunk::COORD_BIT_SIZE)->setFullBlock($x, $y & SubChunk::COORD_MASK, $z, $block);
$this->terrainDirtyFlags |= self::DIRTY_FLAG_TERRAIN; $this->terrainDirtyFlags |= self::DIRTY_FLAG_TERRAIN;
$this->modificationCount++;
} }
/** /**
@ -171,6 +175,7 @@ class Chunk{
public function setBiomeId(int $x, int $z, int $biomeId) : void{ public function setBiomeId(int $x, int $z, int $biomeId) : void{
$this->biomeIds->set($x, $z, $biomeId); $this->biomeIds->set($x, $z, $biomeId);
$this->terrainDirtyFlags |= self::DIRTY_FLAG_BIOMES; $this->terrainDirtyFlags |= self::DIRTY_FLAG_BIOMES;
$this->modificationCount++;
} }
public function isLightPopulated() : ?bool{ public function isLightPopulated() : ?bool{
@ -188,6 +193,7 @@ class Chunk{
public function setPopulated(bool $value = true) : void{ public function setPopulated(bool $value = true) : void{
$this->terrainPopulated = $value; $this->terrainPopulated = $value;
$this->terrainDirtyFlags |= self::DIRTY_FLAG_TERRAIN; $this->terrainDirtyFlags |= self::DIRTY_FLAG_TERRAIN;
$this->modificationCount++;
} }
public function addTile(Tile $tile) : void{ public function addTile(Tile $tile) : void{
@ -270,16 +276,24 @@ class Chunk{
}else{ }else{
$this->terrainDirtyFlags &= ~$flag; $this->terrainDirtyFlags &= ~$flag;
} }
$this->modificationCount++;
} }
public function setTerrainDirty() : void{ public function setTerrainDirty() : void{
$this->terrainDirtyFlags = ~0; $this->terrainDirtyFlags = ~0;
$this->modificationCount++;
} }
public function clearTerrainDirtyFlags() : void{ public function clearTerrainDirtyFlags() : void{
$this->terrainDirtyFlags = 0; $this->terrainDirtyFlags = 0;
} }
/**
* Returns the modcount for this chunk. Any saveable change to the chunk will cause this number to be incremented,
* so you can use this to detect when the chunk has been modified.
*/
public function getModificationCount() : int{ return $this->modificationCount; }
public function getSubChunk(int $y) : SubChunk{ public function getSubChunk(int $y) : SubChunk{
if($y < 0 || $y >= $this->subChunks->getSize()){ if($y < 0 || $y >= $this->subChunks->getSize()){
throw new \InvalidArgumentException("Invalid subchunk Y coordinate $y"); throw new \InvalidArgumentException("Invalid subchunk Y coordinate $y");

View File

@ -51,6 +51,8 @@ final class FastChunkSerializer{
*/ */
public static function serializeTerrain(Chunk $chunk) : string{ public static function serializeTerrain(Chunk $chunk) : string{
$stream = new BinaryStream(); $stream = new BinaryStream();
$stream->putLong($chunk->getModificationCount());
$stream->putByte( $stream->putByte(
($chunk->isPopulated() ? self::FLAG_POPULATED : 0) ($chunk->isPopulated() ? self::FLAG_POPULATED : 0)
); );
@ -88,6 +90,7 @@ final class FastChunkSerializer{
*/ */
public static function deserializeTerrain(string $data) : Chunk{ public static function deserializeTerrain(string $data) : Chunk{
$stream = new BinaryStream($data); $stream = new BinaryStream($data);
$modificationCounter = $stream->getLong();
$flags = $stream->getByte(); $flags = $stream->getByte();
$terrainPopulated = (bool) ($flags & self::FLAG_POPULATED); $terrainPopulated = (bool) ($flags & self::FLAG_POPULATED);
@ -115,6 +118,6 @@ final class FastChunkSerializer{
$biomeIds = new BiomeArray($stream->get(256)); $biomeIds = new BiomeArray($stream->get(256));
return new Chunk($subChunks, $biomeIds, $terrainPopulated); return new Chunk($subChunks, $biomeIds, $terrainPopulated, $modificationCounter);
} }
} }