Revolt.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. <?php
  2. /**
  3. * This file is part of workerman.
  4. *
  5. * Licensed under The MIT License
  6. * For full copyright and license information, please see the MIT-LICENSE.txt
  7. * Redistributions of files must retain the above copyright notice.
  8. *
  9. * @author walkor<walkor@workerman.net>
  10. * @copyright walkor<walkor@workerman.net>
  11. * @link http://www.workerman.net/
  12. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  13. */
  14. declare(strict_types=1);
  15. namespace Workerman\Events;
  16. use Revolt\EventLoop;
  17. use Revolt\EventLoop\Driver;
  18. use function count;
  19. use function function_exists;
  20. use function pcntl_signal;
  21. /**
  22. * Revolt eventloop
  23. */
  24. class Revolt implements EventInterface
  25. {
  26. /**
  27. * @var Driver
  28. */
  29. protected Driver $driver;
  30. /**
  31. * All listeners for read event.
  32. *
  33. * @var array<int, string>
  34. */
  35. protected array $readEvents = [];
  36. /**
  37. * All listeners for write event.
  38. *
  39. * @var array<int, string>
  40. */
  41. protected array $writeEvents = [];
  42. /**
  43. * Event listeners of signal.
  44. *
  45. * @var array<int, string>
  46. */
  47. protected array $eventSignal = [];
  48. /**
  49. * Event listeners of timer.
  50. *
  51. * @var array<int, string>
  52. */
  53. protected array $eventTimer = [];
  54. /**
  55. * Timer id.
  56. *
  57. * @var int
  58. */
  59. protected int $timerId = 1;
  60. /**
  61. * Construct.
  62. */
  63. public function __construct()
  64. {
  65. $this->driver = EventLoop::getDriver();
  66. }
  67. /**
  68. * Get driver.
  69. *
  70. * @return Driver
  71. */
  72. public function driver(): Driver
  73. {
  74. return $this->driver;
  75. }
  76. /**
  77. * {@inheritdoc}
  78. */
  79. public function run(): void
  80. {
  81. $this->driver->run();
  82. }
  83. /**
  84. * {@inheritdoc}
  85. */
  86. public function stop(): void
  87. {
  88. foreach ($this->eventSignal as $cbId) {
  89. $this->driver->cancel($cbId);
  90. }
  91. $this->driver->stop();
  92. if (function_exists('pcntl_signal')) {
  93. pcntl_signal(SIGINT, SIG_IGN);
  94. }
  95. }
  96. /**
  97. * {@inheritdoc}
  98. */
  99. public function delay(float $delay, callable $func, array $args = []): int
  100. {
  101. $timerId = $this->timerId++;
  102. $closure = function () use ($func, $args, $timerId) {
  103. unset($this->eventTimer[$timerId]);
  104. $func(...$args);
  105. };
  106. $cbId = $this->driver->delay($delay, $closure);
  107. $this->eventTimer[$timerId] = $cbId;
  108. return $timerId;
  109. }
  110. /**
  111. * {@inheritdoc}
  112. */
  113. public function repeat(float $interval, callable $func, array $args = []): int
  114. {
  115. $timerId = $this->timerId++;
  116. $cbId = $this->driver->repeat($interval, static fn () => $func(...$args));
  117. $this->eventTimer[$timerId] = $cbId;
  118. return $timerId;
  119. }
  120. /**
  121. * {@inheritdoc}
  122. */
  123. public function onReadable($stream, callable $func): void
  124. {
  125. $fdKey = (int)$stream;
  126. if (isset($this->readEvents[$fdKey])) {
  127. $this->driver->cancel($this->readEvents[$fdKey]);
  128. unset($this->readEvents[$fdKey]);
  129. }
  130. $this->readEvents[$fdKey] = $this->driver->onReadable($stream, static fn () => $func($stream));
  131. }
  132. /**
  133. * {@inheritdoc}
  134. */
  135. public function offReadable($stream): bool
  136. {
  137. $fdKey = (int)$stream;
  138. if (isset($this->readEvents[$fdKey])) {
  139. $this->driver->cancel($this->readEvents[$fdKey]);
  140. unset($this->readEvents[$fdKey]);
  141. return true;
  142. }
  143. return false;
  144. }
  145. /**
  146. * {@inheritdoc}
  147. */
  148. public function onWritable($stream, callable $func): void
  149. {
  150. $fdKey = (int)$stream;
  151. if (isset($this->writeEvents[$fdKey])) {
  152. $this->driver->cancel($this->writeEvents[$fdKey]);
  153. unset($this->writeEvents[$fdKey]);
  154. }
  155. $this->writeEvents[$fdKey] = $this->driver->onWritable($stream, static fn () => $func($stream));
  156. }
  157. /**
  158. * {@inheritdoc}
  159. */
  160. public function offWritable($stream): bool
  161. {
  162. $fdKey = (int)$stream;
  163. if (isset($this->writeEvents[$fdKey])) {
  164. $this->driver->cancel($this->writeEvents[$fdKey]);
  165. unset($this->writeEvents[$fdKey]);
  166. return true;
  167. }
  168. return false;
  169. }
  170. /**
  171. * {@inheritdoc}
  172. */
  173. public function onSignal(int $signal, callable $func): void
  174. {
  175. $fdKey = $signal;
  176. if (isset($this->eventSignal[$fdKey])) {
  177. $this->driver->cancel($this->eventSignal[$fdKey]);
  178. unset($this->eventSignal[$fdKey]);
  179. }
  180. $this->eventSignal[$fdKey] = $this->driver->onSignal($signal, static fn () => $func($signal));
  181. }
  182. /**
  183. * {@inheritdoc}
  184. */
  185. public function offSignal(int $signal): bool
  186. {
  187. $fdKey = $signal;
  188. if (isset($this->eventSignal[$fdKey])) {
  189. $this->driver->cancel($this->eventSignal[$fdKey]);
  190. unset($this->eventSignal[$fdKey]);
  191. return true;
  192. }
  193. return false;
  194. }
  195. /**
  196. * {@inheritdoc}
  197. */
  198. public function offDelay(int $timerId): bool
  199. {
  200. if (isset($this->eventTimer[$timerId])) {
  201. $this->driver->cancel($this->eventTimer[$timerId]);
  202. unset($this->eventTimer[$timerId]);
  203. return true;
  204. }
  205. return false;
  206. }
  207. /**
  208. * {@inheritdoc}
  209. */
  210. public function offRepeat(int $timerId): bool
  211. {
  212. return $this->offDelay($timerId);
  213. }
  214. /**
  215. * {@inheritdoc}
  216. */
  217. public function deleteAllTimer(): void
  218. {
  219. foreach ($this->eventTimer as $cbId) {
  220. $this->driver->cancel($cbId);
  221. }
  222. $this->eventTimer = [];
  223. }
  224. /**
  225. * {@inheritdoc}
  226. */
  227. public function getTimerCount(): int
  228. {
  229. return count($this->eventTimer);
  230. }
  231. /**
  232. * {@inheritdoc}
  233. */
  234. public function setErrorHandler(callable $errorHandler): void
  235. {
  236. $this->driver->setErrorHandler($errorHandler);
  237. }
  238. /**
  239. * {@inheritdoc}
  240. */
  241. public function getErrorHandler(): ?callable
  242. {
  243. return $this->driver->getErrorHandler();
  244. }
  245. }