using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Spectre.Console.Internal;
using Spectre.Console.Rendering;
namespace Spectre.Console
{
///
/// Represents a task list.
///
public sealed class Progress
{
private readonly IAnsiConsole _console;
///
/// Gets or sets a value indicating whether or not task list should auto refresh.
/// Defaults to true.
///
public bool AutoRefresh { get; set; } = true;
///
/// Gets or sets a value indicating whether or not the task list should
/// be cleared once it completes.
/// Defaults to false.
///
public bool AutoClear { get; set; }
internal List Columns { get; }
///
/// Initializes a new instance of the class.
///
/// The console to render to.
public Progress(IAnsiConsole console)
{
_console = console ?? throw new ArgumentNullException(nameof(console));
// Initialize with default columns
Columns = new List
{
new TaskDescriptionColumn(),
new ProgressBarColumn(),
new PercentageColumn(),
};
}
///
/// Starts the progress task list.
///
/// The action to execute.
public void Start(Action action)
{
var task = StartAsync(ctx =>
{
action(ctx);
return Task.CompletedTask;
});
task.GetAwaiter().GetResult();
}
///
/// Starts the progress task list.
///
/// The action to execute.
/// A representing the asynchronous operation.
public async Task StartAsync(Func action)
{
if (action is null)
{
throw new ArgumentNullException(nameof(action));
}
var renderer = CreateRenderer();
renderer.Started();
try
{
using (new RenderHookScope(_console, renderer))
{
var context = new ProgressContext(_console, renderer);
if (AutoRefresh)
{
using (var thread = new ProgressRefreshThread(context, renderer.RefreshRate))
{
await action(context).ConfigureAwait(false);
}
}
else
{
await action(context).ConfigureAwait(false);
}
context.Refresh();
}
}
finally
{
renderer.Completed(AutoClear);
}
}
private ProgressRenderer CreateRenderer()
{
var caps = _console.Capabilities;
var interactive = caps.SupportsInteraction && caps.SupportsAnsi;
if (interactive)
{
var columns = new List(Columns);
return new InteractiveProgressRenderer(_console, columns);
}
else
{
return new NonInteractiveProgressRenderer();
}
}
}
}