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); } } }