mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-06-19 13:28:16 +08:00
Add support for exclusive mode
This commit is contained in:

committed by
Phil Scott

parent
c2bab0ebf8
commit
7f6f2437b1
@ -13,9 +13,10 @@ namespace Spectre.Console
|
||||
public Profile Profile { get; }
|
||||
public IAnsiConsoleCursor Cursor => GetBackend().Cursor;
|
||||
public IAnsiConsoleInput Input { get; }
|
||||
public IExclusivityMode ExclusivityMode { get; }
|
||||
public RenderPipeline Pipeline { get; }
|
||||
|
||||
public AnsiConsoleFacade(Profile profile)
|
||||
public AnsiConsoleFacade(Profile profile, IExclusivityMode exclusivityMode)
|
||||
{
|
||||
_renderLock = new object();
|
||||
_ansiBackend = new AnsiConsoleBackend(profile);
|
||||
@ -23,6 +24,7 @@ namespace Spectre.Console
|
||||
|
||||
Profile = profile ?? throw new ArgumentNullException(nameof(profile));
|
||||
Input = new DefaultInput(Profile);
|
||||
ExclusivityMode = exclusivityMode ?? throw new ArgumentNullException(nameof(exclusivityMode));
|
||||
Pipeline = new RenderPipeline();
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
using System.Linq;
|
||||
using Spectre.Console.Rendering;
|
||||
using Wcwidth;
|
||||
|
||||
|
57
src/Spectre.Console/Internal/DefaultExclusivityMode.cs
Normal file
57
src/Spectre.Console/Internal/DefaultExclusivityMode.cs
Normal file
@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spectre.Console.Internal
|
||||
{
|
||||
internal sealed class DefaultExclusivityMode : IExclusivityMode
|
||||
{
|
||||
private static readonly SemaphoreSlim _semaphore;
|
||||
|
||||
static DefaultExclusivityMode()
|
||||
{
|
||||
_semaphore = new SemaphoreSlim(1, 1);
|
||||
}
|
||||
|
||||
public T Run<T>(Func<T> func)
|
||||
{
|
||||
// Try aquiring the exclusivity semaphore
|
||||
if (!_semaphore.Wait(0))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Trying to run one or more interactive functions concurrently. " +
|
||||
"Operations with dynamic displays (e.g. a prompt and a progress display) " +
|
||||
"cannot be running at the same time.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return func();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_semaphore.Release(1);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<T> Run<T>(Func<Task<T>> func)
|
||||
{
|
||||
// Try aquiring the exclusivity semaphore
|
||||
if (!await _semaphore.WaitAsync(0).ConfigureAwait(false))
|
||||
{
|
||||
// TODO: Need a better message here
|
||||
throw new InvalidOperationException(
|
||||
"Could not aquire the interactive semaphore");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return await func();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_semaphore.Release(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user