Lines 100.00% 17 / 17
Methods 100.00% 4 / 4
Classes 100.00% 1 / 1
Name Lines Methods CRAP
 startTimer 100.00% 8 / 8 100.00% 1 / 1 1
 waitFor 100.00% 7 / 7 100.00% 1 / 1 3
 timeout 100.00% 1 / 1 100.00% 1 / 1 1
 delay 100.00% 1 / 1 100.00% 1 / 1 1
19final class RevoltTimers implements Timers, Deadlines
20{
21    public function startTimer(Duration $delay, Closure $callback): TimerHandle
22    {
23        $handle = new RevoltTimerHandle();
24
25        $identifier = EventLoop::delay($delay->toSeconds(), static function () use ($handle, $callback): void {
26            $handle->markFired();
27
28            $callback();
29        });
30
31        EventLoop::unreference($identifier);
32
33        $handle->attachWatcher($identifier);
34
35        return $handle;
36    }
37
38    /**
39     * @template T
40     * @param Closure(PendingWait<T>): (Closure(): void) $arm
41     * @return T|null
42     */
43    public function waitFor(Closure $arm, ?Duration $timeout = null): mixed
44    {
45        /** @var DeferredWait<T> $wait */
46        $wait = new DeferredWait();
47        $teardown = $arm($wait);
48        // Referenced, unlike startTimer(), so a wait in {main} keeps the loop running until it ends.
49        $timeoutWatcher = $timeout === null ? null : EventLoop::delay($timeout->toSeconds(), $wait->expire(...));
50
51        try {
52            return $wait->awaitOutcome();
53        } finally {
54            if ($timeoutWatcher !== null) {
55                EventLoop::cancel($timeoutWatcher);
56            }
57
58            $teardown();
59        }
60    }
61
62    public function timeout(Duration $limit): Cancellation
63    {
64        return new TimeoutCancellation($limit->toSeconds());
65    }
66
67    public function delay(Duration $wait, ?Cancellation $cancellation = null): void
68    {
69        delay($wait->toSeconds(), cancellation: $cancellation);
70    }
71}