mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-09 11:31:49 +00:00
LightPopulationTask no longer hard-depends on Server
This commit is contained in:
parent
ebd19f5a70
commit
b31b097b8e
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 */
|
|
||||||
$world = $this->fetchLocal(self::TLS_KEY_WORLD);
|
|
||||||
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 int[] $heightMapArray */
|
||||||
$heightMapArray = igbinary_unserialize($this->resultHeightMap);
|
$heightMapArray = igbinary_unserialize($this->resultHeightMap);
|
||||||
$chunk->setHeightMapArray($heightMapArray);
|
|
||||||
|
|
||||||
/** @var LightArray[] $skyLightArrays */
|
/** @var LightArray[] $skyLightArrays */
|
||||||
$skyLightArrays = igbinary_unserialize($this->resultSkyLightArrays);
|
$skyLightArrays = igbinary_unserialize($this->resultSkyLightArrays);
|
||||||
/** @var LightArray[] $blockLightArrays */
|
/** @var LightArray[] $blockLightArrays */
|
||||||
$blockLightArrays = igbinary_unserialize($this->resultBlockLightArrays);
|
$blockLightArrays = igbinary_unserialize($this->resultBlockLightArrays);
|
||||||
|
|
||||||
foreach($skyLightArrays as $y => $array){
|
/**
|
||||||
$chunk->getSubChunk($y)->setBlockSkyLightArray($array);
|
* @var \Closure
|
||||||
}
|
* @phpstan-var \Closure(array<int, LightArray> $blockLight, array<int, LightArray> $skyLight, array<int, int> $heightMap>) : void
|
||||||
foreach($blockLightArrays as $y => $array){
|
*/
|
||||||
$chunk->getSubChunk($y)->setBlockLightArray($array);
|
$callback = $this->fetchLocal(self::TLS_KEY_COMPLETION_CALLBACK);
|
||||||
}
|
$callback($blockLightArrays, $skyLightArrays, $heightMapArray);
|
||||||
$chunk->setLightPopulated();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user