Remove $create parameter from ChunkManager::getChunk()

this restores SimpleChunkManager's behaviour to PM3, removing the need for GeneratorChunkManager (although I'm dubious whether SubChunkExplorer makes any sense in there any more now that we have morton in the mix).
This commit is contained in:
Dylan K. Taylor 2020-10-31 21:54:51 +00:00
parent dec235abab
commit ddda2d1e64
11 changed files with 27 additions and 68 deletions

View File

@ -40,7 +40,7 @@ interface ChunkManager{
*/ */
public function setBlockAt(int $x, int $y, int $z, Block $block) : void; public function setBlockAt(int $x, int $y, int $z, Block $block) : void;
public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk; public function getChunk(int $chunkX, int $chunkZ) : ?Chunk;
public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk) : void; public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk) : void;

View File

@ -124,7 +124,7 @@ class Explosion{
$pointerY += $shiftY; $pointerY += $shiftY;
$pointerZ += $shiftZ; $pointerZ += $shiftZ;
if($this->subChunkExplorer->moveTo($vBlockX, $vBlockY, $vBlockZ, false) === SubChunkExplorerStatus::INVALID){ if($this->subChunkExplorer->moveTo($vBlockX, $vBlockY, $vBlockZ) === SubChunkExplorerStatus::INVALID){
continue; continue;
} }

View File

@ -51,14 +51,14 @@ class SimpleChunkManager implements ChunkManager{
} }
public function getBlockAt(int $x, int $y, int $z) : Block{ public function getBlockAt(int $x, int $y, int $z) : Block{
if($this->terrainPointer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ if($this->terrainPointer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){
return BlockFactory::getInstance()->fromFullBlock($this->terrainPointer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf)); return BlockFactory::getInstance()->fromFullBlock($this->terrainPointer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf));
} }
return VanillaBlocks::AIR(); return VanillaBlocks::AIR();
} }
public function setBlockAt(int $x, int $y, int $z, Block $block) : void{ public function setBlockAt(int $x, int $y, int $z, Block $block) : void{
if($this->terrainPointer->moveTo($x, $y, $z, true) !== SubChunkExplorerStatus::INVALID){ if($this->terrainPointer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){
$this->terrainPointer->currentSubChunk->setFullBlock($x & 0xf, $y & 0xf, $z & 0xf, $block->getFullId()); $this->terrainPointer->currentSubChunk->setFullBlock($x & 0xf, $y & 0xf, $z & 0xf, $block->getFullId());
$this->terrainPointer->currentChunk->setDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); $this->terrainPointer->currentChunk->setDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true);
}else{ }else{
@ -66,9 +66,8 @@ class SimpleChunkManager implements ChunkManager{
} }
} }
public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{ public function getChunk(int $chunkX, int $chunkZ) : ?Chunk{
$hash = World::chunkHash($chunkX, $chunkZ); return $this->chunks[World::chunkHash($chunkX, $chunkZ)] ?? null;
return $this->chunks[$hash] ?? ($create ? $this->chunks[$hash] = new Chunk($chunkX, $chunkZ) : null);
} }
public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk) : void{ public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk) : void{

View File

@ -1839,7 +1839,7 @@ class World implements ChunkManager{
* @return int 0-15 * @return int 0-15
*/ */
public function getPotentialBlockSkyLightAt(int $x, int $y, int $z) : int{ public function getPotentialBlockSkyLightAt(int $x, int $y, int $z) : int{
if(($chunk = $this->getChunk($x >> 4, $z >> 4, false)) !== null){ if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){
return $chunk->getSubChunk($y >> 4)->getBlockSkyLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); return $chunk->getSubChunk($y >> 4)->getBlockSkyLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f);
} }
return 0; //TODO: this should probably throw instead (light not calculated yet) return 0; //TODO: this should probably throw instead (light not calculated yet)
@ -1851,7 +1851,7 @@ class World implements ChunkManager{
* @return int 0-15 * @return int 0-15
*/ */
public function getBlockLightAt(int $x, int $y, int $z) : int{ public function getBlockLightAt(int $x, int $y, int $z) : int{
if(($chunk = $this->getChunk($x >> 4, $z >> 4, false)) !== null){ if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){
return $chunk->getSubChunk($y >> 4)->getBlockLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); return $chunk->getSubChunk($y >> 4)->getBlockLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f);
} }
return 0; //TODO: this should probably throw instead (light not calculated yet) return 0; //TODO: this should probably throw instead (light not calculated yet)
@ -1895,12 +1895,8 @@ class World implements ChunkManager{
return null; return null;
} }
public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{ public function getChunk(int $chunkX, int $chunkZ) : ?Chunk{
$hash = World::chunkHash($chunkX, $chunkZ); return $this->chunks[World::chunkHash($chunkX, $chunkZ)] ?? null;
if(isset($this->chunks[$hash])){
return $this->chunks[$hash];
}
return $create ? ($this->chunks[$hash] = new Chunk($chunkX, $chunkZ)) : null;
} }
/** /**

View File

@ -1,38 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\world\generator;
use pocketmine\world\format\Chunk;
use pocketmine\world\SimpleChunkManager;
use pocketmine\world\World;
class GeneratorChunkManager extends SimpleChunkManager{
public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{
if(!isset($this->chunks[World::chunkHash($chunkX, $chunkZ)])){
throw new \InvalidArgumentException("Chunk does not exist");
}
return parent::getChunk($chunkX, $chunkZ, $create);
}
}

View File

@ -25,6 +25,7 @@ namespace pocketmine\world\generator;
use pocketmine\scheduler\AsyncTask; use pocketmine\scheduler\AsyncTask;
use pocketmine\world\biome\Biome; use pocketmine\world\biome\Biome;
use pocketmine\world\SimpleChunkManager;
use pocketmine\world\World; use pocketmine\world\World;
use function igbinary_serialize; use function igbinary_serialize;
use function igbinary_unserialize; use function igbinary_unserialize;
@ -56,7 +57,7 @@ class GeneratorRegisterTask extends AsyncTask{
public function onRun() : void{ public function onRun() : void{
Biome::init(); Biome::init();
$manager = new GeneratorChunkManager($this->worldHeight); $manager = new SimpleChunkManager($this->worldHeight);
$this->worker->saveToThreadStore("generation.world{$this->worldId}.manager", $manager); $this->worker->saveToThreadStore("generation.world{$this->worldId}.manager", $manager);
/** /**

View File

@ -26,6 +26,7 @@ namespace pocketmine\world\generator;
use pocketmine\scheduler\AsyncTask; use pocketmine\scheduler\AsyncTask;
use pocketmine\world\format\Chunk; use pocketmine\world\format\Chunk;
use pocketmine\world\format\io\FastChunkSerializer; use pocketmine\world\format\io\FastChunkSerializer;
use pocketmine\world\SimpleChunkManager;
use pocketmine\world\World; use pocketmine\world\World;
class PopulationTask extends AsyncTask{ class PopulationTask extends AsyncTask{
@ -73,7 +74,7 @@ class PopulationTask extends AsyncTask{
public function onRun() : void{ public function onRun() : void{
$manager = $this->worker->getFromThreadStore("generation.world{$this->worldId}.manager"); $manager = $this->worker->getFromThreadStore("generation.world{$this->worldId}.manager");
$generator = $this->worker->getFromThreadStore("generation.world{$this->worldId}.generator"); $generator = $this->worker->getFromThreadStore("generation.world{$this->worldId}.generator");
if(!($manager instanceof GeneratorChunkManager) or !($generator instanceof Generator)){ if(!($manager instanceof SimpleChunkManager) or !($generator instanceof Generator)){
$this->state = false; $this->state = false;
return; return;
} }

View File

@ -53,14 +53,14 @@ class BlockLightUpdate extends LightUpdate{
} }
public function recalculateNode(int $x, int $y, int $z) : void{ public function recalculateNode(int $x, int $y, int $z) : void{
if($this->subChunkExplorer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ if($this->subChunkExplorer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){
$block = $this->subChunkExplorer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf); $block = $this->subChunkExplorer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf);
$this->setAndUpdateLight($x, $y, $z, max($this->lightEmitters[$block], $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$block])); $this->setAndUpdateLight($x, $y, $z, max($this->lightEmitters[$block], $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$block]));
} }
} }
public function recalculateChunk(int $chunkX, int $chunkZ) : int{ public function recalculateChunk(int $chunkX, int $chunkZ) : int{
if($this->subChunkExplorer->moveToChunk($chunkX, 0, $chunkZ, false) === SubChunkExplorerStatus::INVALID){ if($this->subChunkExplorer->moveToChunk($chunkX, 0, $chunkZ) === SubChunkExplorerStatus::INVALID){
throw new \InvalidArgumentException("Chunk $chunkX $chunkZ does not exist"); throw new \InvalidArgumentException("Chunk $chunkX $chunkZ does not exist");
} }
$chunk = $this->subChunkExplorer->currentChunk; $chunk = $this->subChunkExplorer->currentChunk;

View File

@ -68,7 +68,7 @@ abstract class LightUpdate{
abstract public function recalculateChunk(int $chunkX, int $chunkZ) : int; abstract public function recalculateChunk(int $chunkX, int $chunkZ) : int;
protected function getEffectiveLight(int $x, int $y, int $z) : int{ protected function getEffectiveLight(int $x, int $y, int $z) : int{
if($this->subChunkExplorer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ if($this->subChunkExplorer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){
return $this->getCurrentLightArray()->get($x & 0xf, $y & 0xf, $z & 0xf); return $this->getCurrentLightArray()->get($x & 0xf, $y & 0xf, $z & 0xf);
} }
return 0; return 0;
@ -98,7 +98,7 @@ abstract class LightUpdate{
private function prepareNodes() : LightPropagationContext{ private function prepareNodes() : LightPropagationContext{
$context = new LightPropagationContext(); $context = new LightPropagationContext();
foreach($this->updateNodes as $blockHash => [$x, $y, $z, $newLevel]){ foreach($this->updateNodes as $blockHash => [$x, $y, $z, $newLevel]){
if($this->subChunkExplorer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ if($this->subChunkExplorer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){
$lightArray = $this->getCurrentLightArray(); $lightArray = $this->getCurrentLightArray();
$oldLevel = $lightArray->get($x & 0xf, $y & 0xf, $z & 0xf); $oldLevel = $lightArray->get($x & 0xf, $y & 0xf, $z & 0xf);
@ -135,7 +135,7 @@ abstract class LightUpdate{
]; ];
foreach($points as [$cx, $cy, $cz]){ foreach($points as [$cx, $cy, $cz]){
if($this->subChunkExplorer->moveTo($cx, $cy, $cz, false) !== SubChunkExplorerStatus::INVALID){ if($this->subChunkExplorer->moveTo($cx, $cy, $cz) !== SubChunkExplorerStatus::INVALID){
$this->computeRemoveLight($cx, $cy, $cz, $oldAdjacentLight, $context); $this->computeRemoveLight($cx, $cy, $cz, $oldAdjacentLight, $context);
}elseif($this->getEffectiveLight($cx, $cy, $cz) > 0 and !isset($context->spreadVisited[$index = World::blockHash($cx, $cy, $cz)])){ }elseif($this->getEffectiveLight($cx, $cy, $cz) > 0 and !isset($context->spreadVisited[$index = World::blockHash($cx, $cy, $cz)])){
$context->spreadVisited[$index] = true; $context->spreadVisited[$index] = true;
@ -165,7 +165,7 @@ abstract class LightUpdate{
]; ];
foreach($points as [$cx, $cy, $cz]){ foreach($points as [$cx, $cy, $cz]){
if($this->subChunkExplorer->moveTo($cx, $cy, $cz, false) !== SubChunkExplorerStatus::INVALID){ if($this->subChunkExplorer->moveTo($cx, $cy, $cz) !== SubChunkExplorerStatus::INVALID){
$this->computeSpreadLight($cx, $cy, $cz, $newAdjacentLight, $context); $this->computeSpreadLight($cx, $cy, $cz, $newAdjacentLight, $context);
} }
} }

View File

@ -61,7 +61,7 @@ class SkyLightUpdate extends LightUpdate{
} }
public function recalculateNode(int $x, int $y, int $z) : void{ public function recalculateNode(int $x, int $y, int $z) : void{
if($this->subChunkExplorer->moveTo($x, $y, $z, false) === SubChunkExplorerStatus::INVALID){ if($this->subChunkExplorer->moveTo($x, $y, $z) === SubChunkExplorerStatus::INVALID){
return; return;
} }
$chunk = $this->subChunkExplorer->currentChunk; $chunk = $this->subChunkExplorer->currentChunk;
@ -98,7 +98,7 @@ class SkyLightUpdate extends LightUpdate{
} }
public function recalculateChunk(int $chunkX, int $chunkZ) : int{ public function recalculateChunk(int $chunkX, int $chunkZ) : int{
if($this->subChunkExplorer->moveToChunk($chunkX, 0, $chunkZ, false) === SubChunkExplorerStatus::INVALID){ if($this->subChunkExplorer->moveToChunk($chunkX, 0, $chunkZ) === SubChunkExplorerStatus::INVALID){
throw new \InvalidArgumentException("Chunk $chunkX $chunkZ does not exist"); throw new \InvalidArgumentException("Chunk $chunkX $chunkZ does not exist");
} }
$chunk = $this->subChunkExplorer->currentChunk; $chunk = $this->subChunkExplorer->currentChunk;
@ -151,7 +151,7 @@ class SkyLightUpdate extends LightUpdate{
$lightSources++; $lightSources++;
} }
for($y = $nodeColumnEnd + 1, $yMax = $lowestClearSubChunk * 16; $y < $yMax; $y++){ for($y = $nodeColumnEnd + 1, $yMax = $lowestClearSubChunk * 16; $y < $yMax; $y++){
if($this->subChunkExplorer->moveTo($x + $baseX, $y, $z + $baseZ, false) !== SubChunkExplorerStatus::INVALID){ if($this->subChunkExplorer->moveTo($x + $baseX, $y, $z + $baseZ) !== SubChunkExplorerStatus::INVALID){
$this->getCurrentLightArray()->set($x, $y & 0xf, $z, 15); $this->getCurrentLightArray()->set($x, $y & 0xf, $z, 15);
} }
} }

View File

@ -58,13 +58,13 @@ class SubChunkExplorer{
/** /**
* @phpstan-return SubChunkExplorerStatus::* * @phpstan-return SubChunkExplorerStatus::*
*/ */
public function moveTo(int $x, int $y, int $z, bool $create) : int{ public function moveTo(int $x, int $y, int $z) : int{
if($this->currentChunk === null or $this->currentX !== ($x >> 4) or $this->currentZ !== ($z >> 4)){ if($this->currentChunk === null or $this->currentX !== ($x >> 4) or $this->currentZ !== ($z >> 4)){
$this->currentX = $x >> 4; $this->currentX = $x >> 4;
$this->currentZ = $z >> 4; $this->currentZ = $z >> 4;
$this->currentSubChunk = null; $this->currentSubChunk = null;
$this->currentChunk = $this->world->getChunk($this->currentX, $this->currentZ, $create); $this->currentChunk = $this->world->getChunk($this->currentX, $this->currentZ);
if($this->currentChunk === null){ if($this->currentChunk === null){
return SubChunkExplorerStatus::INVALID; return SubChunkExplorerStatus::INVALID;
} }
@ -93,9 +93,9 @@ class SubChunkExplorer{
/** /**
* @phpstan-return SubChunkExplorerStatus::* * @phpstan-return SubChunkExplorerStatus::*
*/ */
public function moveToChunk(int $chunkX, int $chunkY, int $chunkZ, bool $create) : int{ public function moveToChunk(int $chunkX, int $chunkY, int $chunkZ) : int{
//this is a cold path, so we don't care much if it's a bit slower (extra fcall overhead) //this is a cold path, so we don't care much if it's a bit slower (extra fcall overhead)
return $this->moveTo($chunkX << 4, $chunkY << 4, $chunkZ << 4, $create); return $this->moveTo($chunkX << 4, $chunkY << 4, $chunkZ << 4);
} }
/** /**