Skip to content

Commit

Permalink
Merge branch 'feature/signals-refactor' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
trq committed Oct 31, 2012
2 parents b606985 + 7c124dd commit 005e68c
Show file tree
Hide file tree
Showing 6 changed files with 305 additions and 66 deletions.
49 changes: 48 additions & 1 deletion lib/Proem/Signal/Event/Standard.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,20 @@
*/
class Standard implements Template
{
/**
* Halted queue flag
*
* @var bool
*/
protected $haltedQueue = false;

/**
* Halt the queue *early* flag.
*
* @var bool
*/
protected $haltedQueueEarly = false;

/**
* Store params
*
Expand All @@ -59,6 +73,37 @@ public function __construct($name)
$this->name = $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 = false)
{
if ($early) {
$this->haltedQueueEarly = true;
}

$this->haltedQueue = true;
return $this;
}

/**
* 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()
{
return $this->haltedQueue;
}

/**
* Set a param
*
Expand All @@ -77,11 +122,13 @@ public function setParam($index, $value)
*
* @return mixed
*/
public function getParam($index)
public function getParam($index, $default = null)
{
if (isset($this->params[$index])) {
return $this->params[$index];
}

return $default;
}

/**
Expand Down
35 changes: 35 additions & 0 deletions lib/Proem/Signal/Event/Template.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,41 @@ interface Template
*/
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 isQueueHaltedEarly();

/**
* Check to see if the haltedQueue flag is true
*/
public function isQueueHalted();

/**
* Set a param
*
* @param string $key
* @param mixed $param
* @return Proem\Signal\Event\Template
*/
public function setParam($key, $param);

/**
* Retrieve a parameter (or some default value) by key
*
* @param string $key
* @param mixed $default Default value returned if $key does not exist
* @return mixed
*/
public function getParam($key, $default);

/**
* Set params
*
Expand Down
167 changes: 106 additions & 61 deletions lib/Proem/Signal/Manager/Standard.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@

use Proem\Util\Storage\Queue;
use Proem\Util\Process\Callback;
use Proem\Signal\Event\Standard as Event;
use Proem\Util\Process\EventCallback;
use Proem\Signal\Event\Template as EventInterface;
use Proem\Signal\Manager\Template;

/**
Expand Down Expand Up @@ -67,6 +68,84 @@ class Standard implements Template
*/
protected $wildcardSearching = false;

/**
* Given an event name, this method searches for all possible
* wildcard matches in the queues. When/If a match is found
* it will then copy it's key and priority from the wildcards
* queue into the named event's queue.
*
* @param $name The event name
* @return bool True if match is found
*/
protected function populateQueueFromWildSearch($name)
{
$listenerMatched = false;
$parts = explode('.', $name);
while (count($parts)) {
array_pop($parts);
$part = implode('.', $parts) . self::WILDCARD;

if (isset($this->queues[$part])) {
$listenerMatched = true;
/**
* Add to currently named queue
*/
foreach ($this->queues[$part] as $listener) {
if (isset($this->queues[$name])) {
$this->queues[$name]->insert($listener['key'], $listener['priority']);
} else {
$this->queues[$name] = new Queue;
$this->queues[$name]->insert($listener['key'], $listener['priority']);
}
}
}
}

return $listenerMatched;
}

/**
* Store a callback index by a generated key
*
* @param callable $callback
* @return string $key
*/
protected function storeCallback(callable $callback)
{
$key = md5(microtime());
$this->callbacks[$key] = $callback;
return $key;
}

/**
* Store a callback's key and priority in a queue indexed
* by the event they are attached to.
*
* @param $event The name of the event this callback is being attached to
* @param string $key The key the callback is stored under
* @priority The priority this callback has within this queue
*/
protected function pushToQueue($event, $key, $priority)
{
$end = substr($event, -2);
if (isset($this->queues[$event])) {
if ($end == self::WILDCARD) {
$this->wildcardSearching = true;
$this->queues[$event][] = ['key' => $key, 'priority' => $priority];
} else {
$this->queues[$event]->insert($key, $priority);
}
} else {
if ($end == self::WILDCARD) {
$this->wildcardSearching = true;
$this->queues[$event][] = ['key' => $key, 'priority' => $priority];
} else {
$this->queues[$event] = new Queue;
$this->queues[$event]->insert($key, $priority);
}
}
}

/**
* Remove event listeners from a particular index.
*
Expand Down Expand Up @@ -106,25 +185,8 @@ public function getListeners($name)
* Optionally search for wildcard matches.
*/
if ($this->wildcardSearching) {
$parts = explode('.', $name);
while (count($parts)) {
array_pop($parts);
$part = implode('.', $parts) . self::WILDCARD;

if (isset($this->queues[$part])) {
$listenerMatched = true;
/**
* Add to currently named queue
*/
foreach ($this->queues[$part] as $listener) {
if (isset($this->queues[$name])) {
$this->queues[$name]->insert($listener[0], $listener[1]);
} else {
$this->queues[$name] = new Queue;
$this->queues[$name]->insert($listener[0], $listener[1]);
}
}
}
if ($this->populateQueueFromWildSearch($name)) {
$listenerMatched = true;
}
}

Expand Down Expand Up @@ -167,49 +229,16 @@ public function getListeners($name)
*
* @return Proem\Signal\Manager\Template
*/
public function attach($name, Callable $callback, $priority = 0)
public function attach($name, callable $callback, $priority = 0)
{
$key = md5(microtime());
$this->callbacks[$key] = $callback;
$key = $this->storeCallback($callback);

if (is_array($name)) {
foreach ($name as $event) {
$end = substr($event, -2);
if (isset($this->queues[$event])) {
if ($end == self::WILDCARD) {
$this->wildcardSearching = true;
$this->queues[$name][] = [$key, $priority];
} else {
$this->queues[$event]->insert($key, $priority);
}
} else {
if ($end == self::WILDCARD) {
$this->wildcardSearching = true;
$this->queues[$event][] = [$key, $priority];
} else {
$this->queues[$event] = new Queue;
$this->queues[$event]->insert($key, $priority);
}
}
$this->pushToQueue($event, $key, $priority);
}
} else {
$end = substr($name, -2);
if (isset($this->queues[$name])) {
if ($end == self::WILDCARD) {
$this->wildcardSearching = true;
$this->queues[$name][] = [$key, $priority];
} else {
$this->queues[$name]->insert($key, $priority);
}
} else {
if ($end == self::WILDCARD) {
$this->wildcardSearching = true;
$this->queues[$name][] = [$key, $priority];
} else {
$this->queues[$name] = new Queue;
$this->queues[$name]->insert($key, $priority);
}
}
$this->pushToQueue($name, $key, $priority);
}

return $this;
Expand All @@ -223,13 +252,29 @@ public function attach($name, Callable $callback, $priority = 0)
*
* @return Proem\Signal\Manager\Template
*/
public function trigger(Event $event, Callable $callback = null)
public function trigger(EventInterface $event, Callable $callback = null)
{
if ($listeners = $this->getListeners($event->getName())) {
foreach ($listeners as $listener) {
if ($result = (new Callback($listener, $event))->call()) {
if ($callback !== null) {
(new Callback($callback, $result))->call();
if ($result = (new EventCallback($listener, $event))->call()) {
if ($result instanceof EventInterface) {
// Was the queue halted early ?
if ($result->isQueueHaltedEarly()) {
return $this;
}

if ($callback !== null) {
(new EventCallback($callback, $result))->call();
}

// 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'
);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions lib/Proem/Signal/Manager/Template.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*/
namespace Proem\Signal\Manager;

use Proem\Signal\Event\Standard as Event;
use Proem\Signal\Event\Template as EventInterface;

/**
* Interface that all signal managers must implement.
Expand Down Expand Up @@ -61,5 +61,5 @@ public function attach($name, Callable $callback);
* @param array $options An array of Proem\Util\Opt\Options objects
* @return Proem\Signal\Manager\Template
*/
public function trigger(Event $event, Callable $callback = null);
public function trigger(EventInterface $event, Callable $callback = null);
}
Loading

0 comments on commit 005e68c

Please sign in to comment.