diff --git a/src/EventQueue.php b/src/EventQueue.php index 3041d08..32fd8ac 100644 --- a/src/EventQueue.php +++ b/src/EventQueue.php @@ -20,8 +20,15 @@ * @category Phergie * @package Phergie\Irc\Bot\React */ -class EventQueue extends \SplPriorityQueue implements EventQueueInterface +class EventQueue implements EventQueueInterface { + /** + * Internal priority queue. + * + * @var \Phergie\Irc\Bot\React\EventQueueInternal + */ + protected $queue; + /** * Prefix for queued messages * @@ -48,18 +55,31 @@ class EventQueue extends \SplPriorityQueue implements EventQueueInterface */ public function __construct() { - // For HHVM compatibility - // @see https://github.com/facebook/hhvm/issues/1695 - // @see http://stackoverflow.com/a/4650617/906821 - // @codeCoverageIgnoreStart - if (method_exists('\SplPriorityQueue', '__construct')) { - parent::__construct(); - } - // @codeCoverageIgnoreEnd + $this->queue = new EventQueueInternal; $this->priorities = $this->getPriorities(); } + /** + * Allows iteration over the event queue. + * + * @return \Phergie\Irc\Bot\React\EventQueueInternal + */ + public function getIterator() + { + return clone $this->queue; + } + + /** + * Wrapper for the queue's internal count method. + * + * @return int + */ + public function count() + { + return $this->queue->count(); + } + /** * Removes and returns an event from the front of the queue. * @@ -68,10 +88,10 @@ public function __construct() */ public function extract() { - if ($this->isEmpty()) { + if ($this->queue->isEmpty()) { return null; } - return parent::extract(); + return $this->queue->extract(); } /** @@ -115,7 +135,7 @@ protected function queueRequest(UserEventInterface $event, $command, array $para $event->setPrefix($this->prefix); $event->setCommand($command); $event->setParams(array_filter($params)); - $this->insert($event, $this->getPriority($command, $params)); + $this->queue->insert($event, $this->getPriority($command, $params)); } /** @@ -129,23 +149,6 @@ protected function queueIrcRequest($command, array $params = array()) $this->queueRequest(new UserEvent, $command, $params); } - /** - * Overrides native default comparison logic to assign higher priority to - * events inserted earlier. - * - * @param \Phergie\Irc\Bot\React\EventQueuePriority $priority1 - * @param \Phergie\Irc\Bot\React\EventQueuePriority $priority2 - * @return int - */ - public function compare($priority1, $priority2) - { - $priority = $priority1->value - $priority2->value; - if (!$priority) { - $priority = $priority2->timestamp - $priority1->timestamp; - } - return $priority; - } - /** * Enqueues a new CTCP event. * diff --git a/src/EventQueueInterface.php b/src/EventQueueInterface.php index 4ed130b..d13fe9e 100644 --- a/src/EventQueueInterface.php +++ b/src/EventQueueInterface.php @@ -18,7 +18,7 @@ * @category Phergie * @package Phergie\Irc\Bot\React */ -interface EventQueueInterface extends GeneratorInterface, \Iterator, \Countable +interface EventQueueInterface extends GeneratorInterface, \IteratorAggregate, \Countable { /** * Removes and returns an event from the front of the queue. diff --git a/src/EventQueueInternal.php b/src/EventQueueInternal.php new file mode 100644 index 0000000..c7c09cc --- /dev/null +++ b/src/EventQueueInternal.php @@ -0,0 +1,40 @@ +value - $priority2->value; + if (!$priority) { + $priority = $priority2->timestamp - $priority1->timestamp; + } + return $priority; + } +} diff --git a/tests/EventQueueTest.php b/tests/EventQueueTest.php index bcdd21c..8eebc4c 100644 --- a/tests/EventQueueTest.php +++ b/tests/EventQueueTest.php @@ -222,4 +222,25 @@ public function testPriorities() $this->assertNull($this->queue->extract()); } + + /** + * Tests that iterating over the event queue does not truncate its contents. + */ + public function testNonDestructiveIteration() + { + $this->assertNull($this->queue->extract()); + + $this->queue->ircQuit(); + $contents = []; + foreach ($this->queue as $value) { + $contents[] = $value; + } + + $event = $this->queue->extract(); + $this->assertInstanceOf('\Phergie\Irc\Event\EventInterface', $event); + $this->assertEquals('QUIT', $event->getCommand()); + $this->assertEmpty($event->getParams()); + + $this->assertEquals([$event], $contents); + } }