BlockFactory: change property cache arrays to use regular arrays instead of SplFixedArray

this does come at a performance cost, but is necessary for metadata expansion.

we finally concede that this is not going to happen without BC breaks, however small they might be ...
This commit is contained in:
Dylan K. Taylor
2022-03-23 15:22:57 +00:00
parent b52bb5016c
commit 334c9daa6a
6 changed files with 55 additions and 58 deletions

View File

@ -35,18 +35,18 @@ use function max;
class SkyLightUpdate extends LightUpdate{
/**
* @var \SplFixedArray|bool[]
* @phpstan-var \SplFixedArray<bool>
* @var true[]
* @phpstan-var array<int, true>
*/
private $directSkyLightBlockers;
/**
* @param \SplFixedArray|int[] $lightFilters
* @param \SplFixedArray|bool[] $directSkyLightBlockers
* @phpstan-param \SplFixedArray<int> $lightFilters
* @phpstan-param \SplFixedArray<bool> $directSkyLightBlockers
* @param int[] $lightFilters
* @param true[] $directSkyLightBlockers
* @phpstan-param array<int, int> $lightFilters
* @phpstan-param array<int, true> $directSkyLightBlockers
*/
public function __construct(SubChunkExplorer $subChunkExplorer, \SplFixedArray $lightFilters, \SplFixedArray $directSkyLightBlockers){
public function __construct(SubChunkExplorer $subChunkExplorer, array $lightFilters, array $directSkyLightBlockers){
parent::__construct($subChunkExplorer, $lightFilters);
$this->directSkyLightBlockers = $directSkyLightBlockers;
}
@ -78,7 +78,7 @@ class SkyLightUpdate extends LightUpdate{
$newHeightMap = self::recalculateHeightMapColumn($chunk, $x & Chunk::COORD_MASK, $z & Chunk::COORD_MASK, $this->directSkyLightBlockers);
$chunk->setHeightMap($x & Chunk::COORD_MASK, $z & Chunk::COORD_MASK, $newHeightMap);
}elseif($yPlusOne > $oldHeightMap){ //Block changed above the heightmap.
if($this->directSkyLightBlockers[$source]){
if(isset($this->directSkyLightBlockers[$source])){
$chunk->setHeightMap($x & Chunk::COORD_MASK, $z & Chunk::COORD_MASK, $yPlusOne);
$newHeightMap = $yPlusOne;
}else{ //Block changed which has no effect on direct sky light, for example placing or removing glass.
@ -97,7 +97,7 @@ class SkyLightUpdate extends LightUpdate{
$this->setAndUpdateLight($x, $i, $z, 15);
}
}else{ //No heightmap change, block changed "underground"
$this->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$source]));
$this->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentLight($x, $y, $z) - ($this->lightFilters[$source] ?? self::BASE_LIGHT_FILTER)));
}
}
@ -168,10 +168,10 @@ class SkyLightUpdate extends LightUpdate{
/**
* Recalculates the heightmap for the whole chunk.
*
* @param \SplFixedArray|bool[] $directSkyLightBlockers
* @phpstan-param \SplFixedArray<bool> $directSkyLightBlockers
* @param true[] $directSkyLightBlockers
* @phpstan-param array<int, true> $directSkyLightBlockers
*/
private static function recalculateHeightMap(Chunk $chunk, \SplFixedArray $directSkyLightBlockers) : HeightArray{
private static function recalculateHeightMap(Chunk $chunk, array $directSkyLightBlockers) : HeightArray{
$maxSubChunkY = Chunk::MAX_SUBCHUNK_INDEX;
for(; $maxSubChunkY >= Chunk::MIN_SUBCHUNK_INDEX; $maxSubChunkY--){
if(!$chunk->getSubChunk($maxSubChunkY)->isEmptyFast()){
@ -198,7 +198,7 @@ class SkyLightUpdate extends LightUpdate{
$result->set($x, $z, World::Y_MIN);
}else{
for(; $y >= World::Y_MIN; --$y){
if($directSkyLightBlockers[$chunk->getFullBlock($x, $y, $z)]){
if(isset($directSkyLightBlockers[$chunk->getFullBlock($x, $y, $z)])){
$result->set($x, $z, $y + 1);
break;
}
@ -214,18 +214,18 @@ class SkyLightUpdate extends LightUpdate{
*
* @param int $x 0-15
* @param int $z 0-15
* @param \SplFixedArray|bool[] $directSkyLightBlockers
* @phpstan-param \SplFixedArray<bool> $directSkyLightBlockers
* @param true[] $directSkyLightBlockers
* @phpstan-param array<int, true> $directSkyLightBlockers
*
* @return int New calculated heightmap value (0-256 inclusive)
*/
private static function recalculateHeightMapColumn(Chunk $chunk, int $x, int $z, \SplFixedArray $directSkyLightBlockers) : int{
private static function recalculateHeightMapColumn(Chunk $chunk, int $x, int $z, array $directSkyLightBlockers) : int{
$y = $chunk->getHighestBlockAt($x, $z);
if($y === null){
return World::Y_MIN;
}
for(; $y >= World::Y_MIN; --$y){
if($directSkyLightBlockers[$chunk->getFullBlock($x, $y, $z)]){
if(isset($directSkyLightBlockers[$chunk->getFullBlock($x, $y, $z)])){
break;
}
}