2021-09-04 09:33:59 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
2021-09-04 12:01:03 +00:00
|
|
|
|
namespace Tapeti.Cmd.ConsoleHelper
|
2021-09-04 09:33:59 +00:00
|
|
|
|
{
|
|
|
|
|
public class ProgressBar : IDisposable, IProgress<int>
|
|
|
|
|
{
|
|
|
|
|
private static readonly TimeSpan UpdateInterval = TimeSpan.FromMilliseconds(20);
|
|
|
|
|
|
2021-09-04 12:01:03 +00:00
|
|
|
|
private readonly IConsoleWriter consoleWriter;
|
2021-09-04 09:33:59 +00:00
|
|
|
|
private readonly int max;
|
|
|
|
|
private readonly int width;
|
|
|
|
|
private readonly bool showPosition;
|
|
|
|
|
private int position;
|
|
|
|
|
|
|
|
|
|
private readonly bool enabled;
|
|
|
|
|
private DateTime lastUpdate = DateTime.MinValue;
|
|
|
|
|
|
|
|
|
|
|
2021-09-04 12:01:03 +00:00
|
|
|
|
public ProgressBar(IConsole console, int max, int width = 10, bool showPosition = true)
|
2021-09-04 09:33:59 +00:00
|
|
|
|
{
|
|
|
|
|
if (width <= 0)
|
|
|
|
|
throw new ArgumentOutOfRangeException(nameof(width), "Width must be greater than zero");
|
|
|
|
|
|
|
|
|
|
if (max <= 0)
|
|
|
|
|
throw new ArgumentOutOfRangeException(nameof(max), "Max must be greater than zero");
|
2021-09-04 12:01:03 +00:00
|
|
|
|
|
|
|
|
|
consoleWriter = console.GetTemporaryWriter();
|
|
|
|
|
|
2021-09-04 09:33:59 +00:00
|
|
|
|
this.max = max;
|
|
|
|
|
this.width = width;
|
|
|
|
|
this.showPosition = showPosition;
|
|
|
|
|
|
2021-09-04 12:01:03 +00:00
|
|
|
|
enabled = consoleWriter.Enabled;
|
2021-09-04 09:33:59 +00:00
|
|
|
|
if (!enabled)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Redraw();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
2021-09-04 12:01:03 +00:00
|
|
|
|
consoleWriter.Dispose();
|
2021-09-04 09:33:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Report(int value)
|
|
|
|
|
{
|
|
|
|
|
if (!enabled)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
value = Math.Max(0, Math.Min(max, value));
|
|
|
|
|
position = value;
|
|
|
|
|
|
|
|
|
|
var now = DateTime.Now;
|
|
|
|
|
if (now - lastUpdate < UpdateInterval)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
lastUpdate = now;
|
|
|
|
|
Redraw();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void Redraw()
|
|
|
|
|
{
|
|
|
|
|
var output = new StringBuilder("[");
|
|
|
|
|
|
|
|
|
|
var blockCount = (int)Math.Truncate((decimal)position / max * width);
|
|
|
|
|
if (blockCount > 0)
|
|
|
|
|
output.Append(new string('#', blockCount));
|
|
|
|
|
|
|
|
|
|
if (blockCount < width)
|
|
|
|
|
output.Append(new string('.', width - blockCount));
|
|
|
|
|
|
|
|
|
|
output.Append("] ");
|
|
|
|
|
|
|
|
|
|
if (showPosition)
|
|
|
|
|
{
|
|
|
|
|
output
|
|
|
|
|
.Append(position.ToString("N0")).Append(" / ").Append(max.ToString("N0"))
|
|
|
|
|
.Append(" (").Append((int) Math.Truncate((decimal) position / max * 100)).Append("%)");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
output.Append(" ").Append((int)Math.Truncate((decimal)position / max * 100)).Append("%");
|
|
|
|
|
|
2021-09-04 12:01:03 +00:00
|
|
|
|
consoleWriter.WriteLine(output.ToString());
|
2021-09-04 09:33:59 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|