PageRenderTime 45ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/React/EventLoop/Timer/Timers.php

https://gitlab.com/x33n/ampache
PHP | 104 lines | 80 code | 24 blank | 0 comment | 8 complexity | 66fd7b196db7d8adaba6336cc5250e89 MD5 | raw file
  1. <?php
  2. namespace React\EventLoop\Timer;
  3. use SplObjectStorage;
  4. use SplPriorityQueue;
  5. use InvalidArgumentException;
  6. class Timers
  7. {
  8. const MIN_RESOLUTION = 0.001;
  9. private $time;
  10. private $timers;
  11. private $scheduler;
  12. public function __construct()
  13. {
  14. $this->timers = new SplObjectStorage();
  15. $this->scheduler = new SplPriorityQueue();
  16. }
  17. public function updateTime()
  18. {
  19. return $this->time = microtime(true);
  20. }
  21. public function getTime()
  22. {
  23. return $this->time ?: $this->updateTime();
  24. }
  25. public function add(TimerInterface $timer)
  26. {
  27. $interval = $timer->getInterval();
  28. if ($interval < self::MIN_RESOLUTION) {
  29. throw new InvalidArgumentException('Timer events do not support sub-millisecond timeouts.');
  30. }
  31. $scheduledAt = $interval + $this->getTime();
  32. $this->timers->attach($timer, $scheduledAt);
  33. $this->scheduler->insert($timer, -$scheduledAt);
  34. }
  35. public function contains(TimerInterface $timer)
  36. {
  37. return $this->timers->contains($timer);
  38. }
  39. public function cancel(TimerInterface $timer)
  40. {
  41. $this->timers->detach($timer);
  42. }
  43. public function getFirst()
  44. {
  45. if ($this->scheduler->isEmpty()) {
  46. return null;
  47. }
  48. $scheduledAt = $this->timers[$this->scheduler->top()];
  49. return $scheduledAt;
  50. }
  51. public function isEmpty()
  52. {
  53. return count($this->timers) === 0;
  54. }
  55. public function tick()
  56. {
  57. $time = $this->updateTime();
  58. $timers = $this->timers;
  59. $scheduler = $this->scheduler;
  60. while (!$scheduler->isEmpty()) {
  61. $timer = $scheduler->top();
  62. if (!isset($timers[$timer])) {
  63. $scheduler->extract();
  64. $timers->detach($timer);
  65. continue;
  66. }
  67. if ($timers[$timer] >= $time) {
  68. break;
  69. }
  70. $scheduler->extract();
  71. call_user_func($timer->getCallback(), $timer);
  72. if ($timer->isPeriodic() && isset($timers[$timer])) {
  73. $timers[$timer] = $scheduledAt = $timer->getInterval() + $time;
  74. $scheduler->insert($timer, -$scheduledAt);
  75. } else {
  76. $timers->detach($timer);
  77. }
  78. }
  79. }
  80. }