Timer::start()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 2
eloc 5
nc 2
nop 1
1
<?php
2
namespace Bedd\Timer;
3
4
/**
5
 * Timer
6
 *
7
 * Inspired by https://github.com/jsanc623/PHPBenchTime
8
 */
9
class Timer
10
{
11
    /**
12
     * Status: initialized
13
     *
14
     * @var int
15
     */
16
    const STATUS_INITIALIZED = 0;
17
18
    /**
19
     * Status: running
20
     *
21
     * @var int
22
     */
23
    const STATUS_RUNNING = 1;
24
25
    /**
26
     * Status: paused
27
     *
28
     * @var int
29
     */
30
    const STATUS_PAUSED = 2;
31
32
    /**
33
     * Status: ended
34
     *
35
     * @var int
36
     */
37
    const STATUS_ENDED = 3;
38
39
    /**
40
     * Status
41
     *
42
     * @var int
43
     */
44
    protected $status = null;
45
46
    /**
47
     * Starttime
48
     *
49
     * @var float
50
     */
51
    private $startTime = 0.0;
52
53
    /**
54
     * Endtime
55
     *
56
     * @var float
57
     */
58
    private $endTime = 0.0;
59
60
    /**
61
     * Paused time
62
     *
63
     * @var float
64
     */
65
    private $pauseTime = 0.0;
66
67
    /**
68
     * Total pause time
69
     *
70
     * @var float
71
     */
72
    private $totalPauseTime = 0.0;
73
74
    /**
75
     * List of laps
76
     *
77
     * @var array
78
     */
79
    private $laps = [];
80
81
    /**
82
     * List of Timer
83
     *
84
     * @var Timer[]
85
     */
86
    private static $timers = [];
87
88
    /**
89
     * constructor
90
     */
91
    public function __construct()
92
    {
93
        $this->reset();
94
    }
95
96
    /**
97
     * Creates and/or return a Timer instance
98
     *
99
     * @param string $name
100
     *
101
     * @throws \InvalidArgumentException
102
     *
103
     * @return Timer
104
     */
105
    public static function getInstance($name)
106
    {
107
        if (!is_string($name)) {
108
            throw new \InvalidArgumentException('$name should be a string. a '.gettype($name).' is given.');
109
        }
110
        if (!isset(self::$timers[$name])) {
111
            self::$timers[$name] = new self();
112
        }
113
        return self::$timers[$name];
114
    }
115
116
    /**
117
     * Starts the timer
118
     *
119
     * @param string $name
120
     *
121
     * @throws \LogicException
122
     */
123
    public function start($name = 'start')
124
    {
125
        if ($this->getStatus() !== self::STATUS_INITIALIZED) {
126
            throw new \LogicException('Only initialied timmers could start. The actually status is '.$this->getStatus());
127
        }
128
        $this->startTime = $this->getCurrentTime();
129
        $this->addLap($name);
130
    }
131
132
    /**
133
     * Ends the timer
134
     *
135
     * @throws \LogicException
136
     */
137
    public function end()
138
    {
139
        if ($this->getStatus() !== self::STATUS_RUNNING) {
140
            throw new \LogicException('Only running timmers could end. The actually status is '.$this->getStatus());
141
        }
142
        $this->endTime = $this->getCurrentTime();
143
        $this->status = self::STATUS_ENDED;
144
        $this->endLap();
145
    }
146
147
    /**
148
     * Starts a new lap
149
     *
150
     * @param string $name Name of the lap
151
     */
152
    public function addLap($name = null)
153
    {
154
        $this->endLap();
155
        $this->status = self::STATUS_RUNNING;
156
        $this->laps[] = [
157
            'name' => $name ? $name : count($this->laps) + 1,
158
            'start' => $this->getCurrentTime(),
159
            'end' => -1,
160
            'total' => -1,
161
        ];
162
    }
163
164
    /**
165
     * Ends a lap
166
     */
167
    protected function endLap()
168
    {
169
        if (empty($this->laps)) {
170
            return;
171
        }
172
        $lapIndex = count($this->laps) - 1;
173
        $this->laps[$lapIndex]['end'] = $this->getCurrentTime();
174
        $this->laps[$lapIndex]['total'] = $this->laps[$lapIndex]['end'] - $this->laps[$lapIndex]['start'];
175
    }
176
177
    /**
178
     * Reset the Timer
179
     */
180
    public function reset()
181
    {
182
        $this->status = self::STATUS_INITIALIZED;
183
        $this->startTime = 0.0;
184
        $this->endTime = 0.0;
185
        $this->pauseTime = 0.0;
186
        $this->totalPauseTime = 0.0;
187
        $this->laps = [];
188
    }
189
190
    /**
191
     * Returns the summary
192
     *
193
     * @return array
194
     */
195
    public function getSummary()
196
    {
197
        return [
198
            'status' => $this->getStatus(),
199
            'start' => $this->startTime,
200
            'end' => $this->endTime,
201
            'total' => $this->endTime - $this->startTime,
202
            'paused' => $this->totalPauseTime,
203
            'laps' => $this->laps,
204
        ];
205
    }
206
207
    /**
208
     * Pause the Timer
209
     *
210
     * @throws \LogicException
211
     */
212
    public function pause()
213
    {
214
        if ($this->getStatus() !== self::STATUS_RUNNING) {
215
            throw new \LogicException('Only running timmers could end. The actually status is '.$this->getStatus());
216
        }
217
        $this->status = self::STATUS_PAUSED;
218
        $this->pauseTime = $this->getCurrentTime();
219
    }
220
221
    /**
222
     * Unpause the Timer
223
     *
224
     * @throws \LogicException
225
     */
226
    public function unpause()
227
    {
228
        if ($this->getStatus() !== self::STATUS_PAUSED) {
229
            throw new \LogicException('Only paused timmers could unpaused. The actually status is '.$this->getStatus());
230
        }
231
        $this->status = self::STATUS_RUNNING;
232
        $this->totalPauseTime = $this->getCurrentTime() - $this->pauseTime;
233
        $this->pauseTime = 0.0;
234
    }
235
236
    /**
237
     * Returns the current time
238
     *
239
     * @return float
240
     */
241
    private function getCurrentTime()
242
    {
243
        return microtime(true);
244
    }
245
246
    /**
247
     * Returns the status
248
     *
249
     * @return int
250
     */
251
    public function getStatus()
252
    {
253
        return $this->status;
254
    }
255
}
256