RevoltLoopAdapter::autoStart()   A
last analyzed

Complexity

Conditions 4
Paths 1

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 19
rs 9.9666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AlecRabbit\Spinner\Asynchronous\Revolt;
6
7
use AlecRabbit\Spinner\Core\Loop\Contract\A\ALoopAdapter;
8
use AlecRabbit\Spinner\Exception\InvalidArgument;
9
use Closure;
10
use Revolt\EventLoop;
11
12
/**
13
 * @codeCoverageIgnore
14
 */
15
final class RevoltLoopAdapter extends ALoopAdapter
16
{
17
    private static bool $stopped = false;
18
19
    public function __construct(
20
        private readonly EventLoop\Driver $loop,
21
    ) {
22
    }
23
24
    public function cancel(mixed $timer): void
25
    {
26
        if (!is_string($timer)) {
27
            throw new InvalidArgument(
28
                sprintf(
29
                    'Invalid timer type: %s, expected string',
30
                    gettype($timer)
31
                )
32
            );
33
        }
34
        EventLoop::cancel($timer);
35
    }
36
37
    public function repeat(float $interval, Closure $closure): string
38
    {
39
        /** @psalm-suppress MixedArgumentTypeCoercion */
40
        return EventLoop::repeat($interval, $closure);
41
    }
42
43
    public function autoStart(): void
44
    {
45
        // Automatically run loop at the end of script, unless already started or stopped explicitly.
46
        // @codeCoverageIgnoreStart
47
        $hasRun = false;
48
        EventLoop::defer(static function () use (&$hasRun): void {
49
            $hasRun = true;
50
        });
51
52
        /** @psalm-suppress UnsupportedPropertyReferenceUsage */
53
        $stopped = &self::$stopped;
54
        register_shutdown_function(static function () use (&$hasRun, &$stopped): void {
55
            // Don't run if we're coming from a fatal error (uncaught exception).
56
            if (self::error()) { // See [889ad594-ca28-4770-bb38-fd5bd8cb1777].
57
                return;
58
            }
59
60
            if (!$hasRun && !$stopped) {
61
                EventLoop::run();
62
            }
63
        });
64
        // @codeCoverageIgnoreEnd
65
    }
66
67
    public function run(): void
68
    {
69
        $this->loop->run();
70
    }
71
72
    public function delay(float $delay, Closure $closure): void
73
    {
74
        /** @psalm-suppress MixedArgumentTypeCoercion */
75
        EventLoop::delay($delay, $closure);
76
    }
77
78
    public function stop(): void
79
    {
80
        self::$stopped = true;
81
        $this->loop->stop();
82
    }
83
84
    public function onSignal(int $signal, Closure $closure): void
85
    {
86
        /** @psalm-suppress MixedArgumentTypeCoercion */
87
        EventLoop::onSignal($signal, $closure);
88
    }
89
}
90