I've been building an IDE using C# and only the console. To get keyboard input in real time (as opposed to a read–eval–print loop,) I have the following method to get keyboard input:
public static ConsoleKeyInfo[] GetInput()
{
// A list of characters
List<ConsoleKeyInfo> input = new List<ConsoleKeyInfo>();
// Loop while keys are available or we hit 10 keys
for (int i = 0; Console.KeyAvailable && i < 10; i++)
{
// Read a key (preventing it from being printed)
// and put it in the key list (if it's not in there yet)
ConsoleKeyInfo info = Console.ReadKey(true);
if (!input.Contains(info))
{
input.Add(info);
}
}
// Use up any remaining key presses
while (Console.KeyAvailable)
{
// Read a single key
Console.ReadKey(true);
}
// Convert the list to an array and return
return input.ToArray();
}
GetInput called once at the start of the main loop and the result is passed into objects that handle key presses:
ConsoleKeyInfo[] keysHit = ConEx.ConEx_Input.GetInput();
Program.Interpreter.Update(Program.Interpreter.CurMode, keysHit);
Program.WindowUI.Update(Program.Interpreter.CurMode, keysHit);
Program.WindowSideBar.Update(Program.Interpreter.CurMode, keysHit);
Inside an Update method:
for (int i = 0; i < keysHit.Length; i++)
{
switch (keysHit[i].Key)
{
//Cycle through the pages
case ConsoleKey.Home:
//Do some stuff
break;
case ConsoleKey.End:
//Do other stuff
break;
}
}
Is this a sub optimal solution for getting keyboard input? I'm very willing to breakout P/Invoke or a threaded solution if need be. I can't support an event handler based solution due to the tight control of sequence needed.
Edit: Nikita B's answer is marked as Accepted because it reduced the amount of ticks taken from ~60 to ~30. Thanks!