Passed
Push — master ( 823aee...b9b37f )
by Alec
13:15 queued 12s
created

ATimer   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 40
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 21
c 0
b 0
f 0
dl 0
loc 40
rs 10
wmc 7

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A assertTimeFunction() 0 16 5
A elapsed() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AlecRabbit\Spinner\Core\A;
6
7
use AlecRabbit\Spinner\Contract\ITimer;
8
use Closure;
9
use InvalidArgumentException;
10
use ReflectionException;
11
use ReflectionFunction;
12
13
/**
14
 * @codeCoverageIgnore
15
 */
16
abstract class ATimer implements ITimer
17
{
18
    protected const COEFFICIENT = 1e-6; // for milliseconds
19
    protected Closure $timeFunction;
20
21
    public function __construct(
22
        ?Closure $timeFunction = null,
23
        protected float $time = 0.0,
24
    ) {
25
        self::assertTimeFunction($timeFunction);
26
        $this->timeFunction =
27
            $timeFunction
28
            ??
29
            static fn(): float => hrtime(true) * self::COEFFICIENT; // returns milliseconds
30
    }
31
32
    private static function assertTimeFunction(?Closure $timeFunction): void
33
    {
34
        if (null === $timeFunction) {
35
            return;
36
        }
37
        try {
38
            $reflection = new ReflectionFunction($timeFunction);
39
            if (1 !== $reflection->getNumberOfParameters()) {
40
                throw new InvalidArgumentException('Time function must have no parameters');
41
            }
42
            /** @psalm-suppress UndefinedMethod */
43
            if ('float' !== $reflection->getReturnType()?->getName()) {
0 ignored issues
show
Bug introduced by
The method getName() does not exist on ReflectionType. It seems like you code against a sub-type of ReflectionType such as ReflectionNamedType. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

43
            if ('float' !== $reflection->getReturnType()?->/** @scrutinizer ignore-call */ getName()) {
Loading history...
44
                throw new InvalidArgumentException('Time function must return float');
45
            }
46
        } catch (ReflectionException $e) {
47
            throw new InvalidArgumentException('Time function has invalid signature: ' . $e->getMessage());
48
        }
49
    }
50
51
    public function elapsed(): float
52
    {
53
        $last = $this->time;
54
        $this->time = (float)($this->timeFunction)();
55
        return $this->time - $last;
56
    }
57
}
58