Moved light population to an async task when needed, improved empty chunks

This commit is contained in:
Shoghi Cervantes 2015-05-28 23:13:20 +02:00
parent 0f5f71e612
commit c578898aa4
No known key found for this signature in database
GPG Key ID: 78464DB0A7837F89
7 changed files with 104 additions and 11 deletions

View File

@ -70,6 +70,7 @@ use pocketmine\level\generator\GenerationTask;
use pocketmine\level\generator\Generator; use pocketmine\level\generator\Generator;
use pocketmine\level\generator\GeneratorRegisterTask; use pocketmine\level\generator\GeneratorRegisterTask;
use pocketmine\level\generator\GeneratorUnregisterTask; use pocketmine\level\generator\GeneratorUnregisterTask;
use pocketmine\level\generator\LightPopulationTask;
use pocketmine\level\generator\PopulationTask; use pocketmine\level\generator\PopulationTask;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Math; use pocketmine\math\Math;
@ -2299,6 +2300,10 @@ class Level implements ChunkManager, Metadatable{
return false; return false;
} }
if(!$chunk->isLightPopulated() and $chunk->isPopulated()){
$this->getServer()->getScheduler()->scheduleAsyncTask(new LightPopulationTask($this, $chunk));
}
if($this->isChunkInUse($x, $z)){ if($this->isChunkInUse($x, $z)){
foreach($this->getChunkLoaders($x, $z) as $loader){ foreach($this->getChunkLoaders($x, $z) as $loader){
$loader->onChunkLoaded($chunk); $loader->onChunkLoaded($chunk);

View File

@ -31,6 +31,7 @@ use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\Enum;
use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\Int;
use pocketmine\nbt\tag\IntArray; use pocketmine\nbt\tag\IntArray;
use pocketmine\nbt\tag\Long;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\utils\Binary; use pocketmine\utils\Binary;

View File

@ -164,12 +164,6 @@ abstract class BaseFullChunk implements FullChunk{
$this->isInit = true; $this->isInit = true;
} }
if(!$this->isLightPopulated() and $this->isPopulated()){
$this->recalculateHeightMap();
$this->populateSkyLight();
$this->setLightPopulated();
}
} }
public function getX(){ public function getX(){

View File

@ -109,7 +109,7 @@ class EmptyChunkSection implements ChunkSection{
} }
final public function getBlockSkyLight($x, $y, $z){ final public function getBlockSkyLight($x, $y, $z){
return 0; return 15;
} }
final public function setBlockSkyLight($x, $y, $z, $level){ final public function setBlockSkyLight($x, $y, $z, $level){

View File

@ -29,6 +29,9 @@ use pocketmine\utils\Binary;
class Chunk extends BaseFullChunk{ class Chunk extends BaseFullChunk{
const DATA_LENGTH = 16384 * (2 + 1 + 1 + 1) + 256 + 1024;
protected $isLightPopulated = false;
protected $isPopulated = false; protected $isPopulated = false;
protected $isGenerated = false; protected $isGenerated = false;
@ -195,6 +198,20 @@ class Chunk extends BaseFullChunk{
return substr($this->blockLight, ($x << 10) + ($z << 6), 64); return substr($this->blockLight, ($x << 10) + ($z << 6), 64);
} }
/**
* @return bool
*/
public function isLightPopulated(){
return $this->isLightPopulated;
}
/**
* @param int $value
*/
public function setLightPopulated($value = 1){
$this->isLightPopulated = (bool) $value;
}
/** /**
* @return bool * @return bool
*/ */
@ -350,7 +367,9 @@ class Chunk extends BaseFullChunk{
*/ */
public static function getEmptyChunk($chunkX, $chunkZ, LevelProvider $provider = null){ public static function getEmptyChunk($chunkX, $chunkZ, LevelProvider $provider = null){
try{ try{
return new Chunk($provider instanceof LevelProvider ? $provider : LevelDB::class, $chunkX, $chunkZ, str_repeat("\x00", 16384 * (2 + 1 + 1 + 1) + 256 + 1024)); $chunk = new Chunk($provider instanceof LevelProvider ? $provider : LevelDB::class, $chunkX, $chunkZ, str_repeat("\x00", self::DATA_LENGTH));
$chunk->skyLight = str_repeat("\xff", 16384);
return $chunk;
}catch(\Exception $e){ }catch(\Exception $e){
return null; return null;
} }

View File

@ -238,7 +238,7 @@ class Chunk extends BaseFullChunk{
} }
public function setLightPopulated($value = 1){ public function setLightPopulated($value = 1){
$this->nbt->LightPopulated = new Byte("LightPopulated", $value); $this->nbt->LightPopulated = new Byte("LightPopulated", $value ? 1 : 0);
$this->hasChanged = true; $this->hasChanged = true;
} }
@ -253,7 +253,7 @@ class Chunk extends BaseFullChunk{
* @param int $value * @param int $value
*/ */
public function setPopulated($value = 1){ public function setPopulated($value = 1){
$this->nbt->TerrainPopulated = new Byte("TerrainPopulated", (int) $value); $this->nbt->TerrainPopulated = new Byte("TerrainPopulated", $value ? 1 : 0);
$this->hasChanged = true; $this->hasChanged = true;
} }
@ -428,7 +428,7 @@ class Chunk extends BaseFullChunk{
$chunk->data = str_repeat("\x00", 16384); $chunk->data = str_repeat("\x00", 16384);
$chunk->blocks = $chunk->data . $chunk->data; $chunk->blocks = $chunk->data . $chunk->data;
$chunk->skyLight = $chunk->data; $chunk->skyLight = str_repeat("\xff", 16384);
$chunk->blockLight = $chunk->data; $chunk->blockLight = $chunk->data;
$chunk->heightMap = array_fill(0, 256, 0); $chunk->heightMap = array_fill(0, 256, 0);

View File

@ -0,0 +1,74 @@
<?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/
*
*
*/
namespace pocketmine\level\generator;
use pocketmine\block\Block;
use pocketmine\level\format\FullChunk;
use pocketmine\level\generator\biome\Biome;
use pocketmine\level\Level;
use pocketmine\level\SimpleChunkManager;
use pocketmine\scheduler\AsyncTask;
use pocketmine\Server;
use pocketmine\utils\Random;
class LightPopulationTask extends AsyncTask{
public $levelId;
public $chunk;
public $chunkClass;
public function __construct(Level $level, FullChunk $chunk){
$this->levelId = $level->getId();
$this->chunk = $chunk->toFastBinary();
$this->chunkClass = get_class($chunk);
}
public function onRun(){
/** @var FullChunk $chunk */
$chunk = $this->chunkClass;
$chunk = $chunk::fromFastBinary($this->chunk);
if($chunk === null){
//TODO error
return;
}
$chunk->recalculateHeightMap();
$chunk->populateSkyLight();
$chunk->setLightPopulated();
$this->chunk = $chunk->toFastBinary();
}
public function onCompletion(Server $server){
$level = $server->getLevel($this->levelId);
if($level !== null){
/** @var FullChunk $chunk */
$chunk = $this->chunkClass;
$chunk = $chunk::fromFastBinary($this->chunk, $level->getProvider());
if($chunk === null){
//TODO error
return;
}
$level->generateChunkCallback($chunk->getX(), $chunk->getZ(), $chunk);
}
}
}