Patrik Svensson 450d87f5d3 Add support for fake input in asciicast recordings
* Fixes a bug with `SelectionPrompt` and page size.
* Allow `IAnsiConsoleInput` to return `null`.
2021-05-23 22:22:44 -04:00

82 lines
2.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading;
using Spectre.Console;
namespace Generator.Commands
{
public sealed class AsciiCastInput : IAnsiConsoleInput
{
private readonly Queue<(ConsoleKeyInfo?, int)> _input;
private readonly Random _random = new Random();
public AsciiCastInput()
{
_input = new Queue<(ConsoleKeyInfo?, int)>();
}
public void PushText(string input, int keypressDelayMs)
{
if (input is null)
{
throw new ArgumentNullException(nameof(input));
}
foreach (var character in input)
{
PushCharacter(character, keypressDelayMs);
}
}
public void PushTextWithEnter(string input, int keypressDelayMs)
{
PushText(input, keypressDelayMs);
PushKey(ConsoleKey.Enter, keypressDelayMs);
}
public void PushCharacter(char input, int keypressDelayMs)
{
var delay = keypressDelayMs + _random.Next((int)(keypressDelayMs * -.2), (int)(keypressDelayMs * .2));
switch (input)
{
case '↑':
PushKey(ConsoleKey.UpArrow, keypressDelayMs);
break;
case '↓':
PushKey(ConsoleKey.DownArrow, keypressDelayMs);
break;
case '↲':
PushKey(ConsoleKey.Enter, keypressDelayMs);
break;
case '¦':
_input.Enqueue((null, delay));
break;
default:
var control = char.IsUpper(input);
_input.Enqueue((new ConsoleKeyInfo(input, (ConsoleKey)input, false, false, control), delay));
break;
}
}
public void PushKey(ConsoleKey input, int keypressDelayMs)
{
var delay = keypressDelayMs + _random.Next((int)(keypressDelayMs * -.2), (int)(keypressDelayMs * .2));
_input.Enqueue((new ConsoleKeyInfo((char)input, input, false, false, false), delay));
}
public ConsoleKeyInfo? ReadKey(bool intercept)
{
if (_input.Count == 0)
{
throw new InvalidOperationException("No input available.");
}
var result = _input.Dequeue();
Thread.Sleep(result.Item2);
return result.Item1;
}
}
}