From 0afb67be7df18777f3c385c6056dd7a62126aed6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 27 Jun 2022 15:37:05 +0100 Subject: [PATCH] Improve BlockFactory initialization performance as expected, expanding data range unconditionally resulted in some performance issues ... --- src/block/Anvil.php | 2 ++ src/block/Bamboo.php | 2 ++ src/block/BambooSapling.php | 2 ++ src/block/Barrel.php | 2 ++ src/block/BaseBanner.php | 3 +++ src/block/Bed.php | 2 ++ src/block/Bedrock.php | 2 ++ src/block/Bell.php | 2 ++ src/block/Block.php | 17 +++++++++++++++-- src/block/BlockFactory.php | 6 +++++- src/block/BrewingStand.php | 2 ++ src/block/Button.php | 2 ++ src/block/Cactus.php | 2 ++ src/block/Cake.php | 2 ++ src/block/CocoaBlock.php | 2 ++ src/block/Crops.php | 2 ++ src/block/DaylightSensor.php | 2 ++ src/block/DetectorRail.php | 2 ++ src/block/Dirt.php | 2 ++ src/block/Door.php | 3 +++ src/block/DoublePlant.php | 2 ++ src/block/EndPortalFrame.php | 2 ++ src/block/Farmland.php | 2 ++ src/block/FenceGate.php | 2 ++ src/block/Fire.php | 2 ++ src/block/FloorBanner.php | 2 ++ src/block/FloorCoralFan.php | 2 ++ src/block/FrostedIce.php | 2 ++ src/block/Furnace.php | 2 ++ src/block/Hopper.php | 2 ++ src/block/ItemFrame.php | 2 ++ src/block/Lantern.php | 2 ++ src/block/Leaves.php | 2 ++ src/block/Lectern.php | 2 ++ src/block/Lever.php | 2 ++ src/block/Liquid.php | 2 ++ src/block/NetherPortal.php | 2 ++ src/block/NetherWartPlant.php | 2 ++ src/block/Rail.php | 2 ++ src/block/RedMushroomBlock.php | 2 ++ src/block/RedstoneComparator.php | 2 ++ src/block/RedstoneLamp.php | 2 ++ src/block/RedstoneOre.php | 2 ++ src/block/RedstoneRepeater.php | 2 ++ src/block/RedstoneTorch.php | 2 ++ src/block/Sapling.php | 2 ++ src/block/SeaPickle.php | 2 ++ src/block/ShulkerBox.php | 2 ++ src/block/SimplePressurePlate.php | 2 ++ src/block/Skull.php | 2 ++ src/block/Slab.php | 2 ++ src/block/SnowLayer.php | 2 ++ src/block/Sponge.php | 2 ++ src/block/Stair.php | 2 ++ src/block/StraightOnlyRail.php | 2 ++ src/block/Sugarcane.php | 2 ++ src/block/SweetBerryBush.php | 2 ++ src/block/TNT.php | 2 ++ src/block/Torch.php | 2 ++ src/block/Trapdoor.php | 2 ++ src/block/Tripwire.php | 2 ++ src/block/TripwireHook.php | 2 ++ src/block/Vine.php | 2 ++ src/block/Wall.php | 2 ++ src/block/WallBanner.php | 2 ++ src/block/WallCoralFan.php | 2 ++ .../utils/AnalogRedstoneSignalEmitterTrait.php | 2 ++ src/block/utils/AnyFacingTrait.php | 3 +++ src/block/utils/BlockDataReader.php | 2 ++ src/block/utils/ColoredTrait.php | 2 ++ src/block/utils/CoralTypeTrait.php | 2 ++ src/block/utils/HorizontalFacingTrait.php | 2 ++ src/block/utils/PillarRotationTrait.php | 2 ++ src/block/utils/RailPoweredByRedstoneTrait.php | 2 ++ src/block/utils/SignLikeRotationTrait.php | 2 ++ 75 files changed, 169 insertions(+), 3 deletions(-) diff --git a/src/block/Anvil.php b/src/block/Anvil.php index 25e48ac60b..71fd046257 100644 --- a/src/block/Anvil.php +++ b/src/block/Anvil.php @@ -51,6 +51,8 @@ class Anvil extends Transparent implements Fallable{ return $this->damage << 2; } + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->setDamage($r->readBoundedInt(2, self::UNDAMAGED, self::VERY_DAMAGED)); $this->setFacing($r->readHorizontalFacing()); diff --git a/src/block/Bamboo.php b/src/block/Bamboo.php index a5b2e35e8d..ccd63ced96 100644 --- a/src/block/Bamboo.php +++ b/src/block/Bamboo.php @@ -55,6 +55,8 @@ class Bamboo extends Transparent{ protected bool $ready = false; protected int $leafSize = self::NO_LEAVES; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->setLeafSize($r->readBoundedInt(2, self::NO_LEAVES, self::LARGE_LEAVES)); $this->setThick($r->readBool()); diff --git a/src/block/BambooSapling.php b/src/block/BambooSapling.php index 5d476ff8f5..66b8162417 100644 --- a/src/block/BambooSapling.php +++ b/src/block/BambooSapling.php @@ -36,6 +36,8 @@ use pocketmine\world\BlockTransaction; final class BambooSapling extends Flowable{ private bool $ready = false; + public function getRequiredStateDataBits() : int{ return 1; } + protected function decodeState(BlockDataReader $r) : void{ $this->setReady($r->readBool()); } diff --git a/src/block/Barrel.php b/src/block/Barrel.php index 8979622ba7..748bfd3357 100644 --- a/src/block/Barrel.php +++ b/src/block/Barrel.php @@ -39,6 +39,8 @@ class Barrel extends Opaque{ protected bool $open = false; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->setFacing($r->readFacing()); $this->setOpen($r->readBool()); diff --git a/src/block/BaseBanner.php b/src/block/BaseBanner.php index d785bca1c5..ea33521275 100644 --- a/src/block/BaseBanner.php +++ b/src/block/BaseBanner.php @@ -55,6 +55,9 @@ abstract class BaseBanner extends Transparent{ parent::__construct($idInfo, $name, $breakInfo); } + + public function getRequiredStateDataBits() : int{ return 0; } + protected function decodeState(BlockDataReader $r) : void{ //TODO: we currently purposely don't read or write colour (it's stored on the tile) } diff --git a/src/block/Bed.php b/src/block/Bed.php index 80851c1310..bf9aa730aa 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -54,6 +54,8 @@ class Bed extends Transparent{ parent::__construct($idInfo, $name, $breakInfo); } + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readHorizontalFacing(); $this->occupied = $r->readBool(); diff --git a/src/block/Bedrock.php b/src/block/Bedrock.php index ed77833bb2..3528e8d421 100644 --- a/src/block/Bedrock.php +++ b/src/block/Bedrock.php @@ -29,6 +29,8 @@ use pocketmine\block\utils\BlockDataWriter; class Bedrock extends Opaque{ private bool $burnsForever = false; + public function getRequiredStateDataBits() : int{ return 1; } + protected function decodeState(BlockDataReader $r) : void{ $this->burnsForever = $r->readBool(); } diff --git a/src/block/Bell.php b/src/block/Bell.php index 9a9fad9d98..3388bb5169 100644 --- a/src/block/Bell.php +++ b/src/block/Bell.php @@ -49,6 +49,8 @@ final class Bell extends Transparent{ parent::__construct($idInfo, $name, $breakInfo); } + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->attachmentType = BlockDataReaderHelper::readBellAttachmentType($r); $this->facing = $r->readHorizontalFacing(); diff --git a/src/block/Block.php b/src/block/Block.php index 4bdc776f2d..80da4dea6d 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -100,9 +100,16 @@ class Block{ return 0; } + public function getRequiredStateDataBits() : int{ return 0; } + public function decodeStateData(int $data) : void{ - $reader = new BlockDataReader(self::INTERNAL_STATE_DATA_BITS, $data); + $givenBits = $this->getRequiredStateDataBits(); + $reader = new BlockDataReader($givenBits, $data); $this->decodeState($reader); + $readBits = $reader->getOffset(); + if($givenBits !== $readBits){ + throw new \LogicException("Exactly $givenBits bits of state data were provided, but only $readBits were read"); + } } protected function decodeState(BlockDataReader $r) : void{ @@ -113,8 +120,14 @@ class Block{ * @internal */ public function computeStateData() : int{ - $writer = new BlockDataWriter(self::INTERNAL_STATE_DATA_BITS); + $requiredBits = $this->getRequiredStateDataBits(); + $writer = new BlockDataWriter($requiredBits); $this->encodeState($writer); + + $writtenBits = $writer->getOffset(); + if($requiredBits !== $writtenBits){ + throw new \LogicException("Exactly $requiredBits bits of state data were expected, but only $writtenBits were written"); + } return $writer->getValue(); } diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 7af1685228..1e3c48a1b7 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -864,7 +864,11 @@ class BlockFactory{ //TODO: this bruteforce approach to discovering all valid states is very inefficient for larger state data sizes //at some point we'll need to find a better way to do this - for($stateData = 0; $stateData < (1 << Block::INTERNAL_STATE_DATA_BITS); ++$stateData){ + $bits = $block->getRequiredStateDataBits(); + if($bits > Block::INTERNAL_STATE_DATA_BITS){ + throw new \InvalidArgumentException("Block state data cannot use more than " . Block::INTERNAL_STATE_DATA_BITS . " bits"); + } + for($stateData = 0; $stateData < (1 << $bits); ++$stateData){ $v = clone $block; try{ $v->decodeStateData($stateData); diff --git a/src/block/BrewingStand.php b/src/block/BrewingStand.php index 20b1d802e9..5c732689ea 100644 --- a/src/block/BrewingStand.php +++ b/src/block/BrewingStand.php @@ -46,6 +46,8 @@ class BrewingStand extends Transparent{ */ protected array $slots = []; + public function getRequiredStateDataBits() : int{ return 3; } + protected function decodeState(BlockDataReader $r) : void{ $this->setSlots(BlockDataReaderHelper::readBrewingStandSlotKeySet($r)); } diff --git a/src/block/Button.php b/src/block/Button.php index 6e45df5593..82db565efd 100644 --- a/src/block/Button.php +++ b/src/block/Button.php @@ -39,6 +39,8 @@ abstract class Button extends Flowable{ protected bool $pressed = false; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readFacing(); $this->pressed = $r->readBool(); diff --git a/src/block/Cactus.php b/src/block/Cactus.php index 56b9129a3f..3b69e0f436 100644 --- a/src/block/Cactus.php +++ b/src/block/Cactus.php @@ -42,6 +42,8 @@ class Cactus extends Transparent{ protected int $age = 0; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->age = $r->readBoundedInt(4, 0, self::MAX_AGE); } diff --git a/src/block/Cake.php b/src/block/Cake.php index 770b8fcfe3..40b100f0b3 100644 --- a/src/block/Cake.php +++ b/src/block/Cake.php @@ -41,6 +41,8 @@ class Cake extends Transparent implements FoodSource{ protected int $bites = 0; + public function getRequiredStateDataBits() : int{ return 3; } + protected function decodeState(BlockDataReader $r) : void{ $this->bites = $r->readBoundedInt(3, 0, self::MAX_BITES); } diff --git a/src/block/CocoaBlock.php b/src/block/CocoaBlock.php index b21af5e635..89f8bccf60 100644 --- a/src/block/CocoaBlock.php +++ b/src/block/CocoaBlock.php @@ -47,6 +47,8 @@ class CocoaBlock extends Transparent{ protected int $age = 0; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readHorizontalFacing(); $this->age = $r->readBoundedInt(2, 0, self::MAX_AGE); diff --git a/src/block/Crops.php b/src/block/Crops.php index f7823a8eb5..a4976f0442 100644 --- a/src/block/Crops.php +++ b/src/block/Crops.php @@ -39,6 +39,8 @@ abstract class Crops extends Flowable{ protected int $age = 0; + public function getRequiredStateDataBits() : int{ return 3; } + protected function decodeState(BlockDataReader $r) : void{ $this->age = $r->readBoundedInt(3, 0, self::MAX_AGE); } diff --git a/src/block/DaylightSensor.php b/src/block/DaylightSensor.php index 01c7040a4c..da4c034a87 100644 --- a/src/block/DaylightSensor.php +++ b/src/block/DaylightSensor.php @@ -42,6 +42,8 @@ class DaylightSensor extends Transparent{ protected bool $inverted = false; + public function getRequiredStateDataBits() : int{ return 5; } + protected function decodeState(BlockDataReader $r) : void{ $this->signalStrength = $r->readBoundedInt(4, 0, 15); $this->inverted = $r->readBool(); diff --git a/src/block/DetectorRail.php b/src/block/DetectorRail.php index ad4d95810e..ecf7ee50d3 100644 --- a/src/block/DetectorRail.php +++ b/src/block/DetectorRail.php @@ -29,6 +29,8 @@ use pocketmine\block\utils\BlockDataWriter; class DetectorRail extends StraightOnlyRail{ protected bool $activated = false; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ parent::decodeState($r); $this->activated = $r->readBool(); diff --git a/src/block/Dirt.php b/src/block/Dirt.php index d926000aa9..f163beebe9 100644 --- a/src/block/Dirt.php +++ b/src/block/Dirt.php @@ -39,6 +39,8 @@ class Dirt extends Opaque{ return $this->coarse ? BlockLegacyMetadata::DIRT_FLAG_COARSE : 0; } + public function getRequiredStateDataBits() : int{ return 1; } + protected function decodeState(BlockDataReader $r) : void{ $this->coarse = $r->readBool(); } diff --git a/src/block/Door.php b/src/block/Door.php index 6f3654ca5d..f6ad3a16c8 100644 --- a/src/block/Door.php +++ b/src/block/Door.php @@ -42,6 +42,9 @@ class Door extends Transparent{ protected bool $hingeRight = false; protected bool $open = false; + + public function getRequiredStateDataBits() : int{ return 5; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readHorizontalFacing(); $this->top = $r->readBool(); diff --git a/src/block/DoublePlant.php b/src/block/DoublePlant.php index 14d363794f..add4fce8ee 100644 --- a/src/block/DoublePlant.php +++ b/src/block/DoublePlant.php @@ -34,6 +34,8 @@ use pocketmine\world\BlockTransaction; class DoublePlant extends Flowable{ protected bool $top = false; + public function getRequiredStateDataBits() : int{ return 1; } + protected function decodeState(BlockDataReader $r) : void{ $this->top = $r->readBool(); } diff --git a/src/block/EndPortalFrame.php b/src/block/EndPortalFrame.php index e9c69b1fc4..aace740a63 100644 --- a/src/block/EndPortalFrame.php +++ b/src/block/EndPortalFrame.php @@ -36,6 +36,8 @@ class EndPortalFrame extends Opaque{ protected bool $eye = false; + public function getRequiredStateDataBits() : int{ return 3; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readHorizontalFacing(); $this->eye = $r->readBool(); diff --git a/src/block/Farmland.php b/src/block/Farmland.php index 8dfb3f6f76..97a24fa72b 100644 --- a/src/block/Farmland.php +++ b/src/block/Farmland.php @@ -38,6 +38,8 @@ class Farmland extends Transparent{ protected int $wetness = 0; //"moisture" blockstate property in PC + public function getRequiredStateDataBits() : int{ return 3; } + protected function decodeState(BlockDataReader $r) : void{ $this->wetness = $r->readBoundedInt(3, 0, self::MAX_WETNESS); } diff --git a/src/block/FenceGate.php b/src/block/FenceGate.php index 0cec6374ec..1541322bb5 100644 --- a/src/block/FenceGate.php +++ b/src/block/FenceGate.php @@ -41,6 +41,8 @@ class FenceGate extends Transparent{ protected bool $open = false; protected bool $inWall = false; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readHorizontalFacing(); $this->open = $r->readBool(); diff --git a/src/block/Fire.php b/src/block/Fire.php index b9da2f33a5..d13ca247ab 100644 --- a/src/block/Fire.php +++ b/src/block/Fire.php @@ -46,6 +46,8 @@ class Fire extends Flowable{ protected int $age = 0; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->age = $r->readBoundedInt(4, 0, self::MAX_AGE); } diff --git a/src/block/FloorBanner.php b/src/block/FloorBanner.php index 5e0074477c..8da061e9b6 100644 --- a/src/block/FloorBanner.php +++ b/src/block/FloorBanner.php @@ -38,6 +38,8 @@ final class FloorBanner extends BaseBanner{ encodeState as encodeRotation; } + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ parent::decodeState($r); $this->decodeRotation($r); diff --git a/src/block/FloorCoralFan.php b/src/block/FloorCoralFan.php index d1515eef93..8e5377f231 100644 --- a/src/block/FloorCoralFan.php +++ b/src/block/FloorCoralFan.php @@ -52,6 +52,8 @@ final class FloorCoralFan extends BaseCoral{ return CoralTypeIdMap::getInstance()->toId($this->coralType); } + public function getRequiredStateDataBits() : int{ return parent::getRequiredStateDataBits() + 1; } + protected function decodeState(BlockDataReader $r) : void{ parent::decodeState($r); $this->axis = $r->readHorizontalAxis(); diff --git a/src/block/FrostedIce.php b/src/block/FrostedIce.php index e6addea5cd..be19be5b48 100644 --- a/src/block/FrostedIce.php +++ b/src/block/FrostedIce.php @@ -33,6 +33,8 @@ class FrostedIce extends Ice{ protected int $age = 0; + public function getRequiredStateDataBits() : int{ return 2; } + protected function decodeState(BlockDataReader $r) : void{ $this->age = $r->readBoundedInt(2, 0, self::MAX_AGE); } diff --git a/src/block/Furnace.php b/src/block/Furnace.php index 1bb6191aa8..0dc1e0d1c2 100644 --- a/src/block/Furnace.php +++ b/src/block/Furnace.php @@ -39,6 +39,8 @@ class Furnace extends Opaque{ protected bool $lit = false; + public function getRequiredStateDataBits() : int{ return 3; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readHorizontalFacing(); $this->lit = $r->readBool(); diff --git a/src/block/Hopper.php b/src/block/Hopper.php index 320fd1ce7d..f8ce02fd7e 100644 --- a/src/block/Hopper.php +++ b/src/block/Hopper.php @@ -41,6 +41,8 @@ class Hopper extends Transparent{ private int $facing = Facing::DOWN; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $facing = $r->readFacing(); if($facing === Facing::UP){ diff --git a/src/block/ItemFrame.php b/src/block/ItemFrame.php index 31f802f1dc..762b5d6b0f 100644 --- a/src/block/ItemFrame.php +++ b/src/block/ItemFrame.php @@ -47,6 +47,8 @@ class ItemFrame extends Flowable{ protected int $itemRotation = 0; protected float $itemDropChance = 1.0; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readFacing(); $this->hasMap = $r->readBool(); diff --git a/src/block/Lantern.php b/src/block/Lantern.php index ec54070f33..54a7e1b8cd 100644 --- a/src/block/Lantern.php +++ b/src/block/Lantern.php @@ -37,6 +37,8 @@ use pocketmine\world\BlockTransaction; class Lantern extends Transparent{ protected bool $hanging = false; + public function getRequiredStateDataBits() : int{ return 1; } + protected function decodeState(BlockDataReader $r) : void{ $this->hanging = $r->readBool(); } diff --git a/src/block/Leaves.php b/src/block/Leaves.php index 4a753db521..77d557f599 100644 --- a/src/block/Leaves.php +++ b/src/block/Leaves.php @@ -49,6 +49,8 @@ class Leaves extends Transparent{ $this->treeType = $treeType; } + public function getRequiredStateDataBits() : int{ return 2; } + protected function decodeState(BlockDataReader $r) : void{ $this->noDecay = $r->readBool(); $this->checkDecay = $r->readBool(); diff --git a/src/block/Lectern.php b/src/block/Lectern.php index 7f8e731053..708dcd47db 100644 --- a/src/block/Lectern.php +++ b/src/block/Lectern.php @@ -47,6 +47,8 @@ class Lectern extends Transparent{ protected bool $producingSignal = false; + public function getRequiredStateDataBits() : int{ return 3; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readHorizontalFacing(); $this->producingSignal = $r->readBool(); diff --git a/src/block/Lever.php b/src/block/Lever.php index bf006d30e6..652dd72862 100644 --- a/src/block/Lever.php +++ b/src/block/Lever.php @@ -47,6 +47,8 @@ class Lever extends Flowable{ parent::__construct($idInfo, $name, $breakInfo); } + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = BlockDataReaderHelper::readLeverFacing($r); $this->activated = $r->readBool(); diff --git a/src/block/Liquid.php b/src/block/Liquid.php index e3aca2a520..dca825ad80 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -49,6 +49,8 @@ abstract class Liquid extends Transparent{ protected int $decay = 0; //PC "level" property protected bool $still = false; + public function getRequiredStateDataBits() : int{ return 5; } + protected function decodeState(BlockDataReader $r) : void{ $this->decay = $r->readBoundedInt(3, 0, self::MAX_DECAY); $this->falling = $r->readBool(); diff --git a/src/block/NetherPortal.php b/src/block/NetherPortal.php index 0d94449e08..5317de232f 100644 --- a/src/block/NetherPortal.php +++ b/src/block/NetherPortal.php @@ -35,6 +35,8 @@ class NetherPortal extends Transparent{ protected int $axis = Axis::X; + public function getRequiredStateDataBits() : int{ return 1; } + protected function decodeState(BlockDataReader $r) : void{ $this->axis = $r->readHorizontalAxis(); } diff --git a/src/block/NetherWartPlant.php b/src/block/NetherWartPlant.php index b07644fa51..9cd1516576 100644 --- a/src/block/NetherWartPlant.php +++ b/src/block/NetherWartPlant.php @@ -38,6 +38,8 @@ class NetherWartPlant extends Flowable{ protected int $age = 0; + public function getRequiredStateDataBits() : int{ return 2; } + protected function decodeState(BlockDataReader $r) : void{ $this->age = $r->readBoundedInt(2, 0, self::MAX_AGE); } diff --git a/src/block/Rail.php b/src/block/Rail.php index 4b5ae94d67..dc93f15d66 100644 --- a/src/block/Rail.php +++ b/src/block/Rail.php @@ -35,6 +35,8 @@ class Rail extends BaseRail{ private int $railShape = BlockLegacyMetadata::RAIL_STRAIGHT_NORTH_SOUTH; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $railShape = $r->readInt(4); if(!isset(RailConnectionInfo::CONNECTIONS[$railShape]) && !isset(RailConnectionInfo::CURVE_CONNECTIONS[$railShape])){ diff --git a/src/block/RedMushroomBlock.php b/src/block/RedMushroomBlock.php index f2a22a7441..22a141d2a2 100644 --- a/src/block/RedMushroomBlock.php +++ b/src/block/RedMushroomBlock.php @@ -39,6 +39,8 @@ class RedMushroomBlock extends Opaque{ parent::__construct($idInfo, $name, $breakInfo); } + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->mushroomBlockType = BlockDataReaderHelper::readMushroomBlockType($r); } diff --git a/src/block/RedstoneComparator.php b/src/block/RedstoneComparator.php index 8abb70a217..cc2dbaa89a 100644 --- a/src/block/RedstoneComparator.php +++ b/src/block/RedstoneComparator.php @@ -45,6 +45,8 @@ class RedstoneComparator extends Flowable{ protected bool $isSubtractMode = false; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readHorizontalFacing(); $this->isSubtractMode = $r->readBool(); diff --git a/src/block/RedstoneLamp.php b/src/block/RedstoneLamp.php index de84d7445b..6a6919edc1 100644 --- a/src/block/RedstoneLamp.php +++ b/src/block/RedstoneLamp.php @@ -30,6 +30,8 @@ use pocketmine\block\utils\PoweredByRedstoneTrait; class RedstoneLamp extends Opaque{ use PoweredByRedstoneTrait; + public function getRequiredStateDataBits() : int{ return 1; } + protected function decodeState(BlockDataReader $r) : void{ $this->powered = $r->readBool(); } diff --git a/src/block/RedstoneOre.php b/src/block/RedstoneOre.php index 29946ee474..7695218574 100644 --- a/src/block/RedstoneOre.php +++ b/src/block/RedstoneOre.php @@ -34,6 +34,8 @@ use function mt_rand; class RedstoneOre extends Opaque{ protected bool $lit = false; + public function getRequiredStateDataBits() : int{ return 1; } + protected function decodeState(BlockDataReader $r) : void{ $this->lit = $r->readBool(); } diff --git a/src/block/RedstoneRepeater.php b/src/block/RedstoneRepeater.php index ed6fe01a6b..c56869f9a1 100644 --- a/src/block/RedstoneRepeater.php +++ b/src/block/RedstoneRepeater.php @@ -44,6 +44,8 @@ class RedstoneRepeater extends Flowable{ protected int $delay = self::MIN_DELAY; + public function getRequiredStateDataBits() : int{ return 5; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readHorizontalFacing(); $this->delay = $r->readBoundedInt(2, self::MIN_DELAY - 1, self::MAX_DELAY - 1) + 1; diff --git a/src/block/RedstoneTorch.php b/src/block/RedstoneTorch.php index 78d5d282c5..ada02e26c6 100644 --- a/src/block/RedstoneTorch.php +++ b/src/block/RedstoneTorch.php @@ -29,6 +29,8 @@ use pocketmine\block\utils\BlockDataWriter; class RedstoneTorch extends Torch{ protected bool $lit = true; + public function getRequiredStateDataBits() : int{ return parent::getRequiredStateDataBits() + 1; } + protected function decodeState(BlockDataReader $r) : void{ parent::decodeState($r); $this->lit = $r->readBool(); diff --git a/src/block/Sapling.php b/src/block/Sapling.php index 1c4e87b59d..f2bfd2af44 100644 --- a/src/block/Sapling.php +++ b/src/block/Sapling.php @@ -47,6 +47,8 @@ class Sapling extends Flowable{ $this->treeType = $treeType; } + public function getRequiredStateDataBits() : int{ return 1; } + protected function decodeState(BlockDataReader $r) : void{ $this->ready = $r->readBool(); } diff --git a/src/block/SeaPickle.php b/src/block/SeaPickle.php index b2e3047653..c85d700a91 100644 --- a/src/block/SeaPickle.php +++ b/src/block/SeaPickle.php @@ -39,6 +39,8 @@ class SeaPickle extends Transparent{ protected int $count = self::MIN_COUNT; protected bool $underwater = false; + public function getRequiredStateDataBits() : int{ return 3; } + protected function decodeState(BlockDataReader $r) : void{ $this->count = $r->readBoundedInt(2, self::MIN_COUNT - 1, self::MAX_COUNT - 1) + 1; $this->underwater = $r->readBool(); diff --git a/src/block/ShulkerBox.php b/src/block/ShulkerBox.php index b602555acc..bec196838a 100644 --- a/src/block/ShulkerBox.php +++ b/src/block/ShulkerBox.php @@ -35,6 +35,8 @@ use pocketmine\world\BlockTransaction; class ShulkerBox extends Opaque{ use AnyFacingTrait; + public function getRequiredStateDataBits() : int{ return 0; } + protected function decodeState(BlockDataReader $r) : void{ //NOOP - we don't read or write facing here, because the tile persists it } diff --git a/src/block/SimplePressurePlate.php b/src/block/SimplePressurePlate.php index 205583b41b..7bdfc71186 100644 --- a/src/block/SimplePressurePlate.php +++ b/src/block/SimplePressurePlate.php @@ -29,6 +29,8 @@ use pocketmine\block\utils\BlockDataWriter; abstract class SimplePressurePlate extends PressurePlate{ protected bool $pressed = false; + public function getRequiredStateDataBits() : int{ return 1; } + protected function decodeState(BlockDataReader $r) : void{ $this->pressed = $r->readBool(); } diff --git a/src/block/Skull.php b/src/block/Skull.php index 3495027afc..50b56f3d03 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -51,6 +51,8 @@ class Skull extends Flowable{ parent::__construct($idInfo, $name, $breakInfo); } + public function getRequiredStateDataBits() : int{ return 3; } + protected function decodeState(BlockDataReader $r) : void{ $facing = $r->readFacing(); if($facing === Facing::DOWN){ diff --git a/src/block/Slab.php b/src/block/Slab.php index c39e0de84c..6abab61f6c 100644 --- a/src/block/Slab.php +++ b/src/block/Slab.php @@ -44,6 +44,8 @@ class Slab extends Transparent{ $this->slabType = SlabType::BOTTOM(); } + public function getRequiredStateDataBits() : int{ return 2; } + protected function decodeState(BlockDataReader $r) : void{ $this->slabType = BlockDataReaderHelper::readSlabType($r); } diff --git a/src/block/SnowLayer.php b/src/block/SnowLayer.php index 193d177998..9894dd43a6 100644 --- a/src/block/SnowLayer.php +++ b/src/block/SnowLayer.php @@ -47,6 +47,8 @@ class SnowLayer extends Flowable implements Fallable{ protected int $layers = self::MIN_LAYERS; + public function getRequiredStateDataBits() : int{ return 3; } + protected function decodeState(BlockDataReader $r) : void{ $this->layers = $r->readBoundedInt(3, self::MIN_LAYERS - 1, self::MAX_LAYERS - 1) + 1; } diff --git a/src/block/Sponge.php b/src/block/Sponge.php index f5ee824bb3..8f90242684 100644 --- a/src/block/Sponge.php +++ b/src/block/Sponge.php @@ -33,6 +33,8 @@ class Sponge extends Opaque{ return $this->wet ? BlockLegacyMetadata::SPONGE_FLAG_WET : 0; } + public function getRequiredStateDataBits() : int{ return 1; } + protected function decodeState(BlockDataReader $r) : void{ $this->wet = $r->readBool(); } diff --git a/src/block/Stair.php b/src/block/Stair.php index ab188c53a7..9242b36ab7 100644 --- a/src/block/Stair.php +++ b/src/block/Stair.php @@ -47,6 +47,8 @@ class Stair extends Transparent{ parent::__construct($idInfo, $name, $breakInfo); } + public function getRequiredStateDataBits() : int{ return 3; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readHorizontalFacing(); $this->upsideDown = $r->readBool(); diff --git a/src/block/StraightOnlyRail.php b/src/block/StraightOnlyRail.php index 8d9642987e..c2c171642e 100644 --- a/src/block/StraightOnlyRail.php +++ b/src/block/StraightOnlyRail.php @@ -37,6 +37,8 @@ class StraightOnlyRail extends BaseRail{ private int $railShape = BlockLegacyMetadata::RAIL_STRAIGHT_NORTH_SOUTH; + public function getRequiredStateDataBits() : int{ return 3; } + protected function decodeState(BlockDataReader $r) : void{ $railShape = $r->readInt(3); if(!isset(RailConnectionInfo::CONNECTIONS[$railShape])){ diff --git a/src/block/Sugarcane.php b/src/block/Sugarcane.php index 51726bcff4..320a484f8b 100644 --- a/src/block/Sugarcane.php +++ b/src/block/Sugarcane.php @@ -38,6 +38,8 @@ class Sugarcane extends Flowable{ protected int $age = 0; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->age = $r->readBoundedInt(4, 0, self::MAX_AGE); } diff --git a/src/block/SweetBerryBush.php b/src/block/SweetBerryBush.php index 3fdfc9a4d4..a8c302d611 100644 --- a/src/block/SweetBerryBush.php +++ b/src/block/SweetBerryBush.php @@ -46,6 +46,8 @@ class SweetBerryBush extends Flowable{ protected int $age = self::STAGE_SAPLING; + public function getRequiredStateDataBits() : int{ return 3; } + protected function decodeState(BlockDataReader $r) : void{ $this->age = $r->readBoundedInt(3, self::STAGE_SAPLING, self::STAGE_MATURE); } diff --git a/src/block/TNT.php b/src/block/TNT.php index 18dea8793a..80f83e0151 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -49,6 +49,8 @@ class TNT extends Opaque{ return $this->worksUnderwater ? BlockLegacyMetadata::TNT_FLAG_UNDERWATER : 0; } + public function getRequiredStateDataBits() : int{ return 2; } + protected function decodeState(BlockDataReader $r) : void{ $this->unstable = $r->readBool(); $this->worksUnderwater = $r->readBool(); diff --git a/src/block/Torch.php b/src/block/Torch.php index d9e3ed95da..02cbec2d29 100644 --- a/src/block/Torch.php +++ b/src/block/Torch.php @@ -38,6 +38,8 @@ class Torch extends Flowable{ protected int $facing = Facing::UP; + public function getRequiredStateDataBits() : int{ return 3; } + protected function decodeState(BlockDataReader $r) : void{ $facing = $r->readFacing(); if($facing === Facing::DOWN){ diff --git a/src/block/Trapdoor.php b/src/block/Trapdoor.php index 61d4d58c9a..42f973a4b3 100644 --- a/src/block/Trapdoor.php +++ b/src/block/Trapdoor.php @@ -41,6 +41,8 @@ class Trapdoor extends Transparent{ protected bool $open = false; protected bool $top = false; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readHorizontalFacing(); $this->top = $r->readBool(); diff --git a/src/block/Tripwire.php b/src/block/Tripwire.php index bb045c782c..954fa888aa 100644 --- a/src/block/Tripwire.php +++ b/src/block/Tripwire.php @@ -32,6 +32,8 @@ class Tripwire extends Flowable{ protected bool $connected = false; protected bool $disarmed = false; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->triggered = $r->readBool(); $this->suspended = $r->readBool(); diff --git a/src/block/TripwireHook.php b/src/block/TripwireHook.php index b0fc4876ff..2f76f184fb 100644 --- a/src/block/TripwireHook.php +++ b/src/block/TripwireHook.php @@ -39,6 +39,8 @@ class TripwireHook extends Flowable{ protected bool $connected = false; protected bool $powered = false; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readHorizontalFacing(); $this->connected = $r->readBool(); diff --git a/src/block/Vine.php b/src/block/Vine.php index 4505bb3666..1ac2157efd 100644 --- a/src/block/Vine.php +++ b/src/block/Vine.php @@ -40,6 +40,8 @@ class Vine extends Flowable{ /** @var int[] */ protected array $faces = []; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ foreach(Facing::HORIZONTAL as $facing){ $this->setFace($facing, $r->readBool()); diff --git a/src/block/Wall.php b/src/block/Wall.php index a97aba751b..ae781b32d0 100644 --- a/src/block/Wall.php +++ b/src/block/Wall.php @@ -43,6 +43,8 @@ class Wall extends Transparent{ protected array $connections = []; protected bool $post = false; + public function getRequiredStateDataBits() : int{ return 9; } + protected function decodeState(BlockDataReader $r) : void{ $this->connections = $r->readWallConnections(); $this->post = $r->readBool(); diff --git a/src/block/WallBanner.php b/src/block/WallBanner.php index f3e3b251da..8eee17959d 100644 --- a/src/block/WallBanner.php +++ b/src/block/WallBanner.php @@ -39,6 +39,8 @@ final class WallBanner extends BaseBanner{ encodeState as encodeFacing; } + public function getRequiredStateDataBits() : int{ return 2; } + protected function decodeState(BlockDataReader $r) : void{ parent::decodeState($r); $this->decodeFacing($r); diff --git a/src/block/WallCoralFan.php b/src/block/WallCoralFan.php index 5e95803e7a..125fda9074 100644 --- a/src/block/WallCoralFan.php +++ b/src/block/WallCoralFan.php @@ -43,6 +43,8 @@ final class WallCoralFan extends BaseCoral{ return CoralTypeIdMap::getInstance()->toId($this->coralType); } + public function getRequiredStateDataBits() : int{ return parent::getRequiredStateDataBits() + 2; } + protected function decodeState(BlockDataReader $r) : void{ parent::decodeState($r); $this->facing = $r->readHorizontalFacing(); diff --git a/src/block/utils/AnalogRedstoneSignalEmitterTrait.php b/src/block/utils/AnalogRedstoneSignalEmitterTrait.php index 0089e5a023..aa037f1ca7 100644 --- a/src/block/utils/AnalogRedstoneSignalEmitterTrait.php +++ b/src/block/utils/AnalogRedstoneSignalEmitterTrait.php @@ -26,6 +26,8 @@ namespace pocketmine\block\utils; trait AnalogRedstoneSignalEmitterTrait{ protected int $signalStrength = 0; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->signalStrength = $r->readBoundedInt(4, 0, 15); } diff --git a/src/block/utils/AnyFacingTrait.php b/src/block/utils/AnyFacingTrait.php index 0394d60a41..6c9e35e6b4 100644 --- a/src/block/utils/AnyFacingTrait.php +++ b/src/block/utils/AnyFacingTrait.php @@ -28,6 +28,9 @@ use pocketmine\math\Facing; trait AnyFacingTrait{ protected int $facing = Facing::DOWN; + + public function getRequiredStateDataBits() : int{ return 3; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readFacing(); } diff --git a/src/block/utils/BlockDataReader.php b/src/block/utils/BlockDataReader.php index 22d55dbc86..dbb3f93860 100644 --- a/src/block/utils/BlockDataReader.php +++ b/src/block/utils/BlockDataReader.php @@ -118,4 +118,6 @@ final class BlockDataReader{ return $connections; } + + public function getOffset() : int{ return $this->offset; } } diff --git a/src/block/utils/ColoredTrait.php b/src/block/utils/ColoredTrait.php index 908f1bf6ac..a8efd46ae2 100644 --- a/src/block/utils/ColoredTrait.php +++ b/src/block/utils/ColoredTrait.php @@ -37,6 +37,8 @@ trait ColoredTrait{ return DyeColorIdMap::getInstance()->toId($this->color); } + public function getRequiredStateDataBits() : int{ return 4; } + /** @see Block::decodeState() */ protected function decodeState(BlockDataReader $r) : void{ $this->color = BlockDataReaderHelper::readDyeColor($r); diff --git a/src/block/utils/CoralTypeTrait.php b/src/block/utils/CoralTypeTrait.php index 7f7f5be8f0..c91213a13a 100644 --- a/src/block/utils/CoralTypeTrait.php +++ b/src/block/utils/CoralTypeTrait.php @@ -27,6 +27,8 @@ trait CoralTypeTrait{ protected CoralType $coralType; protected bool $dead = false; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->coralType = BlockDataReaderHelper::readCoralType($r); $this->dead = $r->readBool(); diff --git a/src/block/utils/HorizontalFacingTrait.php b/src/block/utils/HorizontalFacingTrait.php index 13a3d913cb..0da0a9ca12 100644 --- a/src/block/utils/HorizontalFacingTrait.php +++ b/src/block/utils/HorizontalFacingTrait.php @@ -29,6 +29,8 @@ use pocketmine\math\Facing; trait HorizontalFacingTrait{ protected int $facing = Facing::NORTH; + public function getRequiredStateDataBits() : int{ return 2; } + protected function decodeState(BlockDataReader $r) : void{ $this->facing = $r->readHorizontalFacing(); } diff --git a/src/block/utils/PillarRotationTrait.php b/src/block/utils/PillarRotationTrait.php index 3da41373c7..1d4503ff76 100644 --- a/src/block/utils/PillarRotationTrait.php +++ b/src/block/utils/PillarRotationTrait.php @@ -34,6 +34,8 @@ use pocketmine\world\BlockTransaction; trait PillarRotationTrait{ protected int $axis = Axis::Y; + public function getRequiredStateDataBits() : int{ return 2; } + protected function decodeState(BlockDataReader $r) : void{ $this->axis = $r->readAxis(); } diff --git a/src/block/utils/RailPoweredByRedstoneTrait.php b/src/block/utils/RailPoweredByRedstoneTrait.php index c65f0c8b92..9bc98303a9 100644 --- a/src/block/utils/RailPoweredByRedstoneTrait.php +++ b/src/block/utils/RailPoweredByRedstoneTrait.php @@ -26,6 +26,8 @@ namespace pocketmine\block\utils; trait RailPoweredByRedstoneTrait{ use PoweredByRedstoneTrait; + public function getRequiredStateDataBits() : int{ return parent::getRequiredStateDataBits() + 1; } + protected function decodeState(BlockDataReader $r) : void{ parent::decodeState($r); $this->powered = $r->readBool(); diff --git a/src/block/utils/SignLikeRotationTrait.php b/src/block/utils/SignLikeRotationTrait.php index e35bf35745..e4ee5f8689 100644 --- a/src/block/utils/SignLikeRotationTrait.php +++ b/src/block/utils/SignLikeRotationTrait.php @@ -29,6 +29,8 @@ trait SignLikeRotationTrait{ /** @var int */ private $rotation = 0; + public function getRequiredStateDataBits() : int{ return 4; } + protected function decodeState(BlockDataReader $r) : void{ $this->rotation = $r->readBoundedInt(4, 0, 15); }