102 lines
2.2 KiB
C#
102 lines
2.2 KiB
C#
using System;
|
|
using System.Threading;
|
|
|
|
// Wrapper class for the console allowing concurrent read and write operations
|
|
public class Terminal
|
|
{
|
|
private Object TerminalLock = new Object ();
|
|
private Object ReadLineLock = new Object ();
|
|
private AutoResetEvent ResetEvent = new AutoResetEvent (false);
|
|
private String InputBuffer = "";
|
|
private bool AcceptInput = false;
|
|
private int OutLinePos;
|
|
private Thread catchInputThread;
|
|
|
|
public Terminal ()
|
|
{
|
|
OutLinePos = Console.CursorTop;
|
|
catchInputThread = new Thread (new ThreadStart (this.CatchInput));
|
|
catchInputThread.Start ();
|
|
}
|
|
|
|
private void CatchInput ()
|
|
{
|
|
while (true) {
|
|
ConsoleKeyInfo key = Console.ReadKey (false);
|
|
lock (TerminalLock) {
|
|
if (!AcceptInput) {
|
|
Console.CursorLeft--;
|
|
Console.Write (" ");
|
|
Console.CursorLeft--;
|
|
continue;
|
|
}
|
|
if (key.Key == ConsoleKey.Backspace) {
|
|
if (InputBuffer.Length == 0)
|
|
continue;
|
|
InputBuffer = InputBuffer.Substring (0, InputBuffer.Length - 1);
|
|
ClearInputLine ();
|
|
Console.Write (InputBuffer);
|
|
} else if (key.Key == ConsoleKey.Enter) {
|
|
AcceptInput = false;
|
|
ResetEvent.Set ();
|
|
OutLinePos = Console.CursorTop;
|
|
} else {
|
|
InputBuffer += key.KeyChar;
|
|
ClearInputLine ();
|
|
Console.Write (InputBuffer);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void PrintLine (String s)
|
|
{
|
|
lock (TerminalLock) {
|
|
ClearInputLine ();
|
|
Console.WriteLine (s);
|
|
OutLinePos = Console.CursorTop;
|
|
Console.Write (InputBuffer);
|
|
}
|
|
}
|
|
|
|
public String ReadLine ()
|
|
{
|
|
lock (ReadLineLock) {
|
|
try {
|
|
String result;
|
|
AcceptInput = true;
|
|
ResetEvent.WaitOne ();
|
|
result = InputBuffer;
|
|
InputBuffer = "";
|
|
return result;
|
|
} catch (ThreadAbortException e) {
|
|
lock (TerminalLock) {
|
|
AcceptInput = false;
|
|
InputBuffer = "";
|
|
ClearInputLine ();
|
|
}
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ClearInputLine ()
|
|
{
|
|
lock (TerminalLock) {
|
|
int top = Console.CursorTop;
|
|
int left = Console.CursorLeft;
|
|
Console.SetCursorPosition (0, OutLinePos);
|
|
while (left != Console.CursorLeft || top != Console.CursorTop) {
|
|
Console.Write (" ");
|
|
}
|
|
Console.SetCursorPosition (0, OutLinePos);
|
|
}
|
|
}
|
|
|
|
public void Close ()
|
|
{
|
|
catchInputThread.Abort();
|
|
}
|
|
}
|
|
|