Advertisement
HotausTV

Untitled

Apr 22nd, 2018
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.03 KB | None | 0 0
  1. using System;
  2. using System.Text;
  3. using System.Threading;
  4.  
  5. /// <summary>
  6. /// An ASCII progress bar
  7. /// </summary>
  8. public class ProgressBar : IDisposable, IProgress<double>
  9. {
  10.     private const int blockCount = 10;
  11.     private readonly TimeSpan animationInterval = TimeSpan.FromSeconds(1.0 / 8);
  12.     private const string animation = @"|/-\";
  13.  
  14.     private readonly Timer timer;
  15.  
  16.     private double currentProgress = 0;
  17.     private string currentText = string.Empty;
  18.     private bool disposed = false;
  19.     private int animationIndex = 0;
  20.  
  21.     public ProgressBar()
  22.     {
  23.         timer = new Timer(TimerHandler);
  24.  
  25.         // A progress bar is only for temporary display in a console window.
  26.         // If the console output is redirected to a file, draw nothing.
  27.         // Otherwise, we'll end up with a lot of garbage in the target file.
  28.         if (!Console.IsOutputRedirected)
  29.         {
  30.             ResetTimer();
  31.         }
  32.     }
  33.  
  34.     public void Report(double value)
  35.     {
  36.         // Make sure value is in [0..1] range
  37.         value = Math.Max(0, Math.Min(1, value));
  38.         Interlocked.Exchange(ref currentProgress, value);
  39.     }
  40.  
  41.     private void TimerHandler(object state)
  42.     {
  43.         lock (timer)
  44.         {
  45.             if (disposed) return;
  46.  
  47.             int progressBlockCount = (int)(currentProgress * blockCount);
  48.             int percent = (int)(currentProgress * 100);
  49.             string text = string.Format("[{0}{1}] {2,3}% {3}",
  50.                 new string('#', progressBlockCount), new string('-', blockCount - progressBlockCount),
  51.                 percent,
  52.                 animation[animationIndex++ % animation.Length]);
  53.             UpdateText(text);
  54.  
  55.             ResetTimer();
  56.         }
  57.     }
  58.  
  59.     private void UpdateText(string text)
  60.     {
  61.         // Get length of common portion
  62.         int commonPrefixLength = 0;
  63.         int commonLength = Math.Min(currentText.Length, text.Length);
  64.         while (commonPrefixLength < commonLength && text[commonPrefixLength] == currentText[commonPrefixLength])
  65.         {
  66.             commonPrefixLength++;
  67.         }
  68.  
  69.         // Backtrack to the first differing character
  70.         StringBuilder outputBuilder = new StringBuilder();
  71.         outputBuilder.Append('\b', currentText.Length - commonPrefixLength);
  72.  
  73.         // Output new suffix
  74.         outputBuilder.Append(text.Substring(commonPrefixLength));
  75.  
  76.         // If the new text is shorter than the old one: delete overlapping characters
  77.         int overlapCount = currentText.Length - text.Length;
  78.         if (overlapCount > 0)
  79.         {
  80.             outputBuilder.Append(' ', overlapCount);
  81.             outputBuilder.Append('\b', overlapCount);
  82.         }
  83.  
  84.         Console.Write(outputBuilder);
  85.         currentText = text;
  86.     }
  87.  
  88.     private void ResetTimer()
  89.     {
  90.         timer.Change(animationInterval, TimeSpan.FromMilliseconds(-1));
  91.     }
  92.  
  93.     public void Dispose()
  94.     {
  95.         lock (timer)
  96.         {
  97.             disposed = true;
  98.             UpdateText(string.Empty);
  99.         }
  100.     }
  101.  
  102. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement