Lines
88.88%
16 / 18
Functions and Methods
75.00%
3 / 4
Classes and Traits
0.00%
0 / 1
| Name | Lines | Functions and Methods | CRAP | Classes and Traits | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Watch | 88.88% | 16 / 18 | 75.00% | 3 / 4 | 8.09 | 0.00% | 0 / 1 | |||
| __construct | 84.61% | 11 / 13 | 0.00% | 0 / 1 | 4.06 | |||||
| until | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| token | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| release | 100.00% | 3 / 3 | 100.00% | 1 / 1 | 2 | |||||
| 1 | <?php | |
| 2 | ||
| 3 | declare(strict_types=1); | |
| 4 | ||
| 5 | namespace Lorekeeper\Client; | |
| 6 | ||
| 7 | use Closure; | |
| 8 | use Psl\Async; | |
| 9 | use Psl\Async\Awaitable; | |
| 10 | use Psl\Async\CancellationTokenInterface; | |
| 11 | use Psl\Async\Exception\CancelledException; | |
| 12 | use Psl\Async\SignalCancellationToken; | |
| 13 | use Psl\DateTime\Duration; | |
| 14 | ||
| 15 | final class Watch | |
| 16 | { | |
| 17 | private readonly SignalCancellationToken $token; | |
| 18 | ||
| 19 | private readonly SignalCancellationToken $released; | |
| 20 | ||
| 21 | /** @var Awaitable<void> */ | |
| 22 | private readonly Awaitable $watcher; | |
| 23 | ||
| 24 | /** @param Closure(): bool $condition */ | |
| 25 | private function __construct(Closure $condition, Duration $every) | |
| 26 | { | |
| 27 | $this->token = new SignalCancellationToken(); | |
| 28 | $this->released = new SignalCancellationToken(); | |
| 29 | ||
| 30 | $token = $this->token; | |
| 31 | $released = $this->released; | |
| 32 | $this->watcher = Async\run(static function () use ($condition, $every, $token, $released): void { | |
| 33 | while (!$released->isCancelled()) { | |
| 34 | try { | |
| 35 | Async\sleep($every, $released); | |
| 36 | } catch (CancelledException) { | |
| 37 | return; | |
| 38 | } | |
| 39 | ||
| 40 | if ($condition()) { | |
| 41 | $token->cancel(); | |
| 42 | ||
| 43 | return; | |
| 44 | } | |
| 45 | } | |
| 46 | }); | |
| 47 | } | |
| 48 | ||
| 49 | /** @param Closure(): bool $condition */ | |
| 50 | public static function until(Closure $condition, ?Duration $every = null): self | |
| 51 | { | |
| 52 | return new self($condition, $every ?? Duration::seconds(1)); | |
| 53 | } | |
| 54 | ||
| 55 | public function token(): CancellationTokenInterface | |
| 56 | { | |
| 57 | return $this->token; | |
| 58 | } | |
| 59 | ||
| 60 | public function release(): void | |
| 61 | { | |
| 62 | if (!$this->released->isCancelled()) { | |
| 63 | $this->released->cancel(); | |
| 64 | } | |
| 65 | ||
| 66 | $this->watcher->await(); | |
| 67 | } | |
| 68 | } |