[EventDispatcher] Revers event tracing order
This commit is contained in:
parent
68b823f243
commit
2570d6f877
@ -29,7 +29,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
protected $logger;
|
protected $logger;
|
||||||
protected $stopwatch;
|
protected $stopwatch;
|
||||||
|
|
||||||
private $called;
|
private $callStack;
|
||||||
private $dispatcher;
|
private $dispatcher;
|
||||||
private $wrappedListeners;
|
private $wrappedListeners;
|
||||||
|
|
||||||
@ -38,7 +38,6 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
$this->dispatcher = $dispatcher;
|
$this->dispatcher = $dispatcher;
|
||||||
$this->stopwatch = $stopwatch;
|
$this->stopwatch = $stopwatch;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->called = array();
|
|
||||||
$this->wrappedListeners = array();
|
$this->wrappedListeners = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,6 +122,10 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
*/
|
*/
|
||||||
public function dispatch($eventName, Event $event = null)
|
public function dispatch($eventName, Event $event = null)
|
||||||
{
|
{
|
||||||
|
if (null === $this->callStack) {
|
||||||
|
$this->callStack = new \SplObjectStorage();
|
||||||
|
}
|
||||||
|
|
||||||
if (null === $event) {
|
if (null === $event) {
|
||||||
$event = new Event();
|
$event = new Event();
|
||||||
}
|
}
|
||||||
@ -158,11 +161,15 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
*/
|
*/
|
||||||
public function getCalledListeners()
|
public function getCalledListeners()
|
||||||
{
|
{
|
||||||
$called = array();
|
if (null === $this->callStack) {
|
||||||
foreach ($this->called as $eventName => $listeners) {
|
return array();
|
||||||
foreach ($listeners as $listener) {
|
|
||||||
$called[$eventName.'.'.$listener->getPretty()] = $listener->getInfo($eventName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$called = array();
|
||||||
|
foreach ($this->callStack as $listener) {
|
||||||
|
list($eventName) = $this->callStack->getInfo();
|
||||||
|
|
||||||
|
$called[] = $listener->getInfo($eventName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $called;
|
return $called;
|
||||||
@ -188,9 +195,9 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
foreach ($allListeners as $eventName => $listeners) {
|
foreach ($allListeners as $eventName => $listeners) {
|
||||||
foreach ($listeners as $listener) {
|
foreach ($listeners as $listener) {
|
||||||
$called = false;
|
$called = false;
|
||||||
if (isset($this->called[$eventName])) {
|
if (null !== $this->callStack) {
|
||||||
foreach ($this->called[$eventName] as $l) {
|
foreach ($this->callStack as $calledListener) {
|
||||||
if ($l->getWrappedListener() === $listener) {
|
if ($calledListener->getWrappedListener() === $listener) {
|
||||||
$called = true;
|
$called = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -202,19 +209,19 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
if (!$listener instanceof WrappedListener) {
|
if (!$listener instanceof WrappedListener) {
|
||||||
$listener = new WrappedListener($listener, null, $this->stopwatch, $this);
|
$listener = new WrappedListener($listener, null, $this->stopwatch, $this);
|
||||||
}
|
}
|
||||||
$notCalled[$eventName.'.'.$listener->getPretty()] = $listener->getInfo($eventName);
|
$notCalled[] = $listener->getInfo($eventName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uasort($notCalled, array($this, 'sortListenersByPriority'));
|
uasort($notCalled, array($this, 'sortNotCalledListeners'));
|
||||||
|
|
||||||
return $notCalled;
|
return $notCalled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function reset()
|
public function reset()
|
||||||
{
|
{
|
||||||
$this->called = array();
|
$this->callStack = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -258,6 +265,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
$this->wrappedListeners[$eventName][] = $wrappedListener;
|
$this->wrappedListeners[$eventName][] = $wrappedListener;
|
||||||
$this->dispatcher->removeListener($eventName, $listener);
|
$this->dispatcher->removeListener($eventName, $listener);
|
||||||
$this->dispatcher->addListener($eventName, $wrappedListener, $priority);
|
$this->dispatcher->addListener($eventName, $wrappedListener, $priority);
|
||||||
|
$this->callStack->attach($wrappedListener, array($eventName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,8 +294,8 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
if (!isset($this->called[$eventName])) {
|
if (!isset($this->called[$eventName])) {
|
||||||
$this->called[$eventName] = new \SplObjectStorage();
|
$this->called[$eventName] = new \SplObjectStorage();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
$this->called[$eventName]->attach($listener);
|
$this->callStack->detach($listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $this->logger && $skipped) {
|
if (null !== $this->logger && $skipped) {
|
||||||
@ -304,8 +312,12 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function sortListenersByPriority($a, $b)
|
private function sortNotCalledListeners(array $a, array $b)
|
||||||
{
|
{
|
||||||
|
if (0 !== $cmp = strcmp($a['event'], $b['event'])) {
|
||||||
|
return $cmp;
|
||||||
|
}
|
||||||
|
|
||||||
if (\is_int($a['priority']) && !\is_int($b['priority'])) {
|
if (\is_int($a['priority']) && !\is_int($b['priority'])) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -110,17 +110,17 @@ class TraceableEventDispatcherTest extends TestCase
|
|||||||
$tdispatcher->addListener('foo', function () {}, 5);
|
$tdispatcher->addListener('foo', function () {}, 5);
|
||||||
|
|
||||||
$listeners = $tdispatcher->getNotCalledListeners();
|
$listeners = $tdispatcher->getNotCalledListeners();
|
||||||
$this->assertArrayHasKey('stub', $listeners['foo.closure']);
|
$this->assertArrayHasKey('stub', $listeners[0]);
|
||||||
unset($listeners['foo.closure']['stub']);
|
unset($listeners[0]['stub']);
|
||||||
$this->assertEquals(array(), $tdispatcher->getCalledListeners());
|
$this->assertEquals(array(), $tdispatcher->getCalledListeners());
|
||||||
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
|
$this->assertEquals(array(array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
|
||||||
|
|
||||||
$tdispatcher->dispatch('foo');
|
$tdispatcher->dispatch('foo');
|
||||||
|
|
||||||
$listeners = $tdispatcher->getCalledListeners();
|
$listeners = $tdispatcher->getCalledListeners();
|
||||||
$this->assertArrayHasKey('stub', $listeners['foo.closure']);
|
$this->assertArrayHasKey('stub', $listeners[0]);
|
||||||
unset($listeners['foo.closure']['stub']);
|
unset($listeners[0]['stub']);
|
||||||
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
|
$this->assertEquals(array(array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
|
||||||
$this->assertEquals(array(), $tdispatcher->getNotCalledListeners());
|
$this->assertEquals(array(), $tdispatcher->getNotCalledListeners());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,10 +133,10 @@ class TraceableEventDispatcherTest extends TestCase
|
|||||||
$tdispatcher->reset();
|
$tdispatcher->reset();
|
||||||
|
|
||||||
$listeners = $tdispatcher->getNotCalledListeners();
|
$listeners = $tdispatcher->getNotCalledListeners();
|
||||||
$this->assertArrayHasKey('stub', $listeners['foo.closure']);
|
$this->assertArrayHasKey('stub', $listeners[0]);
|
||||||
unset($listeners['foo.closure']['stub']);
|
unset($listeners[0]['stub']);
|
||||||
$this->assertEquals(array(), $tdispatcher->getCalledListeners());
|
$this->assertEquals(array(), $tdispatcher->getCalledListeners());
|
||||||
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
|
$this->assertEquals(array(array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetCalledListenersNested()
|
public function testGetCalledListenersNested()
|
||||||
|
Reference in New Issue
Block a user