mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-22 08:44:01 +00:00
LevelProvider: Remove cyclic dependency between Level and LevelProvider
This will now allow LevelProviders to be constructed on threads.
This commit is contained in:
parent
d19683b7dd
commit
1a615591e2
@ -343,7 +343,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
/** @var LevelProvider $provider */
|
||||
|
||||
if(is_subclass_of($provider, LevelProvider::class, true)){
|
||||
$this->provider = new $provider($this, $path);
|
||||
$this->provider = new $provider($path);
|
||||
}else{
|
||||
throw new LevelException("Provider is not a subclass of LevelProvider");
|
||||
}
|
||||
@ -2546,7 +2546,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
}
|
||||
$this->timings->syncChunkSendPrepareTimer->startTiming();
|
||||
|
||||
$chunk = $this->provider->getChunk($x, $z, false);
|
||||
$chunk = $this->provider->getChunk($x, $z);
|
||||
if(!($chunk instanceof Chunk)){
|
||||
throw new ChunkException("Invalid Chunk sent");
|
||||
}
|
||||
@ -2686,7 +2686,13 @@ class Level implements ChunkManager, Metadatable{
|
||||
|
||||
$this->cancelUnloadChunkRequest($x, $z);
|
||||
|
||||
$chunk = $this->provider->getChunk($x, $z, $generate);
|
||||
$this->timings->syncChunkLoadDataTimer->startTiming();
|
||||
|
||||
$this->provider->loadChunk($x, $z, $generate);
|
||||
$chunk = $this->provider->getChunk($x, $z);
|
||||
|
||||
$this->timings->syncChunkLoadDataTimer->stopTiming();
|
||||
|
||||
if($chunk === null){
|
||||
if($generate){
|
||||
throw new \InvalidStateException("Could not create new Chunk");
|
||||
|
@ -33,8 +33,6 @@ use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
|
||||
abstract class BaseLevelProvider implements LevelProvider{
|
||||
/** @var Level */
|
||||
protected $level;
|
||||
/** @var string */
|
||||
protected $path;
|
||||
/** @var CompoundTag */
|
||||
@ -42,8 +40,7 @@ abstract class BaseLevelProvider implements LevelProvider{
|
||||
/** @var Chunk[] */
|
||||
protected $chunks = [];
|
||||
|
||||
public function __construct(Level $level, string $path){
|
||||
$this->level = $level;
|
||||
public function __construct(string $path){
|
||||
$this->path = $path;
|
||||
if(!file_exists($this->path)){
|
||||
mkdir($this->path, 0777, true);
|
||||
@ -120,15 +117,8 @@ abstract class BaseLevelProvider implements LevelProvider{
|
||||
file_put_contents($this->getPath() . "level.dat", $buffer);
|
||||
}
|
||||
|
||||
public function getChunk(int $chunkX, int $chunkZ, bool $create = false){
|
||||
$index = Level::chunkHash($chunkX, $chunkZ);
|
||||
if(isset($this->chunks[$index])){
|
||||
return $this->chunks[$index];
|
||||
}else{
|
||||
$this->loadChunk($chunkX, $chunkZ, $create);
|
||||
|
||||
return $this->chunks[$index] ?? null;
|
||||
}
|
||||
public function getChunk(int $chunkX, int $chunkZ){
|
||||
return $this->chunks[Level::chunkHash($chunkX, $chunkZ)] ?? null;
|
||||
}
|
||||
|
||||
public function isChunkLoaded(int $chunkX, int $chunkZ) : bool{
|
||||
@ -145,12 +135,10 @@ abstract class BaseLevelProvider implements LevelProvider{
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->level->timings->syncChunkLoadDataTimer->startTiming();
|
||||
$chunk = $this->readChunk($chunkX, $chunkZ);
|
||||
if($chunk === null and $create){
|
||||
$chunk = new Chunk($chunkX, $chunkZ);
|
||||
}
|
||||
$this->level->timings->syncChunkLoadDataTimer->stopTiming();
|
||||
|
||||
if($chunk !== null){
|
||||
$this->chunks[$index] = $chunk;
|
||||
|
@ -24,16 +24,14 @@ declare(strict_types=1);
|
||||
namespace pocketmine\level\format\io;
|
||||
|
||||
use pocketmine\level\format\Chunk;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
|
||||
interface LevelProvider{
|
||||
|
||||
/**
|
||||
* @param Level $level
|
||||
* @param string $path
|
||||
*/
|
||||
public function __construct(Level $level, string $path);
|
||||
public function __construct(string $path);
|
||||
|
||||
/**
|
||||
* Returns the full provider name, like "anvil" or "mcregion", will be used to find the correct format.
|
||||
@ -91,13 +89,12 @@ interface LevelProvider{
|
||||
* Gets the Chunk object
|
||||
* This method must be implemented by all the level formats.
|
||||
*
|
||||
* @param int $chunkX
|
||||
* @param int $chunkZ
|
||||
* @param bool $create
|
||||
* @param int $chunkX
|
||||
* @param int $chunkZ
|
||||
*
|
||||
* @return Chunk|null
|
||||
*/
|
||||
public function getChunk(int $chunkX, int $chunkZ, bool $create = false);
|
||||
public function getChunk(int $chunkX, int $chunkZ);
|
||||
|
||||
/**
|
||||
* @param int $chunkX
|
||||
|
@ -87,10 +87,9 @@ class LevelDB extends BaseLevelProvider{
|
||||
}
|
||||
}
|
||||
|
||||
public function __construct(Level $level, string $path){
|
||||
public function __construct(string $path){
|
||||
self::checkForLevelDBExtension();
|
||||
|
||||
$this->level = $level;
|
||||
$this->path = $path;
|
||||
if(!file_exists($this->path)){
|
||||
mkdir($this->path, 0777, true);
|
||||
@ -530,6 +529,5 @@ class LevelDB extends BaseLevelProvider{
|
||||
public function close(){
|
||||
$this->unloadChunks();
|
||||
$this->db->close();
|
||||
$this->level = null;
|
||||
}
|
||||
}
|
||||
|
@ -355,7 +355,6 @@ class McRegion extends BaseLevelProvider{
|
||||
$region->close();
|
||||
unset($this->regions[$index]);
|
||||
}
|
||||
$this->level = null;
|
||||
}
|
||||
|
||||
protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk{
|
||||
|
Loading…
x
Reference in New Issue
Block a user