Block: Separate encoding of type and state data

the terminology of this needs improvement, but...

the basic concept here is that 'type' data will persist on an itemstack, while 'state' data will not.

Type data consists of things like:
- Colour
- Coral type
- Wet/dry (sponges)
- Live/dead (coral)
- Wood type

State data consists of things like:
- Facing
- Axis
- Powered/unpowered
- Open/closed

In the past, with the old system, this information was separated by way of getStateBitmask(). This solution was fraught with problems, but achieved the basic goal: removing unwanted block properties from items.
This commit is contained in:
Dylan K. Taylor
2022-06-30 18:08:34 +01:00
parent c22a840d27
commit 2a0b500010
18 changed files with 112 additions and 80 deletions

View File

@ -108,16 +108,31 @@ class Block{
return 0;
}
public function getRequiredTypeDataBits() : int{ return 0; }
public function getRequiredStateDataBits() : int{ return 0; }
final public function decodeStateData(int $data) : void{
$givenBits = $this->getRequiredStateDataBits();
$typeBits = $this->getRequiredTypeDataBits();
$stateBits = $this->getRequiredStateDataBits();
$givenBits = $typeBits + $stateBits;
$reader = new BlockDataReader($givenBits, $data);
$this->decodeState($reader);
$this->decodeType($reader);
$readBits = $reader->getOffset();
if($givenBits !== $readBits){
throw new \LogicException("Exactly $givenBits bits of state data were provided, but only $readBits were read");
if($typeBits !== $readBits){
throw new \LogicException("Exactly $typeBits bits of type data were provided, but $readBits were read");
}
$this->decodeState($reader);
$readBits = $reader->getOffset() - $typeBits;
if($stateBits !== $readBits){
throw new \LogicException("Exactly $stateBits bits of state data were provided, but $readBits were read");
}
}
protected function decodeType(BlockDataReader $r) : void{
//NOOP
}
protected function decodeState(BlockDataReader $r) : void{
@ -128,17 +143,30 @@ class Block{
* @internal
*/
final public function computeStateData() : int{
$requiredBits = $this->getRequiredStateDataBits();
$typeBits = $this->getRequiredTypeDataBits();
$stateBits = $this->getRequiredStateDataBits();
$requiredBits = $typeBits + $stateBits;
$writer = new BlockDataWriter($requiredBits);
$this->encodeState($writer);
$this->encodeType($writer);
$writtenBits = $writer->getOffset();
if($requiredBits !== $writtenBits){
throw new \LogicException("Exactly $requiredBits bits of state data were expected, but only $writtenBits were written");
if($typeBits !== $writtenBits){
throw new \LogicException("Exactly $typeBits bits of type data were expected, but $writtenBits were written");
}
$this->encodeState($writer);
$writtenBits = $writer->getOffset() - $typeBits;
if($stateBits !== $writtenBits){
throw new \LogicException("Exactly $stateBits bits of state data were expected, but $writtenBits were written");
}
return $writer->getValue();
}
protected function encodeType(BlockDataWriter $w) : void{
//NOOP
}
protected function encodeState(BlockDataWriter $w) : void{
//NOOP
}