PocketMine-MP 5.15.1 git-fb9a74e8799c71ed8292cfa53abe7a4c9204629d
RegistryTrait.php
1<?php
2
3/*
4 *
5 * ____ _ _ __ __ _ __ __ ____
6 * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8 * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9 * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * @author PocketMine Team
17 * @link http://www.pocketmine.net/
18 *
19 *
20 */
21
22declare(strict_types=1);
23
24namespace pocketmine\utils;
25
26use function array_map;
27use function count;
28use function mb_strtoupper;
29use function preg_match;
30
43 private static $members = null;
44
45 private static function verifyName(string $name) : void{
46 if(preg_match('/^(?!\d)[A-Za-z\d_]+$/u', $name) === 0){
47 throw new \InvalidArgumentException("Invalid member name \"$name\", should only contain letters, numbers and underscores, and must not start with a number");
48 }
49 }
50
56 private static function _registryRegister(string $name, object $member) : void{
57 if(self::$members === null){
58 throw new AssumptionFailedError("Cannot register members outside of " . self::class . "::setup()");
59 }
60 self::verifyName($name);
61 $upperName = mb_strtoupper($name);
62 if(isset(self::$members[$upperName])){
63 throw new \InvalidArgumentException("\"$upperName\" is already reserved");
64 }
65 self::$members[$upperName] = $member;
66 }
67
73 abstract protected static function setup() : void;
74
80 protected static function checkInit() : void{
81 if(self::$members === null){
82 self::$members = [];
84 }
85 }
86
90 private static function _registryFromString(string $name) : object{
91 self::checkInit();
92 if(self::$members === null){
93 throw new AssumptionFailedError(self::class . "::checkInit() did not initialize self::\$members correctly");
94 }
95 $upperName = mb_strtoupper($name);
96 if(!isset(self::$members[$upperName])){
97 throw new \InvalidArgumentException("No such registry member: " . self::class . "::" . $upperName);
98 }
99 return self::preprocessMember(self::$members[$upperName]);
100 }
101
102 protected static function preprocessMember(object $member) : object{
103 return $member;
104 }
105
113 public static function __callStatic($name, $arguments){
114 if(count($arguments) > 0){
115 throw new \ArgumentCountError("Expected exactly 0 arguments, " . count($arguments) . " passed");
116 }
117
118 //fast path
119 if(self::$members !== null && isset(self::$members[$name])){
120 return self::preprocessMember(self::$members[$name]);
121 }
122
123 //fallback
124 try{
125 return self::_registryFromString($name);
126 }catch(\InvalidArgumentException $e){
127 throw new \Error($e->getMessage(), 0, $e);
128 }
129 }
130
135 private static function _registryGetAll() : array{
136 self::checkInit();
137 return array_map(self::preprocessMember(...), self::$members ?? throw new AssumptionFailedError(self::class . "::checkInit() did not initialize self::\$members correctly"));
138 }
139}
static __callStatic($name, $arguments)