mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-13 13:25:16 +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 */
|
/** @var LevelProvider $provider */
|
||||||
|
|
||||||
if(is_subclass_of($provider, LevelProvider::class, true)){
|
if(is_subclass_of($provider, LevelProvider::class, true)){
|
||||||
$this->provider = new $provider($this, $path);
|
$this->provider = new $provider($path);
|
||||||
}else{
|
}else{
|
||||||
throw new LevelException("Provider is not a subclass of LevelProvider");
|
throw new LevelException("Provider is not a subclass of LevelProvider");
|
||||||
}
|
}
|
||||||
@ -2546,7 +2546,7 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
}
|
}
|
||||||
$this->timings->syncChunkSendPrepareTimer->startTiming();
|
$this->timings->syncChunkSendPrepareTimer->startTiming();
|
||||||
|
|
||||||
$chunk = $this->provider->getChunk($x, $z, false);
|
$chunk = $this->provider->getChunk($x, $z);
|
||||||
if(!($chunk instanceof Chunk)){
|
if(!($chunk instanceof Chunk)){
|
||||||
throw new ChunkException("Invalid Chunk sent");
|
throw new ChunkException("Invalid Chunk sent");
|
||||||
}
|
}
|
||||||
@ -2686,7 +2686,13 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
|
|
||||||
$this->cancelUnloadChunkRequest($x, $z);
|
$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($chunk === null){
|
||||||
if($generate){
|
if($generate){
|
||||||
throw new \InvalidStateException("Could not create new Chunk");
|
throw new \InvalidStateException("Could not create new Chunk");
|
||||||
|
@ -33,8 +33,6 @@ use pocketmine\nbt\tag\CompoundTag;
|
|||||||
use pocketmine\nbt\tag\StringTag;
|
use pocketmine\nbt\tag\StringTag;
|
||||||
|
|
||||||
abstract class BaseLevelProvider implements LevelProvider{
|
abstract class BaseLevelProvider implements LevelProvider{
|
||||||
/** @var Level */
|
|
||||||
protected $level;
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
protected $path;
|
protected $path;
|
||||||
/** @var CompoundTag */
|
/** @var CompoundTag */
|
||||||
@ -42,8 +40,7 @@ abstract class BaseLevelProvider implements LevelProvider{
|
|||||||
/** @var Chunk[] */
|
/** @var Chunk[] */
|
||||||
protected $chunks = [];
|
protected $chunks = [];
|
||||||
|
|
||||||
public function __construct(Level $level, string $path){
|
public function __construct(string $path){
|
||||||
$this->level = $level;
|
|
||||||
$this->path = $path;
|
$this->path = $path;
|
||||||
if(!file_exists($this->path)){
|
if(!file_exists($this->path)){
|
||||||
mkdir($this->path, 0777, true);
|
mkdir($this->path, 0777, true);
|
||||||
@ -120,15 +117,8 @@ abstract class BaseLevelProvider implements LevelProvider{
|
|||||||
file_put_contents($this->getPath() . "level.dat", $buffer);
|
file_put_contents($this->getPath() . "level.dat", $buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getChunk(int $chunkX, int $chunkZ, bool $create = false){
|
public function getChunk(int $chunkX, int $chunkZ){
|
||||||
$index = Level::chunkHash($chunkX, $chunkZ);
|
return $this->chunks[Level::chunkHash($chunkX, $chunkZ)] ?? null;
|
||||||
if(isset($this->chunks[$index])){
|
|
||||||
return $this->chunks[$index];
|
|
||||||
}else{
|
|
||||||
$this->loadChunk($chunkX, $chunkZ, $create);
|
|
||||||
|
|
||||||
return $this->chunks[$index] ?? null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isChunkLoaded(int $chunkX, int $chunkZ) : bool{
|
public function isChunkLoaded(int $chunkX, int $chunkZ) : bool{
|
||||||
@ -145,12 +135,10 @@ abstract class BaseLevelProvider implements LevelProvider{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->level->timings->syncChunkLoadDataTimer->startTiming();
|
|
||||||
$chunk = $this->readChunk($chunkX, $chunkZ);
|
$chunk = $this->readChunk($chunkX, $chunkZ);
|
||||||
if($chunk === null and $create){
|
if($chunk === null and $create){
|
||||||
$chunk = new Chunk($chunkX, $chunkZ);
|
$chunk = new Chunk($chunkX, $chunkZ);
|
||||||
}
|
}
|
||||||
$this->level->timings->syncChunkLoadDataTimer->stopTiming();
|
|
||||||
|
|
||||||
if($chunk !== null){
|
if($chunk !== null){
|
||||||
$this->chunks[$index] = $chunk;
|
$this->chunks[$index] = $chunk;
|
||||||
|
@ -24,16 +24,14 @@ declare(strict_types=1);
|
|||||||
namespace pocketmine\level\format\io;
|
namespace pocketmine\level\format\io;
|
||||||
|
|
||||||
use pocketmine\level\format\Chunk;
|
use pocketmine\level\format\Chunk;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\math\Vector3;
|
use pocketmine\math\Vector3;
|
||||||
|
|
||||||
interface LevelProvider{
|
interface LevelProvider{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Level $level
|
|
||||||
* @param string $path
|
* @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.
|
* 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
|
* Gets the Chunk object
|
||||||
* This method must be implemented by all the level formats.
|
* This method must be implemented by all the level formats.
|
||||||
*
|
*
|
||||||
* @param int $chunkX
|
* @param int $chunkX
|
||||||
* @param int $chunkZ
|
* @param int $chunkZ
|
||||||
* @param bool $create
|
|
||||||
*
|
*
|
||||||
* @return Chunk|null
|
* @return Chunk|null
|
||||||
*/
|
*/
|
||||||
public function getChunk(int $chunkX, int $chunkZ, bool $create = false);
|
public function getChunk(int $chunkX, int $chunkZ);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $chunkX
|
* @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();
|
self::checkForLevelDBExtension();
|
||||||
|
|
||||||
$this->level = $level;
|
|
||||||
$this->path = $path;
|
$this->path = $path;
|
||||||
if(!file_exists($this->path)){
|
if(!file_exists($this->path)){
|
||||||
mkdir($this->path, 0777, true);
|
mkdir($this->path, 0777, true);
|
||||||
@ -530,6 +529,5 @@ class LevelDB extends BaseLevelProvider{
|
|||||||
public function close(){
|
public function close(){
|
||||||
$this->unloadChunks();
|
$this->unloadChunks();
|
||||||
$this->db->close();
|
$this->db->close();
|
||||||
$this->level = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,7 +355,6 @@ class McRegion extends BaseLevelProvider{
|
|||||||
$region->close();
|
$region->close();
|
||||||
unset($this->regions[$index]);
|
unset($this->regions[$index]);
|
||||||
}
|
}
|
||||||
$this->level = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk{
|
protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user