@@ -31,8 +31,10 @@ final class ProgressBar
31
31
private $ progressChar = '> ' ;
32
32
private $ format ;
33
33
private $ internalFormat ;
34
- private $ redrawFreq ;
34
+ private $ redrawFreq = 1 ;
35
35
private $ lastWriteTime ;
36
+ private $ minSecondsBetweenRedraws = 0 ;
37
+ private $ maxSecondsBetweenRedraws = 1 ;
36
38
private $ output ;
37
39
private $ step = 0 ;
38
40
private $ max ;
@@ -244,6 +246,16 @@ public function setRedrawFrequency(int $freq)
244
246
$ this ->redrawFreq = max ($ freq , 1 );
245
247
}
246
248
249
+ public function preventRedrawFasterThan (float $ intervalInSeconds ): void
250
+ {
251
+ $ this ->minSecondsBetweenRedraws = $ intervalInSeconds ;
252
+ }
253
+
254
+ public function forceRedrawSlowerThan (float $ intervalInSeconds ): void
255
+ {
256
+ $ this ->maxSecondsBetweenRedraws = $ intervalInSeconds ;
257
+ }
258
+
247
259
/**
248
260
* Returns an iterator that will automatically update the progress bar when iterated.
249
261
*
@@ -306,22 +318,26 @@ public function setProgress(int $step)
306
318
$ step = 0 ;
307
319
}
308
320
309
- $ prevStep = $ this ->step ;
321
+ $ prevPeriod = (int ) ($ this ->step / $ this ->redrawFreq );
322
+ $ currPeriod = (int ) ($ step / $ this ->redrawFreq );
310
323
$ this ->step = $ step ;
311
324
$ this ->percent = $ this ->max ? (float ) $ this ->step / $ this ->max : 0 ;
325
+ $ timeInterval = microtime (true ) - $ this ->lastWriteTime ;
312
326
313
- if (null === $ this ->redrawFreq ) {
314
- if (microtime (true ) - $ this ->lastWriteTime >= .04 || $ this ->max === $ step ) {
315
- $ this ->display ();
316
- }
327
+ // Draw regardless of other limits
328
+ if ($ this ->max === $ step ) {
329
+ $ this ->display ();
317
330
318
331
return ;
319
332
}
320
333
321
- $ prevPeriod = (int ) ($ prevStep / $ this ->redrawFreq );
322
- $ currPeriod = (int ) ($ step / $ this ->redrawFreq );
334
+ // Throttling
335
+ if ($ timeInterval < $ this ->minSecondsBetweenRedraws ) {
336
+ return ;
337
+ }
323
338
324
- if ($ prevPeriod !== $ currPeriod || $ this ->max === $ step ) {
339
+ // Draw each step period, but not too late
340
+ if ($ prevPeriod !== $ currPeriod || $ timeInterval >= $ this ->maxSecondsBetweenRedraws ) {
325
341
$ this ->display ();
326
342
}
327
343
}
0 commit comments