PocketMine-MP 5.37.2 git-e507eb5e50da3ead3ae88ed2324df21e75820019
Loading...
Searching...
No Matches
HandlerList.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\event;
25
27use function array_merge;
28use function krsort;
29use function spl_object_id;
30use const SORT_NUMERIC;
31
40 private array $handlerSlots = [];
41
46 private array $affectedHandlerCaches = [];
47
54 public function __construct(
55 private string $class,
56 private ?HandlerList $parentList,
57 private RegisteredListenerCache $handlerCache = new RegisteredListenerCache()
58 ){
59 for($list = $this; $list !== null; $list = $list->parentList){
60 $list->affectedHandlerCaches[spl_object_id($this->handlerCache)] = $this->handlerCache;
61 }
62 }
63
67 public function register(RegisteredListener $listener) : void{
68 if(isset($this->handlerSlots[$listener->getPriority()][spl_object_id($listener)])){
69 throw new \InvalidArgumentException("This listener is already registered to priority {$listener->getPriority()} of event {$this->class}");
70 }
71 $this->handlerSlots[$listener->getPriority()][spl_object_id($listener)] = $listener;
72 $this->invalidateAffectedCaches();
73 }
74
79 public function registerAll(array $listeners) : void{
80 foreach($listeners as $listener){
81 $this->register($listener);
82 }
83 $this->invalidateAffectedCaches();
84 }
85
89 public function unregister(RegisteredListener|Plugin|Listener $object) : void{
90 if($object instanceof Plugin || $object instanceof Listener){
91 foreach($this->handlerSlots as $priority => $list){
92 foreach($list as $hash => $listener){
93 if(($object instanceof Plugin && $listener->getPlugin() === $object)
94 || ($object instanceof Listener && (new \ReflectionFunction($listener->getHandler()))->getClosureThis() === $object) //this doesn't even need to be a listener :D
95 ){
96 unset($this->handlerSlots[$priority][$hash]);
97 }
98 }
99 }
100 }else{
101 unset($this->handlerSlots[$object->getPriority()][spl_object_id($object)]);
102 }
103 $this->invalidateAffectedCaches();
104 }
105
106 public function clear() : void{
107 $this->handlerSlots = [];
108 $this->invalidateAffectedCaches();
109 }
110
115 public function getListenersByPriority(int $priority) : array{
116 return $this->handlerSlots[$priority] ?? [];
117 }
118
122 public function getParent() : ?HandlerList{
123 return $this->parentList;
124 }
125
129 private function invalidateAffectedCaches() : void{
130 foreach($this->affectedHandlerCaches as $cache){
131 $cache->list = null;
132 }
133 }
134
139 public function getListenerList() : array{
140 if($this->handlerCache->list !== null){
141 return $this->handlerCache->list;
142 }
143
144 $handlerLists = [];
145 for($currentList = $this; $currentList !== null; $currentList = $currentList->parentList){
146 $handlerLists[] = $currentList;
147 }
148
149 $listenersByPriority = [];
150 foreach($handlerLists as $currentList){
151 foreach($currentList->handlerSlots as $priority => $listeners){
152 $listenersByPriority[$priority] = array_merge($listenersByPriority[$priority] ?? [], $listeners);
153 }
154 }
155
156 //TODO: why on earth do the priorities have higher values for lower priority?
157 krsort($listenersByPriority, SORT_NUMERIC);
158
159 return $this->handlerCache->list = array_merge(...$listenersByPriority);
160 }
161}
__construct(private string $class, private ?HandlerList $parentList, private RegisteredListenerCache $handlerCache=new RegisteredListenerCache())
unregister(RegisteredListener|Plugin|Listener $object)
registerAll(array $listeners)
getListenersByPriority(int $priority)