diff --git a/src/Drivers/EvLoop.php b/src/Drivers/EvLoop.php index 582284c..11dbab2 100644 --- a/src/Drivers/EvLoop.php +++ b/src/Drivers/EvLoop.php @@ -6,6 +6,7 @@ use EventLoop\Exception\LoopException; use EventLoop\Storage; use EvLoop as BaseEvLoop; +use Closure; class EvLoop implements LoopInterface { @@ -38,7 +39,7 @@ public function __construct() } /** @inheritDoc */ - public function addReadStream($stream, callable $handler): void + public function addReadStream($stream, Closure $handler): void { if(is_resource($stream)){ $event = new \EvIo($stream,\Ev::READ, $handler); @@ -58,7 +59,7 @@ public function delReadStream($stream): void } /** @inheritDoc */ - public function addWriteStream($stream, callable $handler): void + public function addWriteStream($stream, Closure $handler): void { if(is_resource($stream)){ $event = new \EvIo($stream, \Ev::WRITE, $handler); @@ -78,14 +79,14 @@ public function delWriteStream($stream): void } /** @inheritDoc */ - public function addSignal(int $signal, callable $handler): void + public function addSignal(int $signal, Closure $handler): void { $event = new \EvSignal($signal, $handler); $this->_signals[$signal] = $event; } /** @inheritDoc */ - public function delSignal(int $signal, callable $handler): void + public function delSignal(int $signal, Closure $handler): void { if(isset($this->_signals[$signal])){ /** @var \EvSignal $event */ @@ -96,15 +97,14 @@ public function delSignal(int $signal, callable $handler): void } /** @inheritDoc */ - public function addTimer(float $delay, float $repeat, callable $callback): int + public function addTimer(float $delay, float $repeat, Closure $callback): string { - return $this->_storage->add( - $event = new \EvTimer($delay, $repeat, $callback) - ); + $event = new \EvTimer($delay, $repeat, $callback); + return $this->_storage->add(spl_object_hash($event), $event); } /** @inheritDoc */ - public function delTimer(int $timerId): void + public function delTimer(string $timerId): void { /** @var \EvTimer $event */ if($event = $this->_storage->get($timerId)){ diff --git a/src/Drivers/EventLoop.php b/src/Drivers/EventLoop.php index efd339c..c4a83f4 100644 --- a/src/Drivers/EventLoop.php +++ b/src/Drivers/EventLoop.php @@ -7,6 +7,7 @@ use EventBase; use Event; use EventLoop\Storage; +use Closure; class EventLoop implements LoopInterface { @@ -36,7 +37,7 @@ public function __construct() } /** @inheritDoc */ - public function addReadStream($stream, callable $handler): void + public function addReadStream($stream, Closure $handler): void { if(is_resource($stream)){ $event = new Event($this->_eventBase, $stream, \Event::READ | \Event::PERSIST, $handler); @@ -58,7 +59,7 @@ public function delReadStream($stream): void } /** @inheritDoc */ - public function addWriteStream($stream, callable $handler): void + public function addWriteStream($stream, Closure $handler): void { if(is_resource($stream)){ $event = new Event($this->_eventBase, $stream, Event::WRITE | Event::PERSIST, $handler); @@ -80,7 +81,7 @@ public function delWriteStream($stream): void } /** @inheritDoc */ - public function addSignal(int $signal, callable $handler): void + public function addSignal(int $signal, Closure $handler): void { $event = Event::signal($this->_eventBase, $signal, $handler); if ($event or $event->add()) { @@ -90,7 +91,7 @@ public function addSignal(int $signal, callable $handler): void } /** @inheritDoc */ - public function delSignal(int $signal, callable $handler): void + public function delSignal(int $signal, Closure $handler): void { if(isset($this->_signals[$signal])){ /** @var Event $event */ @@ -101,11 +102,11 @@ public function delSignal(int $signal, callable $handler): void } /** @inheritDoc */ - public function addTimer(float $delay, float $repeat, callable $callback): int + public function addTimer(float $delay, float $repeat, Closure $callback): string { - $id = $this->_storage->id(); + $event = new Event($this->_eventBase, -1, \Event::TIMEOUT, function () use(&$event, $repeat, $callback){ + $id = spl_object_hash($event); - $event = new Event($this->_eventBase, -1, \Event::TIMEOUT, function () use($repeat, $id, $callback){ $callback(); if($repeat === 0.0){ @@ -115,15 +116,14 @@ public function addTimer(float $delay, float $repeat, callable $callback): int $event->add($repeat); $this->_storage->set($id, $event); } - }); $event->add($delay); - return $this->_storage->add($event); + return $this->_storage->add(spl_object_hash($event), $event); } /** @inheritDoc */ - public function delTimer(int $timerId): void + public function delTimer(string $timerId): void { /** @var Event $events */ if($event = $this->_storage->get($timerId)){ diff --git a/src/Drivers/LoopInterface.php b/src/Drivers/LoopInterface.php index e94bad4..da06d60 100644 --- a/src/Drivers/LoopInterface.php +++ b/src/Drivers/LoopInterface.php @@ -3,6 +3,7 @@ namespace EventLoop\Drivers; +use Closure; use EventLoop\Exception\LoopException; interface LoopInterface @@ -10,25 +11,25 @@ interface LoopInterface /** * 创建信号处理 * @param int $signal - * @param callable $handler + * @param Closure $handler * @throws LoopException */ - public function addSignal(int $signal, callable $handler): void; + public function addSignal(int $signal, Closure $handler): void; /** * 移除信号处理 * @param int $signal - * @param callable $handler + * @param Closure $handler */ - public function delSignal(int $signal, callable $handler): void; + public function delSignal(int $signal, Closure $handler): void; /** * 创建读流 * @param resource $stream - * @param callable $handler + * @param Closure $handler * @throws LoopException */ - public function addReadStream($stream, callable $handler): void; + public function addReadStream($stream, Closure $handler): void; /** * 移除读流 @@ -39,10 +40,10 @@ public function delReadStream($stream): void; /** * 创建写流 * @param resource $stream - * @param callable $handler + * @param Closure $handler * @throws LoopException */ - public function addWriteStream($stream, callable $handler): void; + public function addWriteStream($stream, Closure $handler): void; /** * 移除写流 @@ -54,16 +55,16 @@ public function delWriteStream($stream): void; * 创建定时器 * @param float $delay * @param float $repeat - * @param callable $callback - * @return int + * @param Closure $callback + * @return string */ - public function addTimer(float $delay, float $repeat, callable $callback): int; + public function addTimer(float $delay, float $repeat, Closure $callback): string; /** * 移除定时触发器 - * @param int $timerId + * @param string $timerId */ - public function delTimer(int $timerId): void; + public function delTimer(string $timerId): void; /** * main loop. diff --git a/src/Drivers/NativeLoop.php b/src/Drivers/NativeLoop.php index cc55880..7619f8b 100644 --- a/src/Drivers/NativeLoop.php +++ b/src/Drivers/NativeLoop.php @@ -5,6 +5,9 @@ use EventLoop\Exception\LoopException; use EventLoop\Storage; +use EventLoop\Timer; +use SplPriorityQueue; +use Closure; class NativeLoop implements LoopInterface { @@ -26,8 +29,8 @@ class NativeLoop implements LoopInterface /** @var Storage 定时器容器 */ protected Storage $_storage; - /** @var \SplPriorityQueue 优先队列 */ - protected \SplPriorityQueue $_queue; + /** @var SplPriorityQueue 优先队列 */ + protected SplPriorityQueue $_queue; protected bool $_stopped = false; @@ -41,14 +44,14 @@ public function __construct() throw new LoopException('not support: ext-pcntl'); } $this->_storage = new Storage(); - $this->_queue = new \SplPriorityQueue(); - $this->_queue->setExtractFlags(\SplPriorityQueue::EXTR_BOTH); + $this->_queue = new SplPriorityQueue(); + $this->_queue->setExtractFlags(SplPriorityQueue::EXTR_BOTH); $this->_readFds = []; $this->_writeFds = []; } /** @inheritDoc */ - public function addReadStream($stream, callable $handler): void + public function addReadStream($stream, Closure $handler): void { if(is_resource($stream)){ $key = (int) $stream; @@ -72,7 +75,7 @@ public function delReadStream($stream): void } /** @inheritDoc */ - public function addWriteStream($stream, callable $handler): void + public function addWriteStream($stream, Closure $handler): void { if(is_resource($stream)){ $key = (int) $stream; @@ -96,7 +99,7 @@ public function delWriteStream($stream): void } /** @inheritDoc */ - public function addSignal(int $signal, callable $handler): void + public function addSignal(int $signal, Closure $handler): void { $this->_signals[$signal] = $handler; \pcntl_signal($signal, function($signal){ @@ -105,26 +108,23 @@ public function addSignal(int $signal, callable $handler): void } /** @inheritDoc */ - public function delSignal(int $signal, callable $handler): void + public function delSignal(int $signal, Closure $handler): void { unset($this->_signals[$signal]); \pcntl_signal($signal, \SIG_IGN); } /** @inheritDoc */ - public function addTimer(float $delay, float $repeat, callable $callback): int + public function addTimer(float $delay, float $repeat, Closure $callback): string { + $timer = new Timer($delay, $repeat, $callback); $runTime = \hrtime(true) * 1e-9 + $delay; - $this->_queue->insert($this->_storage->id(), -$runTime); - return $this->_storage->add([ - 'delay' => $delay, - 'repeat' => $repeat, - 'callback' => $callback - ]); + $this->_queue->insert($id = spl_object_hash($timer), -$runTime); + return $this->_storage->add($id, $timer); } /** @inheritDoc */ - public function delTimer(int $timerId): void + public function delTimer(string $timerId): void { $this->_storage->del($timerId); } @@ -189,9 +189,10 @@ protected function _tick(): void $data = $this->_queue->top(); $runTime = -$data['priority']; $timerId = $data['data']; + /** @var Timer $data */ if($data = $this->_storage->get($timerId)){ - $repeat = $data['repeat']; - $callback = $data['callback']; + $repeat = $data->getRepeat(); + $callback = $data->getHandler(); $timeNow = \hrtime(true) * 1e-9; if (($runTime - $timeNow) <= 0) { $this->_queue->extract(); diff --git a/src/Storage.php b/src/Storage.php index df659d1..d9e3921 100644 --- a/src/Storage.php +++ b/src/Storage.php @@ -5,67 +5,70 @@ final class Storage { - /** @var int id */ - private int $_id = 1; + /** @var int */ + private int $_count = 0; /** @var array storage */ private array $_storage = []; /** - * @param mixed $value - * @return int + * @param string $key + * @param mixed|null $value + * @return string */ - public function add($value): int + public function add(string $key, $value): string { - $this->_storage[$this->_id] = $value; - return $this->_id ++; + $this->_storage[$key] = $value; + $this->_count ++; + return $key; } /** - * @param int $id - * @param $value - * @return int + * @param string $key + * @param mixed|null $value + * @return string */ - public function set(int $id, $value): int + public function set(string $key, $value): string { - if($this->exist($id)){ - $this->_storage[$id] = $value; + if($this->exist($key)){ + $this->_storage[$key] = $value; } - return $id; + return $key; } /** - * @param int $id + * @param string $key */ - public function del(int $id): void + public function del(string $key): void { - unset($this->_storage[$id]); + unset($this->_storage[$key]); + $this->_count --; } /** - * @param int $id + * @param string $key * @return mixed|null */ - public function get(int $id) + public function get(string $key) { - return $this->exist($id) ? $this->_storage[$id] : null; + return $this->exist($key) ? $this->_storage[$key] : null; } /** * @return int */ - public function id(): int + public function count(): int { - return $this->_id; + return $this->_count; } /** - * @param int $id + * @param string $key * @return bool */ - public function exist(int $id): bool + public function exist(string $key): bool { - return isset($this->_storage[$id]); + return isset($this->_storage[$key]); } /** diff --git a/src/Timer.php b/src/Timer.php new file mode 100644 index 0000000..420cb5c --- /dev/null +++ b/src/Timer.php @@ -0,0 +1,48 @@ +delay = $delay; + $this->repeat = $repeat; + $this->handler = $handler; + } + + /** + * @return float + */ + public function getDelay(): float + { + return $this->delay; + } + + /** + * @return float + */ + public function getRepeat(): float + { + return $this->repeat; + } + + /** + * @return Closure + */ + public function getHandler(): Closure + { + return $this->handler; + } + + +} \ No newline at end of file diff --git a/test/test.php b/test/test.php index 5a0b046..c6ce02b 100644 --- a/test/test.php +++ b/test/test.php @@ -1,8 +1,10 @@ addTimer(5.0,1.0,function (){ +$loop = \EventLoop\Factory::create(\EventLoop\Drivers\EventLoop::class); +$id = $loop->addTimer(5.0,1.0,function () use (&$id, $loop){ dump(microtime(true)); + $loop->delTimer($id); + $loop->destroy(); }); $loop->loop(); \ No newline at end of file