Completed
Push — spinner ( 9b73e8 )
by Craig
05:29
created

Spinner   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 158
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 5
dl 0
loc 158
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
B advance() 0 22 5
A drawSpinner() 0 16 2
1
<?php
2
3
namespace League\CLImate\TerminalObject\Dynamic;
4
5
class Spinner extends DynamicTerminalObject
6
{
7
    /**
8
     * The characters to be used to present progress.
9
     *
10
     * @var string $characters
11
     */
12
    private $characters = ["[=---]", "[-=--]", "[--=-]", "[---=]", "[--=-]", "[-=--]"];
13
14
    /**
15
     * The current item of the sequence
16
     *
17
     * @var integer $current
18
     */
19
    private $current = 0;
20
21
    /**
22
     * Flag indicating whether we are writing the bar for the first time
23
     *
24
     * @var boolean $first_line
25
     */
26
    private $first_line = true;
27
28
    /**
29
     * Current label
30
     *
31
     * @var string $label
32
     */
33
    private $label;
34
35
    /**
36
     * When the spinner was last drawn.
37
     *
38
     * @var float $last_drawn
39
     */
40
    private $last_drawn;
41
42
    /**
43
     * How long to wait in seconds between drawing each stage.
44
     *
45
     * @var float $time_limit
46
     */
47
    private $time_limit = 0.1;
48
49
50
    /**
51
     * If they pass in a sequence, set the sequence
52
     *
53
     * @param string $label
54
     * @param string[] $characters
55
     */
56
    public function __construct($label = null, ...$characters)
57
    {
58
        if ($label !== null) {
59
            $this->label = $label;
60
        }
61
62
        if (count($characters) < 1) {
63
            $characters = [];
64
            $size = 5;
65
            $positions = array_merge(range(0, $size - 1), range($size - 2, 1, -1));
66
            foreach ($positions as $pos) {
67
                $line = str_repeat("-", $size);
68
                $characters[] = "[" . substr($line, 0, $pos) . "=" . substr($line, $pos + 1) . "]";
69
            }
70
        }
71
        $this->characters(...$characters);
72
    }
73
74
75
    /**
76
     * Set the length of time to wait between drawing each stage.
77
     *
78
     * @param  float $time_limit
79
     *
80
     * @return Spinner
81
     */
82
    public function timeLimit($time_limit)
83
    {
84
        $this->time_limit = (float) $time_limit;
85
86
        return $this;
87
    }
88
89
90
    /**
91
     * Set the character to loop around.
92
     *
93
     * @param  string $characters
94
     *
95
     * @return Spinner
96
     */
97
    public function characters(...$characters)
98
    {
99
        if (count($characters) < 1) {
100
            throw new \UnexpectedValueException("You must specify the characters to use");
101
        }
102
103
        $this->characters = $characters;
0 ignored issues
show
Documentation Bug introduced by
It seems like $characters of type array<integer,string> is incompatible with the declared type string of property $characters.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
104
105
        return $this;
106
    }
107
108
109
    /**
110
     * Re-writes the spinner
111
     *
112
     * @param string $label
113
     *
114
     * @return void
115
     */
116
    public function advance($label = null)
117
    {
118
        if ($label === null) {
119
            $label = $this->label;
120
        }
121
122
        if ($this->last_drawn) {
123
            $time = microtime(true) - $this->last_drawn;
124
            if ($time < $this->time_limit) {
125
                return;
126
            }
127
        }
128
129
        ++$this->current;
130
        if ($this->current >= count($this->characters)) {
131
            $this->current = 0;
132
        }
133
134
        $characters = $this->characters[$this->current];
135
        $this->drawSpinner($characters, $label);
136
        $this->last_drawn = microtime(true);
137
    }
138
139
140
    /**
141
     * Draw the spinner
142
     *
143
     * @param string $characters
144
     * @param string $label
145
     */
146
    private function drawSpinner($characters, $label)
147
    {
148
        $spinner = "";
149
150
        if ($this->first_line) {
151
            $this->first_line = false;
152
        } else {
153
            $spinner .= $this->util->cursor->up(1);
154
            $spinner .= $this->util->cursor->startOfCurrentLine();
155
            $spinner .= $this->util->cursor->deleteCurrentLine();
156
        }
157
158
        $spinner .= trim("{$characters} {$label}");
159
160
        $this->output->write($this->parser->apply($spinner));
161
    }
162
}
163