BlockStateReader: micro optimize unread properties check

this has a pretty much insignificant performance impact, but reduces the cost of this check to basically 0.
This commit is contained in:
Dylan K. Taylor 2024-03-14 17:54:26 +00:00
parent a835069564
commit e31fd122d9
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D

View File

@ -38,20 +38,24 @@ use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\tag\StringTag;
use pocketmine\nbt\tag\Tag; use pocketmine\nbt\tag\Tag;
use pocketmine\utils\Utils; use function array_keys;
use function count;
use function get_class; use function get_class;
use function implode;
final class BlockStateReader{ final class BlockStateReader{
/** /**
* @var true[] * @var Tag[]
* @phpstan-var array<string, true> * @phpstan-var array<string, Tag>
*/ */
private array $usedStates = []; private array $unusedStates;
public function __construct( public function __construct(
private BlockStateData $data private BlockStateData $data
){} ){
$this->unusedStates = $this->data->getStates();
}
public function missingOrWrongTypeException(string $name, ?Tag $tag) : BlockStateDeserializeException{ public function missingOrWrongTypeException(string $name, ?Tag $tag) : BlockStateDeserializeException{
return new BlockStateDeserializeException("Property \"$name\" " . ($tag !== null ? "has unexpected type " . get_class($tag) : "is missing")); return new BlockStateDeserializeException("Property \"$name\" " . ($tag !== null ? "has unexpected type " . get_class($tag) : "is missing"));
@ -66,7 +70,7 @@ final class BlockStateReader{
/** @throws BlockStateDeserializeException */ /** @throws BlockStateDeserializeException */
public function readBool(string $name) : bool{ public function readBool(string $name) : bool{
$this->usedStates[$name] = true; unset($this->unusedStates[$name]);
$tag = $this->data->getState($name); $tag = $this->data->getState($name);
if($tag instanceof ByteTag){ if($tag instanceof ByteTag){
switch($tag->getValue()){ switch($tag->getValue()){
@ -80,7 +84,7 @@ final class BlockStateReader{
/** @throws BlockStateDeserializeException */ /** @throws BlockStateDeserializeException */
public function readInt(string $name) : int{ public function readInt(string $name) : int{
$this->usedStates[$name] = true; unset($this->unusedStates[$name]);
$tag = $this->data->getState($name); $tag = $this->data->getState($name);
if($tag instanceof IntTag){ if($tag instanceof IntTag){
return $tag->getValue(); return $tag->getValue();
@ -99,7 +103,7 @@ final class BlockStateReader{
/** @throws BlockStateDeserializeException */ /** @throws BlockStateDeserializeException */
public function readString(string $name) : string{ public function readString(string $name) : string{
$this->usedStates[$name] = true; unset($this->unusedStates[$name]);
//TODO: only allow a specific set of values (strings are primarily used for enums) //TODO: only allow a specific set of values (strings are primarily used for enums)
$tag = $this->data->getState($name); $tag = $this->data->getState($name);
if($tag instanceof StringTag){ if($tag instanceof StringTag){
@ -346,7 +350,7 @@ final class BlockStateReader{
*/ */
public function ignored(string $name) : void{ public function ignored(string $name) : void{
if($this->data->getState($name) !== null){ if($this->data->getState($name) !== null){
$this->usedStates[$name] = true; unset($this->unusedStates[$name]);
}else{ }else{
throw $this->missingOrWrongTypeException($name, null); throw $this->missingOrWrongTypeException($name, null);
} }
@ -363,10 +367,8 @@ final class BlockStateReader{
* @throws BlockStateDeserializeException * @throws BlockStateDeserializeException
*/ */
public function checkUnreadProperties() : void{ public function checkUnreadProperties() : void{
foreach(Utils::stringifyKeys($this->data->getStates()) as $name => $tag){ if(count($this->unusedStates) > 0){
if(!isset($this->usedStates[$name])){ throw new BlockStateDeserializeException("Unread properties: " . implode(", ", array_keys($this->unusedStates)));
throw new BlockStateDeserializeException("Unread property \"$name\"");
}
} }
} }
} }