LightPopulationTask no longer hard-depends on Server

This commit is contained in:
Dylan K. Taylor 2021-04-16 15:41:14 +01:00
parent ebd19f5a70
commit b31b097b8e
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
2 changed files with 46 additions and 33 deletions

View File

@ -74,6 +74,7 @@ use pocketmine\world\biome\BiomeRegistry;
use pocketmine\world\format\Chunk; use pocketmine\world\format\Chunk;
use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\exception\CorruptedChunkException;
use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\format\io\WritableWorldProvider;
use pocketmine\world\format\LightArray;
use pocketmine\world\generator\GeneratorManager; use pocketmine\world\generator\GeneratorManager;
use pocketmine\world\generator\GeneratorRegisterTask; use pocketmine\world\generator\GeneratorRegisterTask;
use pocketmine\world\generator\GeneratorUnregisterTask; use pocketmine\world\generator\GeneratorUnregisterTask;
@ -1001,7 +1002,31 @@ class World implements ChunkManager{
if($lightPopulatedState !== true){ if($lightPopulatedState !== true){
if($lightPopulatedState === false){ if($lightPopulatedState === false){
$this->chunks[$hash]->setLightPopulated(null); $this->chunks[$hash]->setLightPopulated(null);
$this->workerPool->submitTask(new LightPopulationTask($this, $dx + $chunkX, $dz + $chunkZ, $this->chunks[$hash]));
$this->workerPool->submitTask(new LightPopulationTask(
$this->chunks[$hash],
function(array $blockLight, array $skyLight, array $heightMap) use ($dx, $chunkX, $dz, $chunkZ) : void{
/**
* TODO: phpstan can't infer these types yet :(
* @phpstan-var array<int, LightArray> $blockLight
* @phpstan-var array<int, LightArray> $skyLight
* @phpstan-var array<int, int> $heightMap
*/
if($this->closed || ($chunk = $this->getChunk($dx + $chunkX, $dz + $chunkZ)) === null || $chunk->isLightPopulated() === true){
return;
}
//TODO: calculated light information might not be valid if the terrain changed during light calculation
$chunk->setHeightMapArray($heightMap);
foreach($blockLight as $y => $lightArray){
$chunk->getSubChunk($y)->setBlockLightArray($lightArray);
}
foreach($skyLight as $y => $lightArray){
$chunk->getSubChunk($y)->setBlockSkyLightArray($lightArray);
}
$chunk->setLightPopulated(true);
}
));
} }
continue; continue;
} }

View File

@ -35,16 +35,11 @@ use function igbinary_serialize;
use function igbinary_unserialize; use function igbinary_unserialize;
class LightPopulationTask extends AsyncTask{ class LightPopulationTask extends AsyncTask{
private const TLS_KEY_WORLD = "world"; private const TLS_KEY_COMPLETION_CALLBACK = "onCompletion";
/** @var string */ /** @var string */
public $chunk; public $chunk;
/** @var int */
private $chunkX;
/** @var int */
private $chunkZ;
/** @var string */ /** @var string */
private $resultHeightMap; private $resultHeightMap;
/** @var string */ /** @var string */
@ -52,25 +47,26 @@ class LightPopulationTask extends AsyncTask{
/** @var string */ /** @var string */
private $resultBlockLightArrays; private $resultBlockLightArrays;
public function __construct(World $world, int $chunkX, int $chunkZ, Chunk $chunk){ /**
$this->storeLocal(self::TLS_KEY_WORLD, $world); * @phpstan-param \Closure(array<int, LightArray> $blockLight, array<int, LightArray> $skyLight, array<int, int> $heightMap) : void $onCompletion
[$this->chunkX, $this->chunkZ] = [$chunkX, $chunkZ]; */
$chunk->setLightPopulated(null); public function __construct(Chunk $chunk, \Closure $onCompletion){
$this->chunk = FastChunkSerializer::serialize($chunk); $this->chunk = FastChunkSerializer::serialize($chunk);
$this->storeLocal(self::TLS_KEY_COMPLETION_CALLBACK, $onCompletion);
} }
public function onRun() : void{ public function onRun() : void{
$chunk = FastChunkSerializer::deserialize($this->chunk); $chunk = FastChunkSerializer::deserialize($this->chunk);
$manager = new SimpleChunkManager(World::Y_MIN, World::Y_MAX); $manager = new SimpleChunkManager(World::Y_MIN, World::Y_MAX);
$manager->setChunk($this->chunkX, $this->chunkZ, $chunk); $manager->setChunk(0, 0, $chunk);
$blockFactory = BlockFactory::getInstance(); $blockFactory = BlockFactory::getInstance();
foreach([ foreach([
"Block" => new BlockLightUpdate(new SubChunkExplorer($manager), $blockFactory->lightFilter, $blockFactory->light), "Block" => new BlockLightUpdate(new SubChunkExplorer($manager), $blockFactory->lightFilter, $blockFactory->light),
"Sky" => new SkyLightUpdate(new SubChunkExplorer($manager), $blockFactory->lightFilter, $blockFactory->blocksDirectSkyLight), "Sky" => new SkyLightUpdate(new SubChunkExplorer($manager), $blockFactory->lightFilter, $blockFactory->blocksDirectSkyLight),
] as $name => $update){ ] as $name => $update){
$update->recalculateChunk($this->chunkX, $this->chunkZ); $update->recalculateChunk(0, 0);
$update->execute(); $update->execute();
} }
@ -88,27 +84,19 @@ class LightPopulationTask extends AsyncTask{
} }
public function onCompletion() : void{ public function onCompletion() : void{
/** @var World $world */ /** @var int[] $heightMapArray */
$world = $this->fetchLocal(self::TLS_KEY_WORLD); $heightMapArray = igbinary_unserialize($this->resultHeightMap);
if(!$world->isClosed() and ($chunk = $world->getChunk($this->chunkX, $this->chunkZ)) !== null){
//TODO: calculated light information might not be valid if the terrain changed during light calculation
/** @var int[] $heightMapArray */ /** @var LightArray[] $skyLightArrays */
$heightMapArray = igbinary_unserialize($this->resultHeightMap); $skyLightArrays = igbinary_unserialize($this->resultSkyLightArrays);
$chunk->setHeightMapArray($heightMapArray); /** @var LightArray[] $blockLightArrays */
$blockLightArrays = igbinary_unserialize($this->resultBlockLightArrays);
/** @var LightArray[] $skyLightArrays */ /**
$skyLightArrays = igbinary_unserialize($this->resultSkyLightArrays); * @var \Closure
/** @var LightArray[] $blockLightArrays */ * @phpstan-var \Closure(array<int, LightArray> $blockLight, array<int, LightArray> $skyLight, array<int, int> $heightMap>) : void
$blockLightArrays = igbinary_unserialize($this->resultBlockLightArrays); */
$callback = $this->fetchLocal(self::TLS_KEY_COMPLETION_CALLBACK);
foreach($skyLightArrays as $y => $array){ $callback($blockLightArrays, $skyLightArrays, $heightMapArray);
$chunk->getSubChunk($y)->setBlockSkyLightArray($array);
}
foreach($blockLightArrays as $y => $array){
$chunk->getSubChunk($y)->setBlockLightArray($array);
}
$chunk->setLightPopulated();
}
} }
} }