Browse files

Add mechanism to halt the event queue early.

This allows the event queue to be halted before the callback declared at
the time off triggering an event can actually be executed.
  • Loading branch information...
1 parent d697a37 commit d0f6ba9874c15b60fc7858b394e28dded0e35454 @trq trq committed Nov 1, 2012
View
25 lib/Proem/Signal/Event/Standard.php
@@ -45,6 +45,13 @@ class Standard implements Template
protected $haltedQueue = false;
/**
+ * Halt the queue *early* flag.
+ *
+ * @var bool
+ */
+ protected $haltedQueueEarly = false;
+
+ /**
* Store params
*
* @var array
@@ -68,15 +75,29 @@ public function __construct($name)
/**
* Set the halt queue flag to true
+ *
+ * @param bool $early If true, the queue will be halted prior to the triggers callback being executed
*/
- public function haltQueue()
+ public function haltQueue($early = false)
{
+ if ($early) {
+ $this->haltedQueueEarly = true;
+ }
+
$this->haltedQueue = true;
return $this;
}
/**
- * Check to see if the haltQueue flag is true
+ * Check to see if the haltedQueueEarly flag is true
+ */
+ public function isQueueHaltedEarly()
+ {
+ return $this->haltedQueueEarly;
+ }
+
+ /**
+ * Check to see if the haltedQueue flag is true
*/
public function isQueueHalted()
{
View
11 lib/Proem/Signal/Event/Template.php
@@ -42,11 +42,18 @@ public function __construct($name);
/**
* Set the halt queue flag to true
+ *
+ * @param bool $early If true, the queue will be halted prior to the triggers callback being executed
+ */
+ public function haltQueue($early);
+
+ /**
+ * Check to see if the haltedQueueEarly flag is true
*/
- public function haltQueue();
+ public function isQueueHaltedEarly();
/**
- * Check to see if the haltQueue flag is true
+ * Check to see if the haltedQueue flag is true
*/
public function isQueueHalted();
View
23 lib/Proem/Signal/Manager/Standard.php
@@ -257,13 +257,24 @@ public function trigger(EventInterface $event, Callable $callback = null)
if ($listeners = $this->getListeners($event->getName())) {
foreach ($listeners as $listener) {
if ($result = (new EventCallback($listener, $event))->call()) {
- if ($result instanceof EventInterface && $callback !== null) {
- (new EventCallback($callback, $result))->call();
- }
+ if ($result instanceof EventInterface) {
+ // Was the queue halted early ?
+ if ($result->isQueueHaltedEarly()) {
+ return $this;
+ }
+
+ if ($callback !== null) {
+ (new EventCallback($callback, $result))->call();
+ }
- // Halt the queue ?
- if ($result->isQueueHalted()) {
- return;
+ // Was the queue halted ?
+ if ($result->isQueueHalted()) {
+ return $this;
+ }
+ } else {
+ throw new \RuntimeException(
+ 'Value returned from an Event Callback must be of type Proem\Signal\Event\Template'
+ );
}
}
}
View
20 tests/lib/Proem/Tests/SignalTest.php
@@ -97,6 +97,26 @@ public function testCanHaltQueue()
$this->assertEquals(1, $r->out);
}
+ public function testCanHaltQueueNow()
+ {
+ $r = new \StdClass;
+ $r->out = 0;
+ (new Manager)
+ ->attach('a', function($e) {
+ return $e; // make sure the callback is triggered.
+ })
+ ->attach('a', function($e) {
+ // halt the queue before the trigger's callback can be called for a second time.
+ return $e->haltQueue(true);
+ })
+
+ ->trigger(new Event('a'), function ($event) use ($r) {
+ $r->out++;
+ });
+
+ $this->assertEquals(1, $r->out);
+ }
+
public function testListenerCanListenToAllEvents()
{
$r = new \StdClass;

0 comments on commit d0f6ba9

Please sign in to comment.