Index: utils/ofhttp/ProgressBar.h ================================================================== --- utils/ofhttp/ProgressBar.h +++ utils/ofhttp/ProgressBar.h @@ -17,23 +17,27 @@ #import "OFObject.h" @class OFDate; @class OFTimer; + +#define BPS_WINDOW_SIZE 10 @interface ProgressBar: OFObject { intmax_t _received, _lastReceived, _length, _resumedFrom; OFDate *_startDate, *_lastReceivedDate; OFTimer *_drawTimer, *_BPSTimer; bool _stopped; float _BPS; double _ETA; + float _BPSWindow[BPS_WINDOW_SIZE]; + size_t _BPSWindowIndex, _BPSWindowLength; } - (instancetype)initWithLength: (intmax_t)length resumedFrom: (intmax_t)resumedFrom; - (void)setReceived: (intmax_t)received; - (void)draw; - (void)calculateBPSAndETA; - (void)stop; @end Index: utils/ofhttp/ProgressBar.m ================================================================== --- utils/ofhttp/ProgressBar.m +++ utils/ofhttp/ProgressBar.m @@ -254,12 +254,22 @@ [self _drawReceived]; } - (void)calculateBPSAndETA { - _BPS = (float)(_received - _lastReceived) / + _BPSWindow[_BPSWindowIndex++ % BPS_WINDOW_SIZE] = + (float)(_received - _lastReceived) / -(float)_lastReceivedDate.timeIntervalSinceNow; + + if (_BPSWindowLength < BPS_WINDOW_SIZE) + _BPSWindowLength++; + + _BPS = 0; + for (size_t i = 0; i < _BPSWindowLength; i++) + _BPS += _BPSWindow[i]; + _BPS /= _BPSWindowLength; + _ETA = (double)(_length - _received) / _BPS; _lastReceived = _received; [_lastReceivedDate release]; _lastReceivedDate = [[OFDate alloc] init];