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

ASpinner::getInterval()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AlecRabbit\Spinner\Core\A;
6
7
use AlecRabbit\Spinner\Contract\IDriver;
8
use AlecRabbit\Spinner\Contract\IFrame;
9
use AlecRabbit\Spinner\Contract\IInterval;
10
use AlecRabbit\Spinner\Core\Contract\ISpinner;
11
use AlecRabbit\Spinner\Core\Factory\FrameFactory;
12
use AlecRabbit\Spinner\Core\Widget\Contract\IWidgetComposite;
13
use AlecRabbit\Spinner\Core\Widget\Contract\IWidgetContext;
14
use Closure;
15
16
abstract class ASpinner implements ISpinner
17
{
18
    protected bool $active = false;
19
    protected bool $interrupted = false;
20
    protected IFrame $currentFrame;
21
22
    public function __construct(
23
        protected readonly IDriver $driver,
24
        protected IWidgetComposite $rootWidget,
25
    ) {
26
        $this->currentFrame = FrameFactory::createEmpty();
27
    }
28
29
    public function initialize(): void
30
    {
31
        $this->driver->initialize();
32
        $this->activate();
33
        $this->update();
34
    }
35
36
    public function activate(): void
37
    {
38
        $this->active = true;
39
    }
40
41
    protected function update(float $dt = null): void
42
    {
43
        $this->currentFrame = $this->rootWidget->update($dt);
44
    }
45
46
    public function interrupt(string $interruptMessage = null): void
47
    {
48
        $this->interrupted = true;
49
        $this->stop();
50
        $this->driver->interrupt($interruptMessage);
51
    }
52
53
    protected function stop(): void
54
    {
55
        $this->deactivate();
56
    }
57
58
    public function deactivate(): void
59
    {
60
        $this->erase();
61
        $this->active = false;
62
    }
63
64
    public function erase(): void
65
    {
66
        if ($this->active) {
67
            $this->driver->erase($this->currentFrame);
68
        }
69
    }
70
71
    public function finalize(string $finalMessage = null): void
72
    {
73
        if ($this->interrupted) {
74
            return;
75
        }
76
        $this->stop();
77
        $this->driver->finalize($finalMessage);
78
    }
79
80
    public function add(IWidgetComposite|IWidgetContext $element): IWidgetContext
81
    {
82
        $this->wrap(
83
            function () use ($element, &$result): void {
84
                $result = $this->rootWidget->add($element);
85
            }
86
        );
87
        /** @var IWidgetContext */
88
        return $result;
89
    }
90
91
    public function wrap(Closure $closure, mixed ...$args): void
92
    {
93
        $this->erase();
94
        $closure(...$args);
95
        $this->spin();
96
    }
97
98
    public function spin(float $dt = null): void
99
    {
100
        $this->render($this->elapsed($dt));
101
    }
102
103
    public function render(float $dt = null): void
104
    {
105
        if ($this->active) {
106
            $this->update($dt);
107
            $this->driver->display($this->currentFrame);
108
        }
109
    }
110
111
    protected function elapsed(?float $dt): float
112
    {
113
        return $dt ?? $this->driver->elapsedTime();
114
    }
115
116
    public function remove(IWidgetComposite|IWidgetContext $element): void
117
    {
118
        $this->wrap(
119
            function () use ($element) {
120
                $this->rootWidget->remove($element);
121
            }
122
        );
123
    }
124
125
    public function getInterval(): IInterval
126
    {
127
        return $this->rootWidget->getInterval();
128
    }
129
}
130