Spinner   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 6
dl 0
loc 146
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 17 4
A timeLimit() 0 6 1
A characters() 0 10 2
A advance() 0 22 5
A drawSpinner() 0 16 2
1
<?php
2
3
namespace League\CLImate\TerminalObject\Dynamic;
4
5
use League\CLImate\Exceptions\UnexpectedValueException;
6
use function array_merge;
7
use function count;
8
use function microtime;
9
use function range;
10
use function str_repeat;
11
use function substr;
12
use function trim;
13
14
final class Spinner extends DynamicTerminalObject
15
{
16
    /**
17
     * @var string[] The characters to be used to present progress.
18
     */
19
    private $characters = ["[=---]", "[-=--]", "[--=-]", "[---=]", "[--=-]", "[-=--]"];
20
21
    /**
22
     * @var int The current item of the sequence
23
     */
24
    private $current = 0;
25
26
    /**
27
     * @var bool Flag indicating whether we are writing the bar for the first time.
28
     */
29
    private $firstLine = true;
30
31
    /**
32
     * @var string Current label.
33
     */
34
    private $label;
35
36
    /**
37
     * @var float When the spinner was last drawn.
38
     */
39
    private $lastDrawn;
40
41
    /**
42
     * @var float How long to wait in seconds between drawing each stage.
43
     */
44
    private $timeLimit = 0.1;
45
46
47
    /**
48
     * If they pass in a sequence, set the sequence
49
     *
50
     * @param string $label
51
     * @param string ...$characters
52
     */
53
    public function __construct($label = null, ...$characters)
54
    {
55
        if ($label !== null) {
56
            $this->label = $label;
57
        }
58
59
        if (count($characters) < 1) {
60
            $characters = [];
61
            $size = 5;
62
            $positions = array_merge(range(0, $size - 1), range($size - 2, 1, -1));
63
            foreach ($positions as $pos) {
64
                $line = str_repeat("-", $size);
65
                $characters[] = "[" . substr($line, 0, $pos) . "=" . substr($line, $pos + 1) . "]";
66
            }
67
        }
68
        $this->characters(...$characters);
69
    }
70
71
72
    /**
73
     * Set the length of time to wait between drawing each stage.
74
     *
75
     * @param float $timeLimit
76
     *
77
     * @return Spinner
78
     */
79
    public function timeLimit($timeLimit)
80
    {
81
        $this->timeLimit = (float) $timeLimit;
82
83
        return $this;
84
    }
85
86
87
    /**
88
     * Set the character to loop around.
89
     *
90
     * @param string $characters
91
     *
92
     * @return Spinner
93
     */
94
    public function characters(...$characters)
95
    {
96
        if (count($characters) < 1) {
97
            throw new UnexpectedValueException("You must specify the characters to use");
98
        }
99
100
        $this->characters = $characters;
101
102
        return $this;
103
    }
104
105
106
    /**
107
     * Re-writes the spinner
108
     *
109
     * @param string $label
110
     *
111
     * @return void
112
     */
113
    public function advance($label = null)
114
    {
115
        if ($label === null) {
116
            $label = $this->label;
117
        }
118
119
        if ($this->lastDrawn) {
120
            $time = microtime(true) - $this->lastDrawn;
121
            if ($time < $this->timeLimit) {
122
                return;
123
            }
124
        }
125
126
        ++$this->current;
127
        if ($this->current >= count($this->characters)) {
128
            $this->current = 0;
129
        }
130
131
        $characters = $this->characters[$this->current];
132
        $this->drawSpinner($characters, $label);
133
        $this->lastDrawn = microtime(true);
134
    }
135
136
137
    /**
138
     * Draw the spinner
139
     *
140
     * @param string $characters
141
     * @param string $label
142
     */
143
    private function drawSpinner($characters, $label)
144
    {
145
        $spinner = "";
146
147
        if ($this->firstLine) {
148
            $this->firstLine = false;
149
        } else {
150
            $spinner .= $this->util->cursor->up(1);
151
            $spinner .= $this->util->cursor->startOfCurrentLine();
152
            $spinner .= $this->util->cursor->deleteCurrentLine();
153
        }
154
155
        $spinner .= trim("{$characters} {$label}");
156
157
        $this->output->write($this->parser->apply($spinner));
158
    }
159
}
160