Improved Vector3 and Block handling, less allocation on Positions

This commit is contained in:
Shoghi Cervantes
2014-10-28 10:03:10 +01:00
parent 69492474e4
commit 144a871c07
18 changed files with 85 additions and 35 deletions

View File

@ -650,8 +650,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$pk->started = $this->level->stopTime == false; $pk->started = $this->level->stopTime == false;
$this->dataPacket($pk); $this->dataPacket($pk);
$pos = new Position($this->x, $this->y, $this->z, $this->level); $pos = $this->level->getSafeSpawn($this);
$pos = $this->level->getSafeSpawn($pos);
$this->server->getPluginManager()->callEvent($ev = new PlayerRespawnEvent($this, $pos)); $this->server->getPluginManager()->callEvent($ev = new PlayerRespawnEvent($this, $pos));
@ -809,8 +808,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
return false; return false;
} }
$this->sleeping = $pos; $this->sleeping = clone $pos;
$this->teleport(new Position($pos->x + 0.5, $pos->y + 1, $pos->z + 0.5, $this->level)); $this->teleport(Position::createPosition($pos->x + 0.5, $pos->y + 1, $pos->z + 0.5, $this->level));
$this->sendMetadata($this->getViewers()); $this->sendMetadata($this->getViewers());
$this->sendMetadata($this); $this->sendMetadata($this);

View File

