Skip to content

Commit

Permalink
Merge pull request #102 from wenbinye/fix-event-listeners
Browse files Browse the repository at this point in the history
Remove state property in PrioritizedListenersForEvent
  • Loading branch information
frankdejonge committed Oct 29, 2022
2 parents a9764f4 + 9ef6813 commit ed612ec
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 40 deletions.
54 changes: 14 additions & 40 deletions src/PrioritizedListenersForEvent.php
Expand Up @@ -13,61 +13,35 @@ class PrioritizedListenersForEvent
{
/** @var array<int, array<int,callable>> */
private $listeners = [];
/** @var array<int,callable> */
private $sortedListeners = [];
/** @var bool */
private $isSorted = false;
/** @var bool */
private $containsOneTimeListener = false;
/** @var array<int,callable>|null */
private $sortedListeners;

public function addListener(callable $listener, int $priority): void
{
$this->isSorted = false;
$this->sortedListeners = null;
$this->listeners[$priority][] = $listener;

if ($listener instanceof OneTimeListener) {
$this->containsOneTimeListener = true;
}
}

public function getListeners(): iterable
{
if ($this->isSorted === false) {
$this->sortListeners();
}

$listeners = $this->sortedListeners;

if ($this->containsOneTimeListener) {
$this->removeOneTimeListeners();
}

return $listeners;
return $this->sortedListeners ?? $this->sortListeners();
}

private function sortListeners(): void
private function sortListeners(): array
{
$this->isSorted = true;
$this->sortedListeners = [];
$filter = static function ($listener): bool {
return $listener instanceof OneTimeListener === false;
};
krsort($this->listeners, SORT_NUMERIC);

foreach ($this->listeners as $group) {
$listeners = [];
foreach ($this->listeners as $priority => $group) {
foreach ($group as $listener) {
$this->sortedListeners[] = $listener;
$listeners[] = $listener;
}
$this->listeners[$priority] = array_filter($group, $filter);
}
}

private function removeOneTimeListeners(): void
{
$filter = static function ($listener): bool {
return $listener instanceof OneTimeListener === false;
};

$this->sortedListeners = array_filter($this->sortedListeners, $filter);
$this->sortedListeners = array_filter($listeners, $filter);

foreach ($this->listeners as $priority => $listeners) {
$this->listeners[$priority] = array_filter($listeners, $filter);
}
return $listeners;
}
}
2 changes: 2 additions & 0 deletions src/PrioritizedListenersForEventTest.php
Expand Up @@ -28,6 +28,8 @@ public function testOneTimeListener(): void
$listener2 = $group->getListeners();
$this->assertCount(3, $listener2);
$this->assertEquals([4, 2, 1], self::inspectListener($listener2));
$listener3 = $group->getListeners();
$this->assertEquals([4, 2, 1], self::inspectListener($listener3));
}

public static function inspectListener(iterable $listeners): array
Expand Down

0 comments on commit ed612ec

Please sign in to comment.