attribute-spass/src/Infrastructure/Event/Dispatcher.php
2023-01-25 22:09:06 +01:00

60 lines
1.5 KiB
PHP

<?php declare(strict_types=1);
namespace Lubian\AttributeMagic\Infrastructure\Event;
use Invoker\InvokerInterface;
use function Lubian\AttributeMagic\Infrastructure\arrayFilter;
use function usort;
final class Dispatcher
{
/**
* @param Listener[] $listeners
*/
public function __construct(
private readonly InvokerInterface $invoker,
private array $listeners = [],
) {
}
public function addListener(Listener $listener): void
{
$this->listeners[] = $listener;
}
/**
* @return Listener[]
*/
public function getListenerForEvent(GenericEvent $event): array
{
return arrayFilter(
$this->listeners,
static fn (Listener $l): bool => $l->eventClass === $event::class,
);
}
/**
* @return Listener[]
*/
public function getSortedListenerForEvent(GenericEvent $event): array
{
$filtered = $this->getListenerForEvent($event);
usort($filtered, static fn (Listener $a, Listener $b): int => $a->priority <=> $b->priority);
return $filtered;
}
public function dispatch(GenericEvent $event): void
{
foreach ($this->getSortedListenerForEvent($event) as $listener) {
if ($event->stopped === true) {
return;
}
$this->invoker->call(
[$listener->listenerClass, $listener->listenerMethod],
[$event],
);
}
}
}