namespace Terminal.Gui.App;
///
/// Timeout which accelerates slowly at first then fast up to a maximum speed.
/// Use to increment the stage of the timer (e.g. in
/// your timer callback code).
///
public class SmoothAcceleratingTimeout : Timeout
{
///
/// Creates a new instance of the smooth acceleration timeout.
///
/// Delay before first tick, the longest it will ever take
/// The fastest the timer can get no matter how long it runs
/// Controls how fast the timer accelerates
/// Method to call when timer ticks
public SmoothAcceleratingTimeout (TimeSpan initialDelay, TimeSpan minDelay, double decayFactor, Func callback)
{
_initialDelay = initialDelay;
_minDelay = minDelay;
_decayFactor = decayFactor;
Callback = callback;
}
private readonly TimeSpan _initialDelay;
private readonly TimeSpan _minDelay;
private readonly double _decayFactor;
private int _stage;
///
/// Advances the timer stage, this should be called from your timer callback or whenever
/// you want to advance the speed.
///
public void AdvanceStage () { _stage++; }
///
/// Resets the timer to original speed.
///
public void Reset () { _stage = 0; }
///
public override TimeSpan Span
{
get
{
double initialMs = _initialDelay.TotalMilliseconds;
double minMs = _minDelay.TotalMilliseconds;
double delayMs = minMs + (initialMs - minMs) * Math.Pow (_decayFactor, _stage);
return TimeSpan.FromMilliseconds (delayMs);
}
}
}