@ -50,6 +50,7 @@ use pocketmine\level\generator\GenerationRequestManager;
use pocketmine\level\generator\Generator; use pocketmine\level\generator\Generator;
use pocketmine\level\generator\Normal; use pocketmine\level\generator\Normal;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\level\Position;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\metadata\EntityMetadataStore; use pocketmine\metadata\EntityMetadataStore;
@ -917,6 +918,7 @@ class Server{
*/ */
public function unloadLevel(Level $level, $forceUnload = false){ public function unloadLevel(Level $level, $forceUnload = false){
if($level->unload($forceUnload) === true){ if($level->unload($forceUnload) === true){
Position::clearPositions();
unset($this->levels[$level->getID()]); unset($this->levels[$level->getID()]);
return true; return true;
@ -2114,13 +2116,9 @@ class Server{
$this->generationManager->process(); $this->generationManager->process();
if(($this->tickCounter % 600) === 0){
Vector3::clearVectors();
AxisAlignedBB::clearBoundingBoxes();
}else{
Vector3::clearVectorList(); Vector3::clearVectorList();
Position::clearPositionList();
AxisAlignedBB::clearBoundingBoxPool(); AxisAlignedBB::clearBoundingBoxPool();
}
Timings::$serverTickTimer->stopTiming(); Timings::$serverTickTimer->stopTiming();

View File

@ -686,7 +686,7 @@ class Block extends Position implements Metadatable{
$block = new Block($id, $meta); $block = new Block($id, $meta);
} }
if($pos instanceof Position){ if($pos !== null){
$block->x = $pos->x; $block->x = $pos->x;
$block->y = $pos->y; $block->y = $pos->y;
$block->z = $pos->z; $block->z = $pos->z;

View File

@ -28,7 +28,7 @@ use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3 as Vector3; use pocketmine\math\Vector3;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\Server; use pocketmine\Server;

View File

@ -56,7 +56,7 @@ class Grass extends Solid{
$z = mt_rand($this->z - 1, $this->z + 1); $z = mt_rand($this->z - 1, $this->z + 1);
$block = $this->getLevel()->getBlockIdAt($x, $y, $z); $block = $this->getLevel()->getBlockIdAt($x, $y, $z);
if($block === Block::DIRT){ if($block === Block::DIRT){
$block = Block::get($block, $this->getLevel()->getBlockDataAt($x, $y, $z), new Position($x, $y, $z, $this->getLevel())); $block = Block::get($block, $this->getLevel()->getBlockDataAt($x, $y, $z), Position::createPosition($x, $y, $z, $this->getLevel()));
if($block->getSide(1) instanceof Transparent){ if($block->getSide(1) instanceof Transparent){
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Grass())); Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Grass()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){

View File

@ -47,7 +47,7 @@ class Mycelium extends Solid{
$z = mt_rand($this->z - 1, $this->z + 1); $z = mt_rand($this->z - 1, $this->z + 1);
$block = $this->getLevel()->getBlockIdAt($x, $y, $z); $block = $this->getLevel()->getBlockIdAt($x, $y, $z);
if($block === Block::DIRT){ if($block === Block::DIRT){
$block = Block::get($block, $this->getLevel()->getBlockDataAt($x, $y, $z), new Position($x, $y, $z, $this->getLevel())); $block = Block::get($block, $this->getLevel()->getBlockDataAt($x, $y, $z), Position::createPosition($x, $y, $z, $this->getLevel()));
if($block->getSide(1) instanceof Transparent){ if($block->getSide(1) instanceof Transparent){
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Mycelium())); Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Mycelium()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){

View File

@ -70,14 +70,14 @@ class SpawnpointCommand extends VanillaCommand{
$x = (int) $this->getRelativeDouble($pos->x, $sender, $args[1]); $x = (int) $this->getRelativeDouble($pos->x, $sender, $args[1]);
$y = $this->getRelativeDouble($pos->y, $sender, $args[2], 0, 128); $y = $this->getRelativeDouble($pos->y, $sender, $args[2], 0, 128);
$z = $this->getRelativeDouble($pos->z, $sender, $args[3]); $z = $this->getRelativeDouble($pos->z, $sender, $args[3]);
$target->setSpawn(new Position($x, $y, $z, $level)); $target->setSpawn(Position::createPosition($x, $y, $z, $level));
Command::broadcastCommandMessage($sender, "Set " . $target->getDisplayName() . "'s spawnpoint to " . $x . ", " . $y . ", " . $z); Command::broadcastCommandMessage($sender, "Set " . $target->getDisplayName() . "'s spawnpoint to " . $x . ", " . $y . ", " . $z);
return true; return true;
} }
}elseif(count($args) <= 1){ }elseif(count($args) <= 1){
if($sender instanceof Player){ if($sender instanceof Player){
$pos = new Position((int) $sender->x, (int) $sender->y, (int) $sender->z, $sender->getLevel()); $pos = Position::createPosition((int) $sender->x, (int) $sender->y, (int) $sender->z, $sender->getLevel());
$target->setSpawn($pos); $target->setSpawn($pos);
Command::broadcastCommandMessage($sender, "Set " . $target->getDisplayName() . "'s spawnpoint to " . $pos->x . ", " . $pos->y . ", " . $pos->z); Command::broadcastCommandMessage($sender, "Set " . $target->getDisplayName() . "'s spawnpoint to " . $pos->x . ", " . $pos->y . ", " . $pos->z);

View File

@ -88,7 +88,7 @@ class TeleportCommand extends VanillaCommand{
} }
if(count($args) < 3){ if(count($args) < 3){
$pos = new Position($target->x, $target->y, $target->z, $target->getLevel()); $pos = Position::clonePosition($target);
$origin->teleport($pos); $origin->teleport($pos);
Command::broadcastCommandMessage($sender, "Teleported " . $origin->getDisplayName() . " to " . $target->getDisplayName()); Command::broadcastCommandMessage($sender, "Teleported " . $origin->getDisplayName() . " to " . $target->getDisplayName());

View File

@ -40,7 +40,7 @@ use pocketmine\level\Location;
use pocketmine\level\Position; use pocketmine\level\Position;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Math; use pocketmine\math\Math;
use pocketmine\math\Vector3 as Vector3; use pocketmine\math\Vector3;
use pocketmine\metadata\Metadatable; use pocketmine\metadata\Metadatable;
use pocketmine\metadata\MetadataValue; use pocketmine\metadata\MetadataValue;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Byte;
@ -737,7 +737,7 @@ abstract class Entity extends Location implements Metadatable{
} }
public function getPosition(){ public function getPosition(){
return new Position($this->x, $this->y, $this->z, $this->level); return Position::createPosition($this->x, $this->y, $this->z, $this->level);
} }
public function getLocation(){ public function getLocation(){

View File

@ -88,7 +88,7 @@ class FallingBlock extends Entity{
if(!$this->dead){ if(!$this->dead){
if($this->ticksLived === 1){ if($this->ticksLived === 1){
$block = $this->level->getBlock($pos = Vector3::createVector($this->x, $this->y, $this->z)->floor()); $block = $this->level->getBlock($pos = Vector3::cloneVector($this)->floor());
if($block->getID() != $this->blockId){ if($block->getID() != $this->blockId){
$this->kill(); $this->kill();
return true; return true;
@ -107,7 +107,7 @@ class FallingBlock extends Entity{
$this->motionY *= 1 - $this->drag; $this->motionY *= 1 - $this->drag;
$this->motionZ *= $friction; $this->motionZ *= $friction;
$pos = Vector3::createVector($this->x, $this->y, $this->z)->floor(); $pos = Vector3::cloneVector($this)->floor();
if($this->onGround){ if($this->onGround){
$this->kill(); $this->kill();

View File

@ -24,7 +24,7 @@ namespace pocketmine\event\entity;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\Event; use pocketmine\Event;
use pocketmine\event\Cancellable; use pocketmine\event\Cancellable;
use pocketmine\math\Vector3 as Vector3; use pocketmine\math\Vector3;
class EntityMotionEvent extends EntityEvent implements Cancellable{ class EntityMotionEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
@ -36,6 +36,9 @@ class EntityMotionEvent extends EntityEvent implements Cancellable{
$this->mot = $mot; $this->mot = $mot;
} }
/**
* @return Vector3
*/
public function getVector(){ public function getVector(){
return $this->mot; return $this->mot;
} }

View File

@ -24,7 +24,7 @@ namespace pocketmine\event\entity;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\Event; use pocketmine\Event;
use pocketmine\event\Cancellable; use pocketmine\event\Cancellable;
use pocketmine\math\Vector3 as Vector3; use pocketmine\math\Vector3;
/** /**
* @deprecated * @deprecated

View File

@ -33,7 +33,7 @@ use pocketmine\event\entity\EntityExplodeEvent;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Math; use pocketmine\math\Math;
use pocketmine\math\Vector3 as Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Byte;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\Double; use pocketmine\nbt\tag\Double;

View File

@ -910,7 +910,7 @@ class Level implements ChunkManager, Metadatable{
return $this->blockCache[$index] = $air; return $this->blockCache[$index] = $air;
} }
return $this->blockCache[$index] = Block::get($blockId, $meta, new Position($pos->x, $pos->y, $pos->z, $this)); return $this->blockCache[$index] = Block::get($blockId, $meta, $pos instanceof Position ? $pos : Position::createPosition($pos->x, $pos->y, $pos->z, $this));
} }
/** /**
@ -940,7 +940,7 @@ class Level implements ChunkManager, Metadatable{
if($this->getChunk($pos->x >> 4, $pos->z >> 4, true)->setBlock($pos->x & 0x0f, $pos->y & 0x7f, $pos->z & 0x0f, $block->getID(), $block->getDamage())){ if($this->getChunk($pos->x >> 4, $pos->z >> 4, true)->setBlock($pos->x & 0x0f, $pos->y & 0x7f, $pos->z & 0x0f, $block->getID(), $block->getDamage())){
if(!($pos instanceof Position)){ if(!($pos instanceof Position)){
$pos = new Position($pos->x, $pos->y, $pos->z, $this); $pos = Position::createPosition($pos->x, $pos->y, $pos->z, $this);
} }
$block->position($pos); $block->position($pos);
$index = Level::chunkHash($pos->x >> 4, $pos->z >> 4); $index = Level::chunkHash($pos->x >> 4, $pos->z >> 4);
@ -1938,14 +1938,14 @@ class Level implements ChunkManager, Metadatable{
for(; $v->y < 128; ++$v->y){ for(; $v->y < 128; ++$v->y){
if($this->getBlock($v->getSide(1)) instanceof Air){ if($this->getBlock($v->getSide(1)) instanceof Air){
if($this->getBlock($v) instanceof Air){ if($this->getBlock($v) instanceof Air){
return new Position($spawn->x, $v->y === Math::floorFloat($spawn->y) ? $spawn->y : $v->y, $spawn->z, $this); return Position::createPosition($spawn->x, $v->y === Math::floorFloat($spawn->y) ? $spawn->y : $v->y, $spawn->z, $this);
} }
}else{ }else{
++$v->y; ++$v->y;
} }
} }
return new Position($spawn->x, $v->y, $spawn->z, $this); return Position::createPosition($spawn->x, $v->y, $spawn->z, $this);
} }
return false; return false;

View File

@ -21,13 +21,54 @@
namespace pocketmine\level; namespace pocketmine\level;
use pocketmine\math\Vector3 as Vector3; use pocketmine\math\Vector3;
class Position extends Vector3{ class Position extends Vector3{
/** @var Position[] */
private static $positionList = [];
private static $nextPosition = 0;
/** @var Level */ /** @var Level */
public $level = null; public $level = null;
public static function clearPositions(){
self::$nextPosition = 0;
self::$positionList = [];
}
public static function clearPositionList(){
if(self::$nextPosition > 65536){
self::clearVectors();
}else{
self::$nextPosition = 0;
}
}
/**
* @param $x
* @param $y
* @param $z
* @param Level $level
*
* @return Position
*/
public static function createPosition($x, $y, $z, Level $level){
if(self::$nextPosition >= count(self::$positionList)){
self::$positionList[] = new Position(0, 0, 0, null);
}
return self::$positionList[self::$nextPosition++]->setLevel($level)->setComponents($x, $y, $z);
}
public static function clonePosition(Position $pos){
if(self::$nextPosition >= count(self::$positionList)){
self::$positionList[] = new Position(0, 0, 0, null);
}
return self::$positionList[self::$nextPosition++]->setLevel($pos->level)->setComponents($pos->x, $pos->y, $pos->z);
}
/** /**
* @param int $x * @param int $x
* @param int $y * @param int $y
@ -42,7 +83,7 @@ class Position extends Vector3{
} }
public static function fromObject(Vector3 $pos, Level $level = null){ public static function fromObject(Vector3 $pos, Level $level = null){
return new Position($pos->x, $pos->y, $pos->z, $level); return self::createPosition($pos->x, $pos->y, $pos->z, $level);
} }
/** /**
@ -52,8 +93,9 @@ class Position extends Vector3{
return $this->level; return $this->level;
} }
public function setLevel(Level $level, $strong = false){ public function setLevel(Level $level){
$this->level = $level; $this->level = $level;
return $this;
} }
/** /**

View File

@ -51,8 +51,12 @@ class AxisAlignedBB{
} }
public static function clearBoundingBoxPool(){ public static function clearBoundingBoxPool(){
if(self::$nextBoundingBox > 65536){
self::clearBoundingBoxes();
}else{
self::$nextBoundingBox = 0; self::$nextBoundingBox = 0;
} }
}
/** /**
* @param $minX * @param $minX

View File

@ -54,8 +54,12 @@ class Vector3{
} }
public static function clearVectorList(){ public static function clearVectorList(){
if(self::$nextVector > 65536){
self::clearVectors();
}else{
self::$nextVector = 0; self::$nextVector = 0;
} }
}
/** /**
* @param $x * @param $x

View File

@ -26,7 +26,7 @@ use pocketmine\inventory\DoubleChestInventory;
use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\InventoryHolder;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\format\FullChunk; use pocketmine\level\format\FullChunk;
use pocketmine\math\Vector3 as Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Byte;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\Compound;