mirror of
				https://github.com/nsnail/spectre.console.git
				synced 2025-11-04 10:35:27 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			93 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			93 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.Threading;
 | 
						|
using System.Threading.Tasks;
 | 
						|
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 bool IsKeyAvailable()
 | 
						|
        {
 | 
						|
            return _input.Count > 0;
 | 
						|
        }
 | 
						|
 | 
						|
        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;
 | 
						|
        }
 | 
						|
 | 
						|
        public Task<ConsoleKeyInfo?> ReadKeyAsync(bool intercept, CancellationToken cancellationToken)
 | 
						|
        {
 | 
						|
            return Task.FromResult(ReadKey(intercept));
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |