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
23 changed files with 78 additions and 29 deletions

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);
}
/**