SmoothAcceleratingTimeout.cs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. #nullable disable
  2. namespace Terminal.Gui.App;
  3. /// <summary>
  4. /// Timeout which accelerates slowly at first then fast up to a maximum speed.
  5. /// Use <see cref="AdvanceStage"/> to increment the stage of the timer (e.g. in
  6. /// your timer callback code).
  7. /// </summary>
  8. public class SmoothAcceleratingTimeout : Timeout
  9. {
  10. /// <summary>
  11. /// Creates a new instance of the smooth acceleration timeout.
  12. /// </summary>
  13. /// <param name="initialDelay">Delay before first tick, the longest it will ever take</param>
  14. /// <param name="minDelay">The fastest the timer can get no matter how long it runs</param>
  15. /// <param name="decayFactor">Controls how fast the timer accelerates</param>
  16. /// <param name="callback">Method to call when timer ticks</param>
  17. public SmoothAcceleratingTimeout (TimeSpan initialDelay, TimeSpan minDelay, double decayFactor, Func<bool> callback)
  18. {
  19. _initialDelay = initialDelay;
  20. _minDelay = minDelay;
  21. _decayFactor = decayFactor;
  22. Callback = callback;
  23. }
  24. private readonly TimeSpan _initialDelay;
  25. private readonly TimeSpan _minDelay;
  26. private readonly double _decayFactor;
  27. private int _stage;
  28. /// <summary>
  29. /// Advances the timer stage, this should be called from your timer callback or whenever
  30. /// you want to advance the speed.
  31. /// </summary>
  32. public void AdvanceStage () { _stage++; }
  33. /// <summary>
  34. /// Resets the timer to original speed.
  35. /// </summary>
  36. public void Reset () { _stage = 0; }
  37. /// <inheritdoc/>
  38. public override TimeSpan Span
  39. {
  40. get
  41. {
  42. double initialMs = _initialDelay.TotalMilliseconds;
  43. double minMs = _minDelay.TotalMilliseconds;
  44. double delayMs = minMs + (initialMs - minMs) * Math.Pow (_decayFactor, _stage);
  45. return TimeSpan.FromMilliseconds (delayMs);
  46. }
  47. }
  48. }