From 2570d6f877538b0cb402b250aac21a6969c03a6d Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Sat, 1 Dec 2018 18:19:47 +0100 Subject: [PATCH] [EventDispatcher] Revers event tracing order --- .../Debug/TraceableEventDispatcher.php | 42 ++++++++++++------- .../Debug/TraceableEventDispatcherTest.php | 18 ++++---- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php index 967bb9fba10e..1696f66b6a83 100644 --- a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php @@ -29,7 +29,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface protected $logger; protected $stopwatch; - private $called; + private $callStack; private $dispatcher; private $wrappedListeners; @@ -38,7 +38,6 @@ public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $sto $this->dispatcher = $dispatcher; $this->stopwatch = $stopwatch; $this->logger = $logger; - $this->called = array(); $this->wrappedListeners = array(); } @@ -123,6 +122,10 @@ public function hasListeners($eventName = null) */ public function dispatch($eventName, Event $event = null) { + if (null === $this->callStack) { + $this->callStack = new \SplObjectStorage(); + } + if (null === $event) { $event = new Event(); } @@ -158,11 +161,15 @@ public function dispatch($eventName, Event $event = null) */ public function getCalledListeners() { + if (null === $this->callStack) { + return array(); + } + $called = array(); - foreach ($this->called as $eventName => $listeners) { - foreach ($listeners as $listener) { - $called[$eventName.'.'.$listener->getPretty()] = $listener->getInfo($eventName); - } + foreach ($this->callStack as $listener) { + list($eventName) = $this->callStack->getInfo(); + + $called[] = $listener->getInfo($eventName); } return $called; @@ -188,9 +195,9 @@ public function getNotCalledListeners() foreach ($allListeners as $eventName => $listeners) { foreach ($listeners as $listener) { $called = false; - if (isset($this->called[$eventName])) { - foreach ($this->called[$eventName] as $l) { - if ($l->getWrappedListener() === $listener) { + if (null !== $this->callStack) { + foreach ($this->callStack as $calledListener) { + if ($calledListener->getWrappedListener() === $listener) { $called = true; break; @@ -202,19 +209,19 @@ public function getNotCalledListeners() if (!$listener instanceof WrappedListener) { $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; } public function reset() { - $this->called = array(); + $this->callStack = array(); } /** @@ -258,6 +265,7 @@ private function preProcess($eventName) $this->wrappedListeners[$eventName][] = $wrappedListener; $this->dispatcher->removeListener($eventName, $listener); $this->dispatcher->addListener($eventName, $wrappedListener, $priority); + $this->callStack->attach($wrappedListener, array($eventName)); } } @@ -286,8 +294,8 @@ private function postProcess($eventName) if (!isset($this->called[$eventName])) { $this->called[$eventName] = new \SplObjectStorage(); } - - $this->called[$eventName]->attach($listener); + } else { + $this->callStack->detach($listener); } if (null !== $this->logger && $skipped) { @@ -304,8 +312,12 @@ private function postProcess($eventName) } } - 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'])) { return 1; } diff --git a/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php b/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php index d7c5ce18ccca..a7efcafa9680 100644 --- a/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php +++ b/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php @@ -110,17 +110,17 @@ public function testGetCalledListeners() $tdispatcher->addListener('foo', function () {}, 5); $listeners = $tdispatcher->getNotCalledListeners(); - $this->assertArrayHasKey('stub', $listeners['foo.closure']); - unset($listeners['foo.closure']['stub']); + $this->assertArrayHasKey('stub', $listeners[0]); + unset($listeners[0]['stub']); $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'); $listeners = $tdispatcher->getCalledListeners(); - $this->assertArrayHasKey('stub', $listeners['foo.closure']); - unset($listeners['foo.closure']['stub']); - $this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners); + $this->assertArrayHasKey('stub', $listeners[0]); + unset($listeners[0]['stub']); + $this->assertEquals(array(array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners); $this->assertEquals(array(), $tdispatcher->getNotCalledListeners()); } @@ -133,10 +133,10 @@ public function testClearCalledListeners() $tdispatcher->reset(); $listeners = $tdispatcher->getNotCalledListeners(); - $this->assertArrayHasKey('stub', $listeners['foo.closure']); - unset($listeners['foo.closure']['stub']); + $this->assertArrayHasKey('stub', $listeners[0]); + unset($listeners[0]['stub']); $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()