mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-21 08:17:34 +00:00
RuntimeBlockStateRegistry: separate permutation expansion from register()
This commit is contained in:
parent
75f74454c6
commit
4c3892b2d6
@ -29,6 +29,7 @@ use pocketmine\data\runtime\InvalidSerializedRuntimeDataException;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\utils\SingletonTrait;
|
||||
use pocketmine\world\light\LightUpdate;
|
||||
use function get_class;
|
||||
use function min;
|
||||
|
||||
/**
|
||||
@ -81,6 +82,34 @@ class RuntimeBlockStateRegistry{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates all the possible valid blockstates for a given block type.
|
||||
*
|
||||
* @phpstan-return \Generator<int, Block, void, void>
|
||||
*/
|
||||
private static function generateAllStatesForType(Block $block) : \Generator{
|
||||
//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
|
||||
$bits = $block->getRequiredTypeDataBits() + $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);
|
||||
if($v->computeStateData() !== $stateData){
|
||||
//TODO: this should probably be a hard error
|
||||
throw new InvalidSerializedRuntimeDataException(get_class($block) . "::decodeStateData() accepts invalid state data (returned " . $v->computeStateData() . " for input $stateData)");
|
||||
}
|
||||
}catch(InvalidSerializedRuntimeDataException){ //invalid property combination, leave it
|
||||
continue;
|
||||
}
|
||||
|
||||
yield $v;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a block type to its corresponding type ID. This is necessary for the block to be recognized when loading
|
||||
* from disk, and also when being read at runtime.
|
||||
@ -102,24 +131,7 @@ class RuntimeBlockStateRegistry{
|
||||
|
||||
$this->typeIndex[$typeId] = clone $block;
|
||||
|
||||
//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
|
||||
$bits = $block->getRequiredTypeDataBits() + $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);
|
||||
if($v->computeStateData() !== $stateData){
|
||||
//if the fullID comes back different, this is a broken state that we can't rely on; map it to default
|
||||
throw new InvalidSerializedRuntimeDataException("Corrupted state");
|
||||
}
|
||||
}catch(InvalidSerializedRuntimeDataException $e){ //invalid property combination, leave it
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach(self::generateAllStatesForType($block) as $v){
|
||||
$this->fillStaticArrays($v->getStateId(), $v);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user