Region: Remove RegionLoader/McRegion cyclic dependency

This commit is contained in:
Dylan K. Taylor 2017-12-30 19:59:35 +00:00
parent 1e896efff9
commit 66e475cbb8
2 changed files with 19 additions and 25 deletions

View File

@ -315,7 +315,7 @@ class McRegion extends BaseLevelProvider{
if(!$chunk->isGenerated()){ if(!$chunk->isGenerated()){
throw new \InvalidStateException("Cannot save un-generated chunk"); throw new \InvalidStateException("Cannot save un-generated chunk");
} }
$this->getRegion($chunkX >> 5, $chunkZ >> 5)->writeChunk($chunk); $this->getRegion($chunkX >> 5, $chunkZ >> 5)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->nbtSerialize($chunk));
return true; return true;
} }
@ -341,7 +341,13 @@ class McRegion extends BaseLevelProvider{
$this->loadRegion($regionX, $regionZ); $this->loadRegion($regionX, $regionZ);
$this->level->timings->syncChunkLoadDataTimer->startTiming(); $this->level->timings->syncChunkLoadDataTimer->startTiming();
$chunk = $this->getRegion($regionX, $regionZ)->readChunk($chunkX & 0x1f, $chunkZ & 0x1f); $chunk = null;
$chunkData = $this->getRegion($regionX, $regionZ)->readChunk($chunkX & 0x1f, $chunkZ & 0x1f);
if($chunkData !== null){
$chunk = $this->nbtDeserialize($chunkData);
}
if($chunk === null and $create){ if($chunk === null and $create){
$chunk = new Chunk($chunkX, $chunkZ); $chunk = new Chunk($chunkX, $chunkZ);
} }
@ -434,7 +440,7 @@ class McRegion extends BaseLevelProvider{
*/ */
protected function loadRegion(int $regionX, int $regionZ){ protected function loadRegion(int $regionX, int $regionZ){
if(!isset($this->regions[$index = Level::chunkHash($regionX, $regionZ)])){ if(!isset($this->regions[$index = Level::chunkHash($regionX, $regionZ)])){
$this->regions[$index] = new RegionLoader($this, $regionX, $regionZ, static::REGION_FILE_EXTENSION); $this->regions[$index] = new RegionLoader($this->getPath() . "region/r.$regionX.$regionZ." . static::REGION_FILE_EXTENSION, $regionX, $regionZ);
try{ try{
$this->regions[$index]->open(); $this->regions[$index]->open();
}catch(CorruptedRegionException $e){ }catch(CorruptedRegionException $e){
@ -448,7 +454,7 @@ class McRegion extends BaseLevelProvider{
rename($path, $backupPath); rename($path, $backupPath);
$logger->error("Corrupted region file has been backed up to " . $backupPath); $logger->error("Corrupted region file has been backed up to " . $backupPath);
$this->regions[$index] = new RegionLoader($this, $regionX, $regionZ, static::REGION_FILE_EXTENSION); $this->regions[$index] = new RegionLoader($this->getPath() . "region/r.$regionX.$regionZ." . static::REGION_FILE_EXTENSION, $regionX, $regionZ);
$this->regions[$index]->open(); //this will create a new empty region to replace the corrupted one $this->regions[$index]->open(); //this will create a new empty region to replace the corrupted one
} }
} }

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\level\format\io\region; namespace pocketmine\level\format\io\region;
use pocketmine\level\format\Chunk;
use pocketmine\level\format\ChunkException; use pocketmine\level\format\ChunkException;
use pocketmine\utils\Binary; use pocketmine\utils\Binary;
use pocketmine\utils\MainLogger; use pocketmine\utils\MainLogger;
@ -49,18 +48,15 @@ class RegionLoader{
protected $filePointer; protected $filePointer;
/** @var int */ /** @var int */
protected $lastSector; protected $lastSector;
/** @var McRegion */
protected $levelProvider;
/** @var int[][] [offset in sectors, chunk size in sectors, timestamp] */ /** @var int[][] [offset in sectors, chunk size in sectors, timestamp] */
protected $locationTable = []; protected $locationTable = [];
/** @var int */ /** @var int */
public $lastUsed = 0; public $lastUsed = 0;
public function __construct(McRegion $level, int $regionX, int $regionZ, string $fileExtension = McRegion::REGION_FILE_EXTENSION){ public function __construct(string $filePath, int $regionX, int $regionZ){
$this->x = $regionX; $this->x = $regionX;
$this->z = $regionZ; $this->z = $regionZ;
$this->levelProvider = $level; $this->filePath = $filePath;
$this->filePath = $this->levelProvider->getPath() . "region/r.$regionX.$regionZ.$fileExtension";
} }
public function open(){ public function open(){
@ -99,7 +95,7 @@ class RegionLoader{
return !($this->locationTable[$index][0] === 0 or $this->locationTable[$index][1] === 0); return !($this->locationTable[$index][0] === 0 or $this->locationTable[$index][1] === 0);
} }
public function readChunk(int $x, int $z){ public function readChunk(int $x, int $z) : ?string{
$index = self::getChunkOffset($x, $z); $index = self::getChunkOffset($x, $z);
if($index < 0 or $index >= 4096){ if($index < 0 or $index >= 4096){
return null; return null;
@ -133,9 +129,9 @@ class RegionLoader{
return null; return null;
} }
$chunk = $this->levelProvider->nbtDeserialize(fread($this->filePointer, $length - 1)); $chunkData = fread($this->filePointer, $length - 1);
if($chunk instanceof Chunk){ if($chunkData !== false){
return $chunk; return $chunkData;
}else{ }else{
MainLogger::getLogger()->error("Corrupted chunk detected"); MainLogger::getLogger()->error("Corrupted chunk detected");
return null; return null;
@ -146,7 +142,9 @@ class RegionLoader{
return $this->isChunkGenerated(self::getChunkOffset($x, $z)); return $this->isChunkGenerated(self::getChunkOffset($x, $z));
} }
protected function saveChunk(int $x, int $z, string $chunkData){ public function writeChunk(int $x, int $z, string $chunkData){
$this->lastUsed = time();
$length = strlen($chunkData) + 1; $length = strlen($chunkData) + 1;
if($length + 4 > self::MAX_SECTOR_LENGTH){ if($length + 4 > self::MAX_SECTOR_LENGTH){
throw new ChunkException("Chunk is too big! " . ($length + 4) . " > " . self::MAX_SECTOR_LENGTH); throw new ChunkException("Chunk is too big! " . ($length + 4) . " > " . self::MAX_SECTOR_LENGTH);
@ -179,14 +177,6 @@ class RegionLoader{
$this->locationTable[$index][1] = 0; $this->locationTable[$index][1] = 0;
} }
public function writeChunk(Chunk $chunk){
$this->lastUsed = time();
$chunkData = $this->levelProvider->nbtSerialize($chunk);
if($chunkData !== false){
$this->saveChunk($chunk->getX() & 0x1f, $chunk->getZ() & 0x1f, $chunkData);
}
}
protected static function getChunkOffset(int $x, int $z) : int{ protected static function getChunkOffset(int $x, int $z) : int{
return $x + ($z << 5); return $x + ($z << 5);
} }
@ -204,8 +194,6 @@ class RegionLoader{
fclose($this->filePointer); fclose($this->filePointer);
} }
$this->levelProvider = null;
} }
public function doSlowCleanUp() : int{ public function doSlowCleanUp() : int{