From b56f1b679ea49aab81222e08a7d36f97d95a895e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 25 Aug 2023 12:30:54 +0100 Subject: [PATCH] Deduplicate a bunch of repeated type ID map code --- build/php | 2 +- src/data/bedrock/DyeColorIdMap.php | 27 ++----- src/data/bedrock/EffectIdMap.php | 34 +------- src/data/bedrock/EnchantmentIdMap.php | 31 +------- src/data/bedrock/IntSaveIdMapTrait.php | 82 ++++++++++++++++++++ src/data/bedrock/MedicineTypeIdMap.php | 30 +------ src/data/bedrock/MobHeadTypeIdMap.php | 30 +------ src/data/bedrock/MushroomBlockTypeIdMap.php | 29 +------ src/data/bedrock/NoteInstrumentIdMap.php | 30 +------ src/data/bedrock/PotionTypeIdMap.php | 30 +------ src/data/bedrock/SuspiciousStewTypeIdMap.php | 30 +------ 11 files changed, 104 insertions(+), 251 deletions(-) create mode 100644 src/data/bedrock/IntSaveIdMapTrait.php diff --git a/build/php b/build/php index a053f65e1..9f984a1dc 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit a053f65e1897e432478229071383fe1ba16032c3 +Subproject commit 9f984a1dc154603a27543ecdcebc6d6a5871f425 diff --git a/src/data/bedrock/DyeColorIdMap.php b/src/data/bedrock/DyeColorIdMap.php index 35db72c3e..0d10edad5 100644 --- a/src/data/bedrock/DyeColorIdMap.php +++ b/src/data/bedrock/DyeColorIdMap.php @@ -29,18 +29,10 @@ use pocketmine\utils\SingletonTrait; final class DyeColorIdMap{ use SingletonTrait; - - /** - * @var DyeColor[] - * @phpstan-var array - */ - private array $idToEnum = []; - - /** - * @var int[] - * @phpstan-var array - */ - private array $enumToId = []; + /** @phpstan-use IntSaveIdMapTrait */ + use IntSaveIdMapTrait { + register as registerInt; + } /** * @var DyeColor[] @@ -74,16 +66,11 @@ final class DyeColorIdMap{ } private function register(int $id, string $itemId, DyeColor $color) : void{ - $this->idToEnum[$id] = $color; - $this->enumToId[$color->id()] = $id; + $this->registerInt($id, $color); $this->itemIdToEnum[$itemId] = $color; $this->enumToItemId[$color->id()] = $itemId; } - public function toId(DyeColor $color) : int{ - return $this->enumToId[$color->id()]; //TODO: is it possible for this to be missing? - } - public function toInvertedId(DyeColor $color) : int{ return ~$this->toId($color) & 0xf; } @@ -92,10 +79,6 @@ final class DyeColorIdMap{ return $this->enumToItemId[$color->id()]; } - public function fromId(int $id) : ?DyeColor{ - return $this->idToEnum[$id] ?? null; - } - public function fromInvertedId(int $id) : ?DyeColor{ return $this->fromId(~$id & 0xf); } diff --git a/src/data/bedrock/EffectIdMap.php b/src/data/bedrock/EffectIdMap.php index 6dce86d9b..6efa10b41 100644 --- a/src/data/bedrock/EffectIdMap.php +++ b/src/data/bedrock/EffectIdMap.php @@ -31,18 +31,8 @@ use function spl_object_id; final class EffectIdMap{ use SingletonTrait; - - /** - * @var Effect[] - * @phpstan-var array - */ - private array $idToEffect = []; - - /** - * @var int[] - * @phpstan-var array - */ - private array $effectToId = []; + /** @phpstan-use IntSaveIdMapTrait */ + use IntSaveIdMapTrait; private function __construct(){ $this->register(EffectIds::SPEED, VanillaEffects::SPEED()); @@ -76,24 +66,4 @@ final class EffectIdMap{ //TODO: VILLAGE_HERO $this->register(EffectIds::DARKNESS, VanillaEffects::DARKNESS()); } - - //TODO: not a big fan of the code duplication here :( - - public function register(int $mcpeId, Effect $effect) : void{ - $this->idToEffect[$mcpeId] = $effect; - $this->effectToId[spl_object_id($effect)] = $mcpeId; - } - - public function fromId(int $id) : ?Effect{ - //we might not have all the effect IDs registered - return $this->idToEffect[$id] ?? null; - } - - public function toId(Effect $effect) : int{ - if(!array_key_exists(spl_object_id($effect), $this->effectToId)){ - //this should never happen, so we treat it as an exceptional condition - throw new \InvalidArgumentException("Effect does not have a mapped ID"); - } - return $this->effectToId[spl_object_id($effect)]; - } } diff --git a/src/data/bedrock/EnchantmentIdMap.php b/src/data/bedrock/EnchantmentIdMap.php index 1d974ed6e..c06080e3e 100644 --- a/src/data/bedrock/EnchantmentIdMap.php +++ b/src/data/bedrock/EnchantmentIdMap.php @@ -34,17 +34,8 @@ use function spl_object_id; */ final class EnchantmentIdMap{ use SingletonTrait; - - /** - * @var Enchantment[] - * @phpstan-var array - */ - private array $idToEnch = []; - /** - * @var int[] - * @phpstan-var array - */ - private array $enchToId = []; + /** @phpstan-use IntSaveIdMapTrait */ + use IntSaveIdMapTrait; private function __construct(){ $this->register(EnchantmentIds::PROTECTION, VanillaEnchantments::PROTECTION()); @@ -77,22 +68,4 @@ final class EnchantmentIdMap{ $this->register(EnchantmentIds::SWIFT_SNEAK, VanillaEnchantments::SWIFT_SNEAK()); } - - public function register(int $mcpeId, Enchantment $enchantment) : void{ - $this->idToEnch[$mcpeId] = $enchantment; - $this->enchToId[spl_object_id($enchantment)] = $mcpeId; - } - - public function fromId(int $id) : ?Enchantment{ - //we might not have all the enchantment IDs registered - return $this->idToEnch[$id] ?? null; - } - - public function toId(Enchantment $enchantment) : int{ - if(!array_key_exists(spl_object_id($enchantment), $this->enchToId)){ - //this should never happen, so we treat it as an exceptional condition - throw new \InvalidArgumentException("Enchantment does not have a mapped ID"); - } - return $this->enchToId[spl_object_id($enchantment)]; - } } diff --git a/src/data/bedrock/IntSaveIdMapTrait.php b/src/data/bedrock/IntSaveIdMapTrait.php new file mode 100644 index 000000000..041dfa9e6 --- /dev/null +++ b/src/data/bedrock/IntSaveIdMapTrait.php @@ -0,0 +1,82 @@ + + */ + private array $idToEnum = []; + + /** + * @var int[] + * @phpstan-var array + */ + private array $enumToId = []; + + /** + * @phpstan-param TObject $enum + */ + protected function getRuntimeId(object $enum) : int{ + //this is fine for enums and non-cloning object registries + return spl_object_id($enum); + } + + /** + * @phpstan-param TObject $enum + */ + public function register(int $saveId, object $enum) : void{ + $this->idToEnum[$saveId] = $enum; + $this->enumToId[$this->getRuntimeId($enum)] = $saveId; + } + + /** + * @phpstan-return TObject|null + */ + public function fromId(int $id) : ?object{ + //we might not have all the effect IDs registered + return $this->idToEnum[$id] ?? null; + } + + /** + * @phpstan-param TObject $enum + */ + public function toId(object $enum) : int{ + $runtimeId = $this->getRuntimeId($enum); + if(!array_key_exists($runtimeId, $this->enumToId)){ + //this should never happen, so we treat it as an exceptional condition + throw new \InvalidArgumentException("Object does not have a mapped save ID"); + } + return $this->enumToId[$runtimeId]; + } +} diff --git a/src/data/bedrock/MedicineTypeIdMap.php b/src/data/bedrock/MedicineTypeIdMap.php index a85dbb7a8..2d9deb380 100644 --- a/src/data/bedrock/MedicineTypeIdMap.php +++ b/src/data/bedrock/MedicineTypeIdMap.php @@ -28,18 +28,8 @@ use pocketmine\utils\SingletonTrait; final class MedicineTypeIdMap{ use SingletonTrait; - - /** - * @var MedicineType[] - * @phpstan-var array - */ - private array $idToEnum = []; - - /** - * @var int[] - * @phpstan-var array - */ - private array $enumToId = []; + /** @phpstan-use IntSaveIdMapTrait */ + use IntSaveIdMapTrait; private function __construct(){ $this->register(MedicineTypeIds::ANTIDOTE, MedicineType::ANTIDOTE()); @@ -47,20 +37,4 @@ final class MedicineTypeIdMap{ $this->register(MedicineTypeIds::EYE_DROPS, MedicineType::EYE_DROPS()); $this->register(MedicineTypeIds::TONIC, MedicineType::TONIC()); } - - private function register(int $id, MedicineType $type) : void{ - $this->idToEnum[$id] = $type; - $this->enumToId[$type->id()] = $id; - } - - public function fromId(int $id) : ?MedicineType{ - return $this->idToEnum[$id] ?? null; - } - - public function toId(MedicineType $type) : int{ - if(!isset($this->enumToId[$type->id()])){ - throw new \InvalidArgumentException("Type does not have a mapped ID"); - } - return $this->enumToId[$type->id()]; - } } diff --git a/src/data/bedrock/MobHeadTypeIdMap.php b/src/data/bedrock/MobHeadTypeIdMap.php index 99213fa46..b99b1097b 100644 --- a/src/data/bedrock/MobHeadTypeIdMap.php +++ b/src/data/bedrock/MobHeadTypeIdMap.php @@ -28,18 +28,8 @@ use pocketmine\utils\SingletonTrait; final class MobHeadTypeIdMap{ use SingletonTrait; - - /** - * @var MobHeadType[] - * @phpstan-var array - */ - private array $idToEnum = []; - - /** - * @var int[] - * @phpstan-var array - */ - private array $enumToId = []; + /** @phpstan-use IntSaveIdMapTrait */ + use IntSaveIdMapTrait; private function __construct(){ $this->register(0, MobHeadType::SKELETON()); @@ -50,20 +40,4 @@ final class MobHeadTypeIdMap{ $this->register(5, MobHeadType::DRAGON()); $this->register(6, MobHeadType::PIGLIN()); } - - private function register(int $id, MobHeadType $type) : void{ - $this->idToEnum[$id] = $type; - $this->enumToId[$type->id()] = $id; - } - - public function fromId(int $id) : ?MobHeadType{ - return $this->idToEnum[$id] ?? null; - } - - public function toId(MobHeadType $type) : int{ - if(!isset($this->enumToId[$type->id()])){ - throw new \InvalidArgumentException("Type does not have a mapped ID"); - } - return $this->enumToId[$type->id()]; - } } diff --git a/src/data/bedrock/MushroomBlockTypeIdMap.php b/src/data/bedrock/MushroomBlockTypeIdMap.php index 2eec17549..5e195ebb2 100644 --- a/src/data/bedrock/MushroomBlockTypeIdMap.php +++ b/src/data/bedrock/MushroomBlockTypeIdMap.php @@ -30,17 +30,8 @@ use function array_key_exists; final class MushroomBlockTypeIdMap{ use SingletonTrait; - - /** - * @var MushroomBlockType[] - * @phpstan-var array - */ - private array $idToEnum = []; - /** - * @var int[] - * @phpstan-var array - */ - private array $enumToId = []; + /** @phpstan-use IntSaveIdMapTrait */ + use IntSaveIdMapTrait; public function __construct(){ $this->register(LegacyMeta::MUSHROOM_BLOCK_ALL_PORES, MushroomBlockType::PORES()); @@ -55,20 +46,4 @@ final class MushroomBlockTypeIdMap{ $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTHEAST_CORNER, MushroomBlockType::CAP_SOUTHEAST()); $this->register(LegacyMeta::MUSHROOM_BLOCK_ALL_CAP, MushroomBlockType::ALL_CAP()); } - - public function register(int $id, MushroomBlockType $type) : void{ - $this->idToEnum[$id] = $type; - $this->enumToId[$type->id()] = $id; - } - - public function fromId(int $id) : ?MushroomBlockType{ - return $this->idToEnum[$id] ?? null; - } - - public function toId(MushroomBlockType $type) : int{ - if(!array_key_exists($type->id(), $this->enumToId)){ - throw new \InvalidArgumentException("Mushroom block type does not have a mapped ID"); //this should never happen - } - return $this->enumToId[$type->id()]; - } } diff --git a/src/data/bedrock/NoteInstrumentIdMap.php b/src/data/bedrock/NoteInstrumentIdMap.php index 0b8a43735..22d7e5cb1 100644 --- a/src/data/bedrock/NoteInstrumentIdMap.php +++ b/src/data/bedrock/NoteInstrumentIdMap.php @@ -28,18 +28,8 @@ use pocketmine\world\sound\NoteInstrument; final class NoteInstrumentIdMap{ use SingletonTrait; - - /** - * @var NoteInstrument[] - * @phpstan-var array - */ - private array $idToEnum = []; - - /** - * @var int[] - * @phpstan-var array - */ - private array $enumToId = []; + /** @phpstan-use IntSaveIdMapTrait */ + use IntSaveIdMapTrait; private function __construct(){ $this->register(0, NoteInstrument::PIANO()); @@ -59,20 +49,4 @@ final class NoteInstrumentIdMap{ $this->register(14, NoteInstrument::BANJO()); $this->register(15, NoteInstrument::PLING()); } - - private function register(int $id, NoteInstrument $instrument) : void{ - $this->idToEnum[$id] = $instrument; - $this->enumToId[$instrument->id()] = $id; - } - - public function fromId(int $id) : ?NoteInstrument{ - return $this->idToEnum[$id] ?? null; - } - - public function toId(NoteInstrument $instrument) : int{ - if(!isset($this->enumToId[$instrument->id()])){ - throw new \InvalidArgumentException("Type does not have a mapped ID"); - } - return $this->enumToId[$instrument->id()]; - } } diff --git a/src/data/bedrock/PotionTypeIdMap.php b/src/data/bedrock/PotionTypeIdMap.php index 8194f24a2..3e9858217 100644 --- a/src/data/bedrock/PotionTypeIdMap.php +++ b/src/data/bedrock/PotionTypeIdMap.php @@ -28,18 +28,8 @@ use pocketmine\utils\SingletonTrait; final class PotionTypeIdMap{ use SingletonTrait; - - /** - * @var PotionType[] - * @phpstan-var array - */ - private array $idToEnum = []; - - /** - * @var int[] - * @phpstan-var array - */ - private array $enumToId = []; + /** @phpstan-use IntSaveIdMapTrait */ + use IntSaveIdMapTrait; private function __construct(){ $this->register(PotionTypeIds::WATER, PotionType::WATER()); @@ -86,20 +76,4 @@ final class PotionTypeIdMap{ $this->register(PotionTypeIds::LONG_SLOW_FALLING, PotionType::LONG_SLOW_FALLING()); $this->register(PotionTypeIds::STRONG_SLOWNESS, PotionType::STRONG_SLOWNESS()); } - - private function register(int $id, PotionType $type) : void{ - $this->idToEnum[$id] = $type; - $this->enumToId[$type->id()] = $id; - } - - public function fromId(int $id) : ?PotionType{ - return $this->idToEnum[$id] ?? null; - } - - public function toId(PotionType $type) : int{ - if(!isset($this->enumToId[$type->id()])){ - throw new \InvalidArgumentException("Type does not have a mapped ID"); - } - return $this->enumToId[$type->id()]; - } } diff --git a/src/data/bedrock/SuspiciousStewTypeIdMap.php b/src/data/bedrock/SuspiciousStewTypeIdMap.php index 1dc86abf1..37d121517 100644 --- a/src/data/bedrock/SuspiciousStewTypeIdMap.php +++ b/src/data/bedrock/SuspiciousStewTypeIdMap.php @@ -28,18 +28,8 @@ use pocketmine\utils\SingletonTrait; final class SuspiciousStewTypeIdMap{ use SingletonTrait; - - /** - * @var SuspiciousStewType[] - * @phpstan-var array - */ - private array $idToEnum = []; - - /** - * @var int[] - * @phpstan-var array - */ - private array $enumToId = []; + /** @phpstan-use IntSaveIdMapTrait */ + use IntSaveIdMapTrait; private function __construct(){ $this->register(SuspiciousStewTypeIds::POPPY, SuspiciousStewType::POPPY()); @@ -53,20 +43,4 @@ final class SuspiciousStewTypeIdMap{ $this->register(SuspiciousStewTypeIds::OXEYE_DAISY, SuspiciousStewType::OXEYE_DAISY()); $this->register(SuspiciousStewTypeIds::WITHER_ROSE, SuspiciousStewType::WITHER_ROSE()); } - - private function register(int $id, SuspiciousStewType $type) : void{ - $this->idToEnum[$id] = $type; - $this->enumToId[$type->id()] = $id; - } - - public function fromId(int $id) : ?SuspiciousStewType{ - return $this->idToEnum[$id] ?? null; - } - - public function toId(SuspiciousStewType $type) : int{ - if(!isset($this->enumToId[$type->id()])){ - throw new \InvalidArgumentException("Type does not have a mapped ID"); - } - return $this->enumToId[$type->id()]; - } }