Event.php
PHP
Path: src/Hooks/Event.php
<?php
namespace mini\Hooks;
use Closure;
/**
* Event dispatcher for events that can trigger multiple times
*
* @template TPayload The primary payload type passed to listeners
* @package mini\Hooks
*/
class Event extends Dispatcher {
/** @var list<callable(TPayload, mixed...): void> */
protected array $listeners = [];
/** @var list<callable(TPayload, mixed...): void> */
protected array $onceListeners = [];
/**
* Invoke all event listeners with the provided arguments
*
* @param TPayload $payload
* @param mixed ...$args Additional arguments
* @throws \Throwable
*/
public function trigger(mixed ...$args): void {
$this->invokeAll($this->listeners, ...$args);
$once = $this->onceListeners;
$this->onceListeners = [];
$this->invokeAll($once, ...$args);
}
/**
* Subscribe to this event
*
* @param callable(TPayload, mixed...): void ...$listeners
*/
public function listen(Closure ...$listeners): void {
foreach ($listeners as $listener) {
$this->listeners[] = $listener;
}
}
/**
* Subscribe and auto-unsubscribe after first trigger
*
* @param callable(TPayload, mixed...): void ...$listeners
*/
public function once(Closure ...$listeners): void {
foreach ($listeners as $listener) {
$this->onceListeners[] = $listener;
}
}
/**
* Unsubscribe from this event
*
* @param callable(TPayload, mixed...): void ...$listeners
*/
public function off(Closure ...$listeners): void {
self::filterArrays(
$listeners,
$this->listeners,
$this->onceListeners,
);
}
}