mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-22 16:51:42 +00:00
Improve enum implementations, move some components to traits
The reason this uses a trait is because `self` refers to the including class in a trait, which offers a small amount of automatic type safety. If we had templates or generics, this would be a generic class instead.
This commit is contained in:
parent
7f4b76aa86
commit
01904adf49
@ -24,147 +24,63 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block\utils;
|
||||
|
||||
use pocketmine\utils\Color;
|
||||
use pocketmine\utils\EnumTrait;
|
||||
|
||||
/**
|
||||
* This doc-block is generated automatically, do not modify it manually.
|
||||
* This must be regenerated whenever enum members are added, removed or changed.
|
||||
* @see EnumTrait::_generateMethodAnnotations()
|
||||
*
|
||||
* @method static self WHITE()
|
||||
* @method static self ORANGE()
|
||||
* @method static self MAGENTA()
|
||||
* @method static self LIGHT_BLUE()
|
||||
* @method static self YELLOW()
|
||||
* @method static self LIME()
|
||||
* @method static self PINK()
|
||||
* @method static self GRAY()
|
||||
* @method static self LIGHT_GRAY()
|
||||
* @method static self CYAN()
|
||||
* @method static self PURPLE()
|
||||
* @method static self BLUE()
|
||||
* @method static self BROWN()
|
||||
* @method static self GREEN()
|
||||
* @method static self RED()
|
||||
* @method static self BLACK()
|
||||
*/
|
||||
final class DyeColor{
|
||||
|
||||
/** @var DyeColor */
|
||||
private static $WHITE;
|
||||
/** @var DyeColor */
|
||||
private static $ORANGE;
|
||||
/** @var DyeColor */
|
||||
private static $MAGENTA;
|
||||
/** @var DyeColor */
|
||||
private static $LIGHT_BLUE;
|
||||
/** @var DyeColor */
|
||||
private static $YELLOW;
|
||||
/** @var DyeColor */
|
||||
private static $LIME;
|
||||
/** @var DyeColor */
|
||||
private static $PINK;
|
||||
/** @var DyeColor */
|
||||
private static $GRAY;
|
||||
/** @var DyeColor */
|
||||
private static $LIGHT_GRAY;
|
||||
/** @var DyeColor */
|
||||
private static $CYAN;
|
||||
/** @var DyeColor */
|
||||
private static $PURPLE;
|
||||
/** @var DyeColor */
|
||||
private static $BLUE;
|
||||
/** @var DyeColor */
|
||||
private static $BROWN;
|
||||
/** @var DyeColor */
|
||||
private static $GREEN;
|
||||
/** @var DyeColor */
|
||||
private static $RED;
|
||||
/** @var DyeColor */
|
||||
private static $BLACK;
|
||||
|
||||
/* auto-generated code */
|
||||
|
||||
public static function WHITE() : DyeColor{
|
||||
return self::$WHITE;
|
||||
}
|
||||
|
||||
public static function ORANGE() : DyeColor{
|
||||
return self::$ORANGE;
|
||||
}
|
||||
|
||||
public static function MAGENTA() : DyeColor{
|
||||
return self::$MAGENTA;
|
||||
}
|
||||
|
||||
public static function LIGHT_BLUE() : DyeColor{
|
||||
return self::$LIGHT_BLUE;
|
||||
}
|
||||
|
||||
public static function YELLOW() : DyeColor{
|
||||
return self::$YELLOW;
|
||||
}
|
||||
|
||||
public static function LIME() : DyeColor{
|
||||
return self::$LIME;
|
||||
}
|
||||
|
||||
public static function PINK() : DyeColor{
|
||||
return self::$PINK;
|
||||
}
|
||||
|
||||
public static function GRAY() : DyeColor{
|
||||
return self::$GRAY;
|
||||
}
|
||||
|
||||
public static function LIGHT_GRAY() : DyeColor{
|
||||
return self::$LIGHT_GRAY;
|
||||
}
|
||||
|
||||
public static function CYAN() : DyeColor{
|
||||
return self::$CYAN;
|
||||
}
|
||||
|
||||
public static function PURPLE() : DyeColor{
|
||||
return self::$PURPLE;
|
||||
}
|
||||
|
||||
public static function BLUE() : DyeColor{
|
||||
return self::$BLUE;
|
||||
}
|
||||
|
||||
public static function BROWN() : DyeColor{
|
||||
return self::$BROWN;
|
||||
}
|
||||
|
||||
public static function GREEN() : DyeColor{
|
||||
return self::$GREEN;
|
||||
}
|
||||
|
||||
public static function RED() : DyeColor{
|
||||
return self::$RED;
|
||||
}
|
||||
|
||||
public static function BLACK() : DyeColor{
|
||||
return self::$BLACK;
|
||||
use EnumTrait {
|
||||
register as Enum_register;
|
||||
__construct as Enum___construct;
|
||||
}
|
||||
|
||||
/** @var DyeColor[] */
|
||||
private static $numericIdMap = [];
|
||||
/** @var DyeColor[] separate mapping that doesn't depend on magic numbers */
|
||||
private static $all = [];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function _init() : void{
|
||||
self::register(self::$WHITE = new DyeColor("White", 0, new Color(0xf0, 0xf0, 0xf0)));
|
||||
self::register(self::$ORANGE = new DyeColor("Orange", 1, new Color(0xf9, 0x80, 0x1d)));
|
||||
self::register(self::$MAGENTA = new DyeColor("Magenta", 2, new Color(0xc7, 0x4e, 0xbd)));
|
||||
self::register(self::$LIGHT_BLUE = new DyeColor("Light Blue", 3, new Color(0x3a, 0xb3, 0xda)));
|
||||
self::register(self::$YELLOW = new DyeColor("Yellow", 4, new Color(0xfe, 0xd8, 0x3d)));
|
||||
self::register(self::$LIME = new DyeColor("Lime", 5, new Color(0x80, 0xc7, 0x1f)));
|
||||
self::register(self::$PINK = new DyeColor("Pink", 6, new Color(0xf3, 0x8b, 0xaa)));
|
||||
self::register(self::$GRAY = new DyeColor("Gray", 7, new Color(0x47, 0x4f, 0x52)));
|
||||
self::register(self::$LIGHT_GRAY = new DyeColor("Light Gray", 8, new Color(0x9d, 0x9d, 0x97)));
|
||||
self::register(self::$CYAN = new DyeColor("Cyan", 9, new Color(0x16, 0x9c, 0x9c)));
|
||||
self::register(self::$PURPLE = new DyeColor("Purple", 10, new Color(0x89, 0x32, 0xb8)));
|
||||
self::register(self::$BLUE = new DyeColor("Blue", 11, new Color(0x3c, 0x44, 0xaa)));
|
||||
self::register(self::$BROWN = new DyeColor("Brown", 12, new Color(0x83, 0x54, 0x32)));
|
||||
self::register(self::$GREEN = new DyeColor("Green", 13, new Color(0x5e, 0x7c, 0x16)));
|
||||
self::register(self::$RED = new DyeColor("Red", 14, new Color(0xb0, 0x2e, 0x26)));
|
||||
self::register(self::$BLACK = new DyeColor("Black", 15, new Color(0x1d, 0x1d, 0x21)));
|
||||
protected static function setup() : array{
|
||||
return [
|
||||
new DyeColor("white", "White", 0, new Color(0xf0, 0xf0, 0xf0)),
|
||||
new DyeColor("orange", "Orange", 1, new Color(0xf9, 0x80, 0x1d)),
|
||||
new DyeColor("magenta", "Magenta", 2, new Color(0xc7, 0x4e, 0xbd)),
|
||||
new DyeColor("light_blue", "Light Blue", 3, new Color(0x3a, 0xb3, 0xda)),
|
||||
new DyeColor("yellow", "Yellow", 4, new Color(0xfe, 0xd8, 0x3d)),
|
||||
new DyeColor("lime", "Lime", 5, new Color(0x80, 0xc7, 0x1f)),
|
||||
new DyeColor("pink", "Pink", 6, new Color(0xf3, 0x8b, 0xaa)),
|
||||
new DyeColor("gray", "Gray", 7, new Color(0x47, 0x4f, 0x52)),
|
||||
new DyeColor("light_gray", "Light Gray", 8, new Color(0x9d, 0x9d, 0x97)),
|
||||
new DyeColor("cyan", "Cyan", 9, new Color(0x16, 0x9c, 0x9c)),
|
||||
new DyeColor("purple", "Purple", 10, new Color(0x89, 0x32, 0xb8)),
|
||||
new DyeColor("blue", "Blue", 11, new Color(0x3c, 0x44, 0xaa)),
|
||||
new DyeColor("brown", "Brown", 12, new Color(0x83, 0x54, 0x32)),
|
||||
new DyeColor("green", "Green", 13, new Color(0x5e, 0x7c, 0x16)),
|
||||
new DyeColor("red", "Red", 14, new Color(0xb0, 0x2e, 0x26)),
|
||||
new DyeColor("black", "Black", 15, new Color(0x1d, 0x1d, 0x21)),
|
||||
];
|
||||
}
|
||||
|
||||
private static function register(DyeColor $color) : void{
|
||||
protected static function register(DyeColor $color) : void{
|
||||
self::Enum_register($color);
|
||||
self::$numericIdMap[$color->getMagicNumber()] = $color;
|
||||
self::$all[] = $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set of all known dye colours.
|
||||
*
|
||||
* @return DyeColor[]
|
||||
*/
|
||||
public static function getAll() : array{
|
||||
return self::$all;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,6 +94,7 @@ final class DyeColor{
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function fromMagicNumber(int $magicNumber, bool $inverted = false) : DyeColor{
|
||||
self::checkInit();
|
||||
$real = $inverted ? ~$magicNumber & 0xf : $magicNumber;
|
||||
if(!isset(self::$numericIdMap[$real])){
|
||||
throw new \InvalidArgumentException("Unknown dye colour magic number $magicNumber");
|
||||
@ -192,7 +109,8 @@ final class DyeColor{
|
||||
/** @var Color */
|
||||
private $rgbValue;
|
||||
|
||||
private function __construct(string $displayName, int $magicNumber, Color $rgbValue){
|
||||
private function __construct(string $enumName, string $displayName, int $magicNumber, Color $rgbValue){
|
||||
$this->Enum___construct($enumName);
|
||||
$this->displayName = $displayName;
|
||||
$this->magicNumber = $magicNumber;
|
||||
$this->rgbValue = $rgbValue;
|
||||
@ -226,4 +144,3 @@ final class DyeColor{
|
||||
return ~$this->magicNumber & 0xf;
|
||||
}
|
||||
}
|
||||
DyeColor::_init();
|
||||
|
@ -23,71 +23,43 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block\utils;
|
||||
|
||||
use pocketmine\utils\EnumTrait;
|
||||
|
||||
/**
|
||||
* This doc-block is generated automatically, do not modify it manually.
|
||||
* This must be regenerated whenever enum members are added, removed or changed.
|
||||
* @see EnumTrait::_generateMethodAnnotations()
|
||||
*
|
||||
* @method static self SKELETON()
|
||||
* @method static self WITHER_SKELETON()
|
||||
* @method static self ZOMBIE()
|
||||
* @method static self PLAYER()
|
||||
* @method static self CREEPER()
|
||||
* @method static self DRAGON()
|
||||
*/
|
||||
final class SkullType{
|
||||
|
||||
/** @var SkullType */
|
||||
private static $SKELETON;
|
||||
/** @var SkullType */
|
||||
private static $WITHER_SKELETON;
|
||||
/** @var SkullType */
|
||||
private static $ZOMBIE;
|
||||
/** @var SkullType */
|
||||
private static $HUMAN;
|
||||
/** @var SkullType */
|
||||
private static $CREEPER;
|
||||
/** @var SkullType */
|
||||
private static $DRAGON;
|
||||
|
||||
/* auto-generated code */
|
||||
|
||||
public static function SKELETON() : SkullType{
|
||||
return self::$SKELETON;
|
||||
use EnumTrait {
|
||||
register as Enum_register;
|
||||
__construct as Enum___construct;
|
||||
}
|
||||
|
||||
public static function WITHER_SKELETON() : SkullType{
|
||||
return self::$WITHER_SKELETON;
|
||||
}
|
||||
|
||||
public static function ZOMBIE() : SkullType{
|
||||
return self::$ZOMBIE;
|
||||
}
|
||||
|
||||
public static function HUMAN() : SkullType{
|
||||
return self::$HUMAN;
|
||||
}
|
||||
|
||||
public static function CREEPER() : SkullType{
|
||||
return self::$CREEPER;
|
||||
}
|
||||
|
||||
public static function DRAGON() : SkullType{
|
||||
return self::$DRAGON;
|
||||
}
|
||||
|
||||
/** @var SkullType[] */
|
||||
private static $all = [];
|
||||
/** @var SkullType[] */
|
||||
private static $numericIdMap = [];
|
||||
|
||||
public static function _init() : void{
|
||||
self::register(self::$SKELETON = new SkullType("Skeleton Skull", 0));
|
||||
self::register(self::$WITHER_SKELETON = new SkullType("Wither Skeleton Skull", 1));
|
||||
self::register(self::$ZOMBIE = new SkullType("Zombie Head", 2));
|
||||
self::register(self::$HUMAN = new SkullType("Player Head", 3));
|
||||
self::register(self::$CREEPER = new SkullType("Creeper Head", 4));
|
||||
self::register(self::$DRAGON = new SkullType("Dragon Head", 5));
|
||||
protected static function setup() : array{
|
||||
return [
|
||||
new SkullType("skeleton", "Skeleton Skull", 0),
|
||||
new SkullType("wither_skeleton", "Wither Skeleton Skull", 1),
|
||||
new SkullType("zombie", "Zombie Head", 2),
|
||||
new SkullType("player", "Player Head", 3),
|
||||
new SkullType("creeper", "Creeper Head", 4),
|
||||
new SkullType("dragon", "Dragon Head", 5)
|
||||
];
|
||||
}
|
||||
|
||||
private static function register(SkullType $type) : void{
|
||||
protected static function register(SkullType $type) : void{
|
||||
self::Enum_register($type);
|
||||
self::$numericIdMap[$type->getMagicNumber()] = $type;
|
||||
self::$all[] = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SkullType[]
|
||||
*/
|
||||
public static function getAll() : array{
|
||||
return self::$all;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,7 +81,8 @@ final class SkullType{
|
||||
/** @var int */
|
||||
private $magicNumber;
|
||||
|
||||
public function __construct(string $displayName, int $magicNumber){
|
||||
public function __construct(string $enumName, string $displayName, int $magicNumber){
|
||||
$this->Enum___construct($enumName);
|
||||
$this->displayName = $displayName;
|
||||
$this->magicNumber = $magicNumber;
|
||||
}
|
||||
@ -128,4 +101,3 @@ final class SkullType{
|
||||
return $this->magicNumber;
|
||||
}
|
||||
}
|
||||
SkullType::_init();
|
||||
|
@ -23,36 +23,25 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block\utils;
|
||||
|
||||
use pocketmine\utils\EnumTrait;
|
||||
|
||||
/**
|
||||
* This doc-block is generated automatically, do not modify it manually.
|
||||
* This must be regenerated whenever enum members are added, removed or changed.
|
||||
* @see EnumTrait::_generateMethodAnnotations()
|
||||
*
|
||||
* @method static self BOTTOM()
|
||||
* @method static self TOP()
|
||||
* @method static self DOUBLE()
|
||||
*/
|
||||
final class SlabType{
|
||||
use EnumTrait;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
public static function BOTTOM() : self{
|
||||
/** @var SlabType $ret */
|
||||
static $ret = null;
|
||||
return $ret ?? ($ret = new self("bottom"));
|
||||
}
|
||||
|
||||
public static function TOP() : self{
|
||||
/** @var SlabType $ret */
|
||||
static $ret = null;
|
||||
return $ret ?? ($ret = new self("top"));
|
||||
}
|
||||
|
||||
public static function DOUBLE() : self{
|
||||
/** @var SlabType $ret */
|
||||
static $ret = null;
|
||||
return $ret ?? ($ret = new self("double"));
|
||||
}
|
||||
|
||||
private function __construct(string $name){
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return $this->name;
|
||||
protected static function setup() : array{
|
||||
return [
|
||||
new self("bottom"),
|
||||
new self("top"),
|
||||
new self("double")
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -23,74 +23,43 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block\utils;
|
||||
|
||||
use pocketmine\utils\EnumTrait;
|
||||
|
||||
/**
|
||||
* This doc-block is generated automatically, do not modify it manually.
|
||||
* This must be regenerated whenever enum members are added, removed or changed.
|
||||
* @see EnumTrait::_generateMethodAnnotations()
|
||||
*
|
||||
* @method static self OAK()
|
||||
* @method static self SPRUCE()
|
||||
* @method static self BIRCH()
|
||||
* @method static self JUNGLE()
|
||||
* @method static self ACACIA()
|
||||
* @method static self DARK_OAK()
|
||||
*/
|
||||
final class TreeType{
|
||||
|
||||
/** @var TreeType */
|
||||
private static $OAK;
|
||||
/** @var TreeType */
|
||||
private static $SPRUCE;
|
||||
/** @var TreeType */
|
||||
private static $BIRCH;
|
||||
/** @var TreeType */
|
||||
private static $JUNGLE;
|
||||
/** @var TreeType */
|
||||
private static $ACACIA;
|
||||
/** @var TreeType */
|
||||
private static $DARK_OAK;
|
||||
|
||||
/* auto-generated code */
|
||||
|
||||
public static function OAK() : TreeType{
|
||||
return self::$OAK;
|
||||
}
|
||||
|
||||
public static function SPRUCE() : TreeType{
|
||||
return self::$SPRUCE;
|
||||
}
|
||||
|
||||
public static function BIRCH() : TreeType{
|
||||
return self::$BIRCH;
|
||||
}
|
||||
|
||||
public static function JUNGLE() : TreeType{
|
||||
return self::$JUNGLE;
|
||||
}
|
||||
|
||||
public static function ACACIA() : TreeType{
|
||||
return self::$ACACIA;
|
||||
}
|
||||
|
||||
public static function DARK_OAK() : TreeType{
|
||||
return self::$DARK_OAK;
|
||||
use EnumTrait {
|
||||
register as Enum_register;
|
||||
__construct as Enum___construct;
|
||||
}
|
||||
|
||||
/** @var TreeType[] */
|
||||
private static $numericIdMap = [];
|
||||
/** @var TreeType[] */
|
||||
private static $all = [];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function _init() : void{
|
||||
self::register(self::$OAK = new TreeType("Oak", 0));
|
||||
self::register(self::$SPRUCE = new TreeType("Spruce", 1));
|
||||
self::register(self::$BIRCH = new TreeType("Birch", 2));
|
||||
self::register(self::$JUNGLE = new TreeType("Jungle", 3));
|
||||
self::register(self::$ACACIA = new TreeType("Acacia", 4));
|
||||
self::register(self::$DARK_OAK = new TreeType("Dark Oak", 5));
|
||||
protected static function setup() : array{
|
||||
return [
|
||||
new TreeType("oak", "Oak", 0),
|
||||
new TreeType("spruce", "Spruce", 1),
|
||||
new TreeType("birch", "Birch", 2),
|
||||
new TreeType("jungle", "Jungle", 3),
|
||||
new TreeType("acacia", "Acacia", 4),
|
||||
new TreeType("dark_oak","Dark Oak", 5)
|
||||
];
|
||||
}
|
||||
|
||||
private static function register(TreeType $type) : void{
|
||||
protected static function register(TreeType $type) : void{
|
||||
self::Enum_register($type);
|
||||
self::$numericIdMap[$type->getMagicNumber()] = $type;
|
||||
self::$all[] = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TreeType[]
|
||||
*/
|
||||
public static function getAll() : array{
|
||||
return self::$all;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,6 +70,7 @@ final class TreeType{
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function fromMagicNumber(int $magicNumber) : TreeType{
|
||||
self::checkInit();
|
||||
if(!isset(self::$numericIdMap[$magicNumber])){
|
||||
throw new \InvalidArgumentException("Unknown tree type magic number $magicNumber");
|
||||
}
|
||||
@ -113,10 +83,12 @@ final class TreeType{
|
||||
private $magicNumber;
|
||||
|
||||
/**
|
||||
* @param string $enumName
|
||||
* @param string $displayName
|
||||
* @param int $magicNumber
|
||||
*/
|
||||
private function __construct(string $displayName, int $magicNumber){
|
||||
private function __construct(string $enumName, string $displayName, int $magicNumber){
|
||||
$this->Enum___construct($enumName);
|
||||
$this->displayName = $displayName;
|
||||
$this->magicNumber = $magicNumber;
|
||||
}
|
||||
@ -135,4 +107,3 @@ final class TreeType{
|
||||
return $this->magicNumber;
|
||||
}
|
||||
}
|
||||
TreeType::_init();
|
||||
|
@ -23,43 +23,25 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\utils\EnumTrait;
|
||||
|
||||
/**
|
||||
* This doc-block is generated automatically, do not modify it manually.
|
||||
* This must be regenerated whenever enum members are added, removed or changed.
|
||||
* @see EnumTrait::_generateMethodAnnotations()
|
||||
*
|
||||
* @method static self NONE()
|
||||
* @method static self FAIL()
|
||||
* @method static self SUCCESS()
|
||||
*/
|
||||
final class ItemUseResult{
|
||||
/** @var ItemUseResult */
|
||||
private static $NONE;
|
||||
/** @var ItemUseResult */
|
||||
private static $FAILED;
|
||||
/** @var ItemUseResult */
|
||||
private static $SUCCEEDED;
|
||||
use EnumTrait;
|
||||
|
||||
/**
|
||||
* No action attempted to take place. Does nothing.
|
||||
*
|
||||
* @return ItemUseResult
|
||||
*/
|
||||
public static function NONE() : ItemUseResult{
|
||||
return self::$NONE ?? (self::$NONE = new self());
|
||||
}
|
||||
|
||||
/**
|
||||
* An action attempted to take place, but failed due to cancellation. This triggers rollback behaviour for a remote
|
||||
* player.
|
||||
*
|
||||
* @return ItemUseResult
|
||||
*/
|
||||
public static function FAIL() : ItemUseResult{
|
||||
return self::$FAILED ?? (self::$FAILED = new self());
|
||||
}
|
||||
|
||||
/**
|
||||
* An action took place successfully. Changes inventory contents if appropriate.
|
||||
*
|
||||
* @return ItemUseResult
|
||||
*/
|
||||
public static function SUCCESS() : ItemUseResult{
|
||||
return self::$SUCCEEDED ?? (self::$SUCCEEDED = new self());
|
||||
}
|
||||
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
protected static function setup() : array{
|
||||
return [
|
||||
new self("none"),
|
||||
new self("fail"),
|
||||
new self("success")
|
||||
];
|
||||
}
|
||||
}
|
||||
|
172
src/pocketmine/utils/EnumTrait.php
Normal file
172
src/pocketmine/utils/EnumTrait.php
Normal file
@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\utils;
|
||||
|
||||
use function count;
|
||||
use function implode;
|
||||
use function preg_match;
|
||||
use function sprintf;
|
||||
use function strtoupper;
|
||||
|
||||
trait EnumTrait{
|
||||
|
||||
/** @var self[] */
|
||||
private static $members = null;
|
||||
|
||||
/**
|
||||
* Registers the given object as an enum member.
|
||||
*
|
||||
* @param self $member
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected static function register(self $member) : void{
|
||||
$name = strtoupper($member->getEnumName());
|
||||
if(isset(self::$members[$name])){
|
||||
throw new \InvalidArgumentException("Enum member name \"$name\" is already reserved");
|
||||
}
|
||||
self::$members[strtoupper($member->getEnumName())] = $member;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of enum members to be registered.
|
||||
*
|
||||
* (This ought to be private, but traits suck too much for that.)
|
||||
*
|
||||
* @return self[]
|
||||
*/
|
||||
abstract protected static function setup() : array;
|
||||
|
||||
/**
|
||||
* @internal Lazy-inits the enum if necessary.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
private static function checkInit() : void{
|
||||
if(self::$members === null){
|
||||
self::$members = [];
|
||||
foreach(self::setup() as $item){
|
||||
self::register($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function fromString(string $name) : self{
|
||||
self::checkInit();
|
||||
$name = strtoupper($name);
|
||||
if(!isset(self::$members[$name])){
|
||||
throw new \Error("Undefined enum member: " . self::class . "::" . $name);
|
||||
}
|
||||
return self::$members[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function __callStatic($name, $arguments){
|
||||
if(!empty($arguments)){
|
||||
throw new \ArgumentCountError("Expected exactly 0 arguments, " . count($arguments) . " passed");
|
||||
}
|
||||
return self::fromString($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return self[]
|
||||
*/
|
||||
public static function getAll() : array{
|
||||
self::checkInit();
|
||||
return self::$members;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates code for static methods for all known enum members.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function _generateGetters() : string{
|
||||
$lines = [];
|
||||
|
||||
static $fnTmpl = '
|
||||
public static function %1$s() : self{
|
||||
return self::fromString("%1$s");
|
||||
}';
|
||||
|
||||
foreach(self::getAll() as $name => $member){
|
||||
$lines[] = sprintf($fnTmpl, $name);
|
||||
}
|
||||
return "/* --- auto-generated code start --- */\n" . implode("\n", $lines) . "\n\n/* --- auto-generated code end --- */\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a block of @ method annotations for accessors for this enum's known members.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function _generateMethodAnnotations() : string{
|
||||
$traitName = (new \ReflectionClass(__TRAIT__))->getShortName();
|
||||
$fnName = (new \ReflectionMethod(__METHOD__))->getShortName();
|
||||
$lines = ["/**"];
|
||||
$lines[] = " * This doc-block is generated automatically, do not modify it manually.";
|
||||
$lines[] = " * This must be regenerated whenever enum members are added, removed or changed.";
|
||||
$lines[] = " * @see $traitName::$fnName()";
|
||||
$lines[] = " *";
|
||||
static $lineTmpl = " * @method static self %s()";
|
||||
|
||||
foreach(self::getAll() as $name => $member){
|
||||
$lines[] = sprintf($lineTmpl, $name);
|
||||
}
|
||||
$lines[] = " */\n";
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/** @var string */
|
||||
private $enumName;
|
||||
|
||||
/**
|
||||
* @param string $enumName
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
private function __construct(string $enumName){
|
||||
static $pattern = '/^\D[A-Za-z\d_]+$/u';
|
||||
if(preg_match($pattern, $enumName, $matches) === 0){
|
||||
throw new \InvalidArgumentException("Invalid enum member name \"$enumName\", should only contain letters, numbers and underscores, and must not start with a number");
|
||||
}
|
||||
$this->enumName = $enumName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEnumName() : string{
|
||||
return $this->enumName;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user