RevoltLoopAdapter   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 73
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 23
c 0
b 0
f 0
dl 0
loc 73
rs 10
wmc 12

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A repeat() 0 4 1
A cancel() 0 11 2
A onSignal() 0 4 1
A stop() 0 4 1
A run() 0 3 1
A autoStart() 0 19 4
A delay() 0 4 1
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