diff --git a/src/world/World.php b/src/world/World.php index 3b5d12ffa..a4bd8e81a 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2813,13 +2813,15 @@ class World implements ChunkManager{ $this->chunkPopulationRequestMap[$index] = $promise; } + $temporaryChunkLoader = new class implements ChunkLoader{}; for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ $this->lockChunk($x + $xx, $z + $zz); + $this->registerChunkLoader($temporaryChunkLoader, $x + $xx, $z + $zz); } } - $task = new PopulationTask($this, $x, $z, $chunk); + $task = new PopulationTask($this, $x, $z, $chunk, $temporaryChunkLoader); $workerId = $this->workerPool->selectWorker(); if(!isset($this->generatorRegisteredWorkers[$workerId])){ $this->registerGeneratorToWorker($workerId); @@ -2840,8 +2842,15 @@ class World implements ChunkManager{ * @param Chunk[] $adjacentChunks * @phpstan-param array $adjacentChunks */ - public function generateChunkCallback(int $x, int $z, Chunk $chunk, array $adjacentChunks) : void{ + public function generateChunkCallback(int $x, int $z, Chunk $chunk, array $adjacentChunks, ChunkLoader $temporaryChunkLoader) : void{ Timings::$generationCallback->startTiming(); + + for($xx = -1; $xx <= 1; ++$xx){ + for($zz = -1; $zz <= 1; ++$zz){ + $this->unregisterChunkLoader($temporaryChunkLoader, $x + $xx, $z + $zz); + } + } + if(isset($this->chunkPopulationRequestMap[$index = World::chunkHash($x, $z)]) && isset($this->activeChunkPopulationTasks[$index])){ for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index e3bccbbfb..19c0038fa 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -26,6 +26,7 @@ namespace pocketmine\world\generator; use pocketmine\data\bedrock\BiomeIds; use pocketmine\scheduler\AsyncTask; use pocketmine\utils\AssumptionFailedError; +use pocketmine\world\ChunkLoader; use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; @@ -38,6 +39,7 @@ use function intdiv; class PopulationTask extends AsyncTask{ private const TLS_KEY_WORLD = "world"; + private const TLS_KEY_CHUNK_LOADER = "chunkLoader"; /** @var int */ public $worldId; @@ -51,7 +53,7 @@ class PopulationTask extends AsyncTask{ private string $adjacentChunks; - public function __construct(World $world, int $chunkX, int $chunkZ, ?Chunk $chunk){ + public function __construct(World $world, int $chunkX, int $chunkZ, ?Chunk $chunk, ChunkLoader $temporaryChunkLoader){ $this->worldId = $world->getId(); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; @@ -63,6 +65,7 @@ class PopulationTask extends AsyncTask{ )) ?? throw new AssumptionFailedError("igbinary_serialize() returned null"); $this->storeLocal(self::TLS_KEY_WORLD, $world); + $this->storeLocal(self::TLS_KEY_CHUNK_LOADER, $temporaryChunkLoader); } public function onRun() : void{ @@ -126,6 +129,8 @@ class PopulationTask extends AsyncTask{ public function onCompletion() : void{ /** @var World $world */ $world = $this->fetchLocal(self::TLS_KEY_WORLD); + /** @var ChunkLoader $temporaryChunkLoader */ + $temporaryChunkLoader = $this->fetchLocal(self::TLS_KEY_CHUNK_LOADER); if($world->isLoaded()){ $chunk = $this->chunk !== null ? FastChunkSerializer::deserializeTerrain($this->chunk) : @@ -146,7 +151,7 @@ class PopulationTask extends AsyncTask{ } } - $world->generateChunkCallback($this->chunkX, $this->chunkZ, $chunk, $adjacentChunks); + $world->generateChunkCallback($this->chunkX, $this->chunkZ, $chunk, $adjacentChunks, $temporaryChunkLoader); } } }