This commit is contained in:
2021-08-03 18:18:09 +08:00
parent 324db2fa3f
commit 5b28c52a10
43 changed files with 755 additions and 653 deletions
+20 -15
View File
@@ -2,31 +2,36 @@
namespace Snowflake\Events;
class EventDispatch
use Annotation\Inject;
use Snowflake\Abstracts\BaseObject;
/**
*
*/
class EventDispatch extends BaseObject
{
private EventListener $eventListener;
#[Inject(EventProvider::class)]
public EventProvider $eventProvider;
/**
* @param $event
* @param array $params
* @param object $triggerEvent
* @return object
*/
public function emit($event, array $params = [])
public function dispatch(object $triggerEvent): object
{
$events = $this->eventListener->getEventListeners($event);
if (empty($events)) {
return;
}
while ($events->valid()) {
/** @var EventDispatchInterface $interface */
$interface = $events->current();
$interface->onHandler();
if ($interface->stopPagination()) {
$lists = $this->eventProvider->getListenersForEvent($triggerEvent);
foreach ($lists as $listener) {
/** @var Struct $list */
$listener($triggerEvent);
if ($triggerEvent instanceof StoppableEventInterface && $triggerEvent->isPropagationStopped()) {
break;
}
$events->next();
}
return $triggerEvent;
}
}
-18
View File
@@ -1,18 +0,0 @@
<?php
namespace Snowflake\Events;
/**
*
*/
interface EventDispatchInterface
{
public function getZOrder(): int;
public function onHandler(): void;
public function stopPagination(): bool;
}
+16
View File
@@ -0,0 +1,16 @@
<?php
namespace Snowflake\Events;
/**
*
*/
interface EventInterface
{
public function process(): void;
}
-37
View File
@@ -1,37 +0,0 @@
<?php
namespace Snowflake\Events;
use SplPriorityQueue;
class EventListener
{
/** @var SplPriorityQueue[] */
private array $_events = [];
/**
* @param $event
* @param EventDispatchInterface $handler
*/
public function on($event, EventDispatchInterface $handler)
{
if (!isset($this->_events[$event])) {
$this->_events[$event] = new SplPriorityQueue();
}
$this->_events[$event]->insert($handler, $handler->getZOrder());
}
/**
* @param $event
* @return SplPriorityQueue|null
*/
public function getEventListeners($event): ?SplPriorityQueue
{
return $this->_events[$event] ?? null;
}
}
+45
View File
@@ -0,0 +1,45 @@
<?php
namespace Snowflake\Events;
/**
*
*/
class EventProvider implements EventProviders
{
/** @var Struct[] */
private array $_listeners = [];
/**
* @param object $event
* @return iterable
*/
public function getListenersForEvent(object $event): iterable
{
$queue = new \SplPriorityQueue();
// TODO: Implement getListenersForEvent() method.
foreach ($this->_listeners as $listener) {
if (!($event instanceof $listener->event)) {
continue;
}
$queue->insert($listener, $listener->priority);
}
return $queue;
}
/**
* @param string $event
* @param callable $handler
* @param int $zOrder
*/
public function on(string $event, callable $handler, int $zOrder = 1)
{
$this->_listeners[$event][] = new Struct($event, $handler, $zOrder);
}
}
+15 -1
View File
@@ -2,7 +2,21 @@
namespace Snowflake\Events;
class EventProviders
/**
*
*/
interface EventProviders
{
/**
* @param object $event
* An event for which to return the relevant listeners.
* @return iterable<callable>
* An iterable (array, iterator, or generator) of callables. Each
* callable MUST be type-compatible with $event.
*/
public function getListenersForEvent(object $event): iterable;
}
+24
View File
@@ -0,0 +1,24 @@
<?php
namespace Snowflake\Events;
/**
*
*/
interface StoppableEventInterface
{
/**
* Is propagation stopped?
*
* This will typically only be used by the Dispatcher to determine if the
* previous listener halted propagation.
*
* @return bool
* True if the Event is complete and no further listeners should be called.
* False to continue calling listeners.
*/
public function isPropagationStopped() : bool;
}
+25
View File
@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace Snowflake\Events;
/**
*
*/
class Struct
{
public string $event;
public \Closure $listener;
public int $priority;
public function __construct(string $event, callable $listener, int $priority)
{
$this->event = $event;
$this->listener = $listener;
$this->priority = $priority;
}
}