RuntimeDataDescriber: Introduce boundedIntAuto, replacing boundedInt

closes #6096
boundedIntAuto automatically calculates the correct number of bits to use based on the given bounds. The bounds must be constant, of course.
This commit is contained in:
Dylan K. Taylor 2023-10-17 12:03:43 +01:00
parent 18b711aca8
commit d0d16cdeb7
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
23 changed files with 78 additions and 29 deletions

View File

@ -50,7 +50,7 @@ final class AmethystCluster extends Transparent{
private int $stage = self::STAGE_CLUSTER;
public function describeBlockItemState(RuntimeDataDescriber $w) : void{
$w->boundedInt(2, self::STAGE_SMALL_BUD, self::STAGE_CLUSTER, $this->stage);
$w->boundedIntAuto(self::STAGE_SMALL_BUD, self::STAGE_CLUSTER, $this->stage);
}
public function getStage() : int{ return $this->stage; }

View File

@ -52,7 +52,7 @@ class Anvil extends Transparent implements Fallable{
private int $damage = self::UNDAMAGED;
public function describeBlockItemState(RuntimeDataDescriber $w) : void{
$w->boundedInt(2, self::UNDAMAGED, self::VERY_DAMAGED, $this->damage);
$w->boundedIntAuto(self::UNDAMAGED, self::VERY_DAMAGED, $this->damage);
}
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{

View File

@ -58,7 +58,7 @@ class Bamboo extends Transparent{
protected int $leafSize = self::NO_LEAVES;
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->boundedInt(2, self::NO_LEAVES, self::LARGE_LEAVES, $this->leafSize);
$w->boundedIntAuto(self::NO_LEAVES, self::LARGE_LEAVES, $this->leafSize);
$w->bool($this->thick);
$w->bool($this->ready);
}

View File

@ -37,7 +37,7 @@ class Cake extends BaseCake{
protected int $bites = 0;
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->boundedInt(3, 0, self::MAX_BITES, $this->bites);
$w->boundedIntAuto(0, self::MAX_BITES, $this->bites);
}
/**

View File

@ -48,7 +48,7 @@ class Candle extends Transparent{
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$this->encodeLitState($w);
$w->boundedInt(2, self::MIN_COUNT, self::MAX_COUNT, $this->count);
$w->boundedIntAuto(self::MIN_COUNT, self::MAX_COUNT, $this->count);
}
public function getCount() : int{ return $this->count; }

View File

@ -49,7 +49,7 @@ class CaveVines extends Flowable{
protected bool $head = false;
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->boundedInt(5, 0, self::MAX_AGE, $this->age);
$w->boundedIntAuto(0, self::MAX_AGE, $this->age);
$w->bool($this->berries);
$w->bool($this->head);
}

View File

@ -48,7 +48,7 @@ class CocoaBlock extends Transparent{
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->horizontalFacing($this->facing);
$w->boundedInt(2, 0, self::MAX_AGE, $this->age);
$w->boundedIntAuto(0, self::MAX_AGE, $this->age);
}
/**

View File

@ -42,7 +42,7 @@ class DaylightSensor extends Transparent{
protected bool $inverted = false;
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->boundedInt(4, 0, 15, $this->signalStrength);
$w->boundedIntAuto(0, 15, $this->signalStrength);
$w->bool($this->inverted);
}

View File

@ -39,7 +39,7 @@ class Farmland extends Transparent{
protected int $wetness = 0; //"moisture" blockstate property in PC
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->boundedInt(3, 0, self::MAX_WETNESS, $this->wetness);
$w->boundedIntAuto(0, self::MAX_WETNESS, $this->wetness);
}
public function getWetness() : int{ return $this->wetness; }

View File

@ -38,7 +38,7 @@ abstract class FillableCauldron extends Transparent{
private int $fillLevel = self::MIN_FILL_LEVEL;
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->boundedInt(3, self::MIN_FILL_LEVEL, self::MAX_FILL_LEVEL, $this->fillLevel);
$w->boundedIntAuto(self::MIN_FILL_LEVEL, self::MAX_FILL_LEVEL, $this->fillLevel);
}
public function getFillLevel() : int{ return $this->fillLevel; }

View File

@ -35,7 +35,7 @@ final class Light extends Flowable{
private int $level = self::MAX_LIGHT_LEVEL;
public function describeBlockItemState(RuntimeDataDescriber $w) : void{
$w->boundedInt(4, self::MIN_LIGHT_LEVEL, self::MAX_LIGHT_LEVEL, $this->level);
$w->boundedIntAuto(self::MIN_LIGHT_LEVEL, self::MAX_LIGHT_LEVEL, $this->level);
}
public function getLightLevel() : int{ return $this->level; }

View File

@ -49,7 +49,7 @@ abstract class Liquid extends Transparent{
protected bool $still = false;
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->boundedInt(3, 0, self::MAX_DECAY, $this->decay);
$w->boundedIntAuto(0, self::MAX_DECAY, $this->decay);
$w->bool($this->falling);
$w->bool($this->still);
}

View File

@ -47,7 +47,7 @@ class PinkPetals extends Flowable{
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->horizontalFacing($this->facing);
$w->boundedInt(2, self::MIN_COUNT, self::MAX_COUNT, $this->count);
$w->boundedIntAuto(self::MIN_COUNT, self::MAX_COUNT, $this->count);
}
public function getCount() : int{

View File

@ -47,7 +47,7 @@ class RedstoneRepeater extends Flowable{
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->horizontalFacing($this->facing);
$w->boundedInt(2, self::MIN_DELAY, self::MAX_DELAY, $this->delay);
$w->boundedIntAuto(self::MIN_DELAY, self::MAX_DELAY, $this->delay);
$w->bool($this->powered);
}

View File

@ -39,7 +39,7 @@ class SeaPickle extends Transparent{
protected bool $underwater = false;
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->boundedInt(2, self::MIN_COUNT, self::MAX_COUNT, $this->count);
$w->boundedIntAuto(self::MIN_COUNT, self::MAX_COUNT, $this->count);
$w->bool($this->underwater);
}

View File

@ -47,7 +47,7 @@ class SnowLayer extends Flowable implements Fallable{
protected int $layers = self::MIN_LAYERS;
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->boundedInt(3, self::MIN_LAYERS, self::MAX_LAYERS, $this->layers);
$w->boundedIntAuto(self::MIN_LAYERS, self::MAX_LAYERS, $this->layers);
}
public function getLayers() : int{ return $this->layers; }

View File

@ -24,7 +24,6 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\data\runtime\RuntimeDataDescriber;
use function log;
/**
* This trait is used for blocks that have an age property.
@ -34,7 +33,7 @@ trait AgeableTrait{
protected int $age = 0;
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->boundedInt(((int) log(self::MAX_AGE, 2)) + 1, 0, self::MAX_AGE, $this->age);
$w->boundedIntAuto(0, self::MAX_AGE, $this->age);
}
public function getAge() : int{ return $this->age; }

View File

@ -29,7 +29,7 @@ trait AnalogRedstoneSignalEmitterTrait{
protected int $signalStrength = 0;
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->boundedInt(4, 0, 15, $this->signalStrength);
$w->boundedIntAuto(0, 15, $this->signalStrength);
}
public function getOutputSignalStrength() : int{ return $this->signalStrength; }

View File

@ -31,7 +31,7 @@ trait SignLikeRotationTrait{
private $rotation = 0;
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
$w->boundedInt(4, 0, 15, $this->rotation);
$w->boundedIntAuto(0, 15, $this->rotation);
}
public function getRotation() : int{ return $this->rotation; }

View File

@ -38,8 +38,17 @@ use pocketmine\math\Facing;
interface RuntimeDataDescriber extends RuntimeEnumDescriber{
public function int(int $bits, int &$value) : void;
/**
* @deprecated Use {@link RuntimeDataDescriber::boundedIntAuto()} instead.
*/
public function boundedInt(int $bits, int $min, int $max, int &$value) : void;
/**
* Same as boundedInt() but automatically calculates the required number of bits from the range.
* The range bounds must be constant.
*/
public function boundedIntAuto(int $min, int $max, int &$value) : void;
public function bool(bool &$value) : void;
public function horizontalFacing(int &$facing) : void;

View File

@ -31,6 +31,7 @@ use pocketmine\math\Facing;
use pocketmine\utils\AssumptionFailedError;
use function get_class;
use function intdiv;
use function log;
use function spl_object_id;
final class RuntimeDataReader implements RuntimeDataDescriber{
@ -58,7 +59,20 @@ final class RuntimeDataReader implements RuntimeDataDescriber{
$value = $this->readInt($bits);
}
protected function readBoundedInt(int $bits, int $min, int $max) : int{
/**
* @deprecated Use {@link self::boundedIntAuto()} instead.
*/
public function boundedInt(int $bits, int $min, int $max, int &$value) : void{
$offset = $this->offset;
$this->boundedIntAuto($min, $max, $value);
$actualBits = $this->offset - $offset;
if($this->offset !== $offset + $bits){
throw new \InvalidArgumentException("Bits should be $actualBits for the given bounds, but received $bits. Use boundedIntAuto() for automatic bits calculation.");
}
}
private function readBoundedIntAuto(int $min, int $max) : int{
$bits = ((int) log($max - $min, 2)) + 1;
$result = $this->readInt($bits) + $min;
if($result < $min || $result > $max){
throw new InvalidSerializedRuntimeDataException("Value is outside the range $min - $max");
@ -66,8 +80,8 @@ final class RuntimeDataReader implements RuntimeDataDescriber{
return $result;
}
public function boundedInt(int $bits, int $min, int $max, int &$value) : void{
$value = $this->readBoundedInt($bits, $min, $max);
public function boundedIntAuto(int $min, int $max, int &$value) : void{
$value = $this->readBoundedIntAuto($min, $max);
}
protected function readBool() : bool{
@ -162,7 +176,7 @@ final class RuntimeDataReader implements RuntimeDataDescriber{
public function wallConnections(array &$connections) : void{
$result = [];
$offset = 0;
$packed = $this->readBoundedInt(7, 0, (3 ** 4) - 1);
$packed = $this->readBoundedIntAuto(0, (3 ** 4) - 1);
foreach(Facing::HORIZONTAL as $facing){
$type = intdiv($packed, (3 ** $offset)) % 3;
if($type !== 0){

View File

@ -26,6 +26,7 @@ namespace pocketmine\data\runtime;
use pocketmine\block\utils\BrewingStandSlot;
use pocketmine\math\Facing;
use function count;
use function log;
final class RuntimeDataSizeCalculator implements RuntimeDataDescriber{
use LegacyRuntimeEnumDescriberTrait;
@ -44,8 +45,20 @@ final class RuntimeDataSizeCalculator implements RuntimeDataDescriber{
$this->addBits($bits);
}
/**
* @deprecated Use {@link self::boundedIntAuto()} instead.
*/
public function boundedInt(int $bits, int $min, int $max, int &$value) : void{
$this->addBits($bits);
$currentBits = $this->bits;
$this->boundedIntAuto($min, $max, $value);
$actualBits = $this->bits - $currentBits;
if($actualBits !== $bits){
throw new \InvalidArgumentException("Bits should be $actualBits for the given bounds, but received $bits. Use boundedIntAuto() for automatic bits calculation.");
}
}
public function boundedIntAuto(int $min, int $max, int &$value) : void{
$this->addBits(((int) log($max - $min, 2)) + 1);
}
public function bool(bool &$value) : void{

View File

@ -28,6 +28,7 @@ use pocketmine\block\utils\WallConnectionType;
use pocketmine\math\Axis;
use pocketmine\math\Facing;
use function array_flip;
use function log;
use function spl_object_id;
final class RuntimeDataWriter implements RuntimeDataDescriber{
@ -56,15 +57,28 @@ final class RuntimeDataWriter implements RuntimeDataDescriber{
$this->writeInt($bits, $value);
}
protected function writeBoundedInt(int $bits, int $min, int $max, int $value) : void{
/**
* @deprecated Use {@link self::boundedIntAuto()} instead.
*/
public function boundedInt(int $bits, int $min, int $max, int &$value) : void{
$offset = $this->offset;
$this->writeBoundedIntAuto($min, $max, $value);
$actualBits = $this->offset - $offset;
if($actualBits !== $bits){
throw new \InvalidArgumentException("Bits should be $actualBits for the given bounds, but received $bits. Use boundedIntAuto() for automatic bits calculation.");
}
}
private function writeBoundedIntAuto(int $min, int $max, int $value) : void{
if($value < $min || $value > $max){
throw new \InvalidArgumentException("Value $value is outside the range $min - $max");
}
$bits = ((int) log($max - $min, 2)) + 1;
$this->writeInt($bits, $value - $min);
}
public function boundedInt(int $bits, int $min, int $max, int &$value) : void{
$this->writeBoundedInt($bits, $min, $max, $value);
public function boundedIntAuto(int $min, int $max, int &$value) : void{
$this->writeBoundedIntAuto($min, $max, $value);
}
protected function writeBool(bool $value) : void{
@ -153,7 +167,7 @@ final class RuntimeDataWriter implements RuntimeDataDescriber{
} * (3 ** $offset);
$offset++;
}
$this->writeBoundedInt(7, 0, (3 ** 4) - 1, $packed);
$this->writeBoundedIntAuto(0, (3 ** 4) - 1, $packed);
}
/**