33 private int $value = 0;
34 private int $offset = 0;
36 public function __construct(
40 public function writeInt(
int $bits,
int $value) :
void{
41 if($this->offset + $bits > $this->maxBits){
42 throw new \InvalidArgumentException(
"Bit buffer cannot be larger than $this->maxBits bits (already have $this->offset bits)");
44 if(($value & (~0 << $bits)) !== 0){
45 throw new \InvalidArgumentException(
"Value $value does not fit into $bits bits");
48 $this->value |= ($value << $this->offset);
49 $this->offset += $bits;
52 public function int(
int $bits,
int &$value) :
void{
53 $this->writeInt($bits, $value);
56 private function writeBoundedIntAuto(
int $min,
int $max,
int $value) :
void{
57 if($value < $min || $value > $max){
58 throw new \InvalidArgumentException(
"Value $value is outside the range $min - $max");
60 $bits = ((int) log($max - $min, 2)) + 1;
61 $this->writeInt($bits, $value - $min);
65 $this->writeBoundedIntAuto($min, $max, $value);
68 protected function writeBool(
bool $value) : void{
69 $this->writeInt(1, $value ? 1 : 0);
72 public function bool(
bool &$value) : void{
73 $this->writeBool($value);
76 public function facingExcept(Facing &$facing, Facing $except) : void{
80 public function horizontalAxis(Axis &$axis) : void{
81 $this->writeInt(1, match($axis){
84 default =>
throw new \InvalidArgumentException(
"Invalid horizontal axis $axis->name")
95 foreach(Facing::HORIZONTAL as $facing){
96 $packed += match($connections[$facing->value] ??
null){
98 WallConnectionType::SHORT => 1,
99 WallConnectionType::TALL => 2,
103 $this->writeBoundedIntAuto(0, (3 ** 4) - 1, $packed);
106 public function enum(\UnitEnum &$case) : void{
108 $this->writeInt($metadata->bits, $metadata->enumToInt($case));
111 public function enumSet(array &$set, array $allCases) : void{
112 foreach($allCases as $case){
113 $this->writeBool(isset($set[spl_object_id($case)]));
117 public function getValue() : int{ return $this->value; }
119 public function getOffset() : int{ return $this->offset; }