Skip to content

Commit

Permalink
Merge pull request #5 from young-steveo/update-cabinet-events
Browse files Browse the repository at this point in the history
Update cabinet events
  • Loading branch information
young-steveo authored Jun 3, 2023
2 parents 99f73d7 + b928c0c commit 8a38049
Show file tree
Hide file tree
Showing 32 changed files with 420 additions and 154 deletions.
22 changes: 22 additions & 0 deletions src/Cabinet/Event/CabinetEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Arcanum\Cabinet\Event;

interface CabinetEvent
{
/**
* Get the service name.
*
* @return class-string
*/
public function serviceName(): string;

/**
* Get the service.
*
* Will return null if the service is not yet resolved.
*/
public function service(): object|null;
}
35 changes: 35 additions & 0 deletions src/Cabinet/Event/ServiceRequested.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace Arcanum\Cabinet\Event;

final class ServiceRequested extends \Arcanum\Echo\Event implements CabinetEvent
{
/**
* @param class-string $service
*/
public function __construct(private string $service)
{
}

/**
* Get the service name.
*
* @return class-string
*/
public function serviceName(): string
{
return $this->service;
}

/**
* Get the service.
*
* Will return null if the service is not yet resolved.
*/
public function service(): object|null
{
return null;
}
}
22 changes: 17 additions & 5 deletions src/Cabinet/Event/ServiceResolved.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,31 @@

namespace Arcanum\Cabinet\Event;

final class ServiceResolved extends \Arcanum\Echo\Event
final class ServiceResolved extends \Arcanum\Echo\Event implements CabinetEvent
{
/**
* @param mixed $service
* @param object $service
*/
public function __construct(private mixed $service)
public function __construct(private object $service)
{
}

/**
* Get the service that was resolved.
* Get the service name.
*
* @return class-string
*/
public function service(): mixed
public function serviceName(): string
{
return get_class($this->service);
}

/**
* Get the service.
*
* Will return null if the service is not yet resolved.
*/
public function service(): object|null
{
return $this->service;
}
Expand Down
10 changes: 8 additions & 2 deletions src/Cabinet/Resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Resolver
/**
* List of Cabinet\EventDispatcher instances.
*
* @var array<class-string, EventDispatcher>
* @var EventDispatcher[]
*/
protected array $eventDispatchers = [];

Expand Down Expand Up @@ -51,6 +51,12 @@ public function resolve(string|callable $serviceName, bool $isDependency = false
return $this->container->get($serviceName);
}

// notify listeners that a service is requested
foreach ($this->eventDispatchers as $dispatcher) {
$dispatcher->dispatch(new Event\ServiceRequested($serviceName));
}


$image = new \ReflectionClass($serviceName);

// If it is not instantiable, we cannot resolve it.
Expand Down Expand Up @@ -201,7 +207,7 @@ protected function resolveClass(\ReflectionParameter $parameter, string $name):
protected function finalize(object $instance): object
{
if ($instance instanceof EventDispatcher) {
$this->eventDispatchers[get_class($instance)] = $instance;
$this->eventDispatchers[] = $instance;
}

foreach ($this->eventDispatchers as $dispatcher) {
Expand Down
11 changes: 11 additions & 0 deletions src/Echo/Dispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,21 @@ public function dispatch(object $event): object
$event = UnknownEvent::fromObject($event);
}

$duplicates = [];
foreach ($this->provider->getListenersForEvent($event) as $listener) {
if ($event->isPropagationStopped()) {
break;
}

// We don't want to call the same listener twice for a single event.
// this check is needed because the same listener might be registered
// for events that inherit from each other.
if (in_array($listener, $duplicates, true)) {
continue;
}
$duplicates[] = $listener;

// execute the listener
$event = $listener($event);
}

Expand Down
14 changes: 7 additions & 7 deletions src/Echo/Provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ public function listen(string $eventName, callable $listener): void
*/
public function getListenersForEvent(object $event): iterable
{
$eventName = get_class($event);

if (!isset($this->listeners[$eventName])) {
return [];
}

return $this->listeners[$eventName];
$image = new \ReflectionClass($event);
do {
$eventName = $image->getName();
if (isset($this->listeners[$eventName])) {
yield from $this->listeners[$eventName];
}
} while ($image = $image->getParentClass());
}
}
Loading

0 comments on commit 8a38049

Please sign in to comment.