recrownedgtk/RecrownedGTK.Tools/CommandProcessor/CommandEngine.cs

102 lines
3.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
namespace RecrownedGTK.Tools.CommandProcessor
{
public class CommandEngine
{
public bool running = true;
public readonly List<EngineCommand> commands;
public CommandEngine()
{
commands = new List<EngineCommand>();
}
public void Run(IUserInput input, IUserOutput output)
{
while (running)
{
output.WriteLine("Awaiting command.");
string command = input.GetInput();
Process(input, output, command);
}
}
public void Process(IUserInput userInput, IUserOutput userOutput, string commandAndArguments)
{
if (userInput == null || userOutput == null || commandAndArguments == null) {
throw new ArgumentNullException("No arguments should be null.");
}
string command = commandAndArguments;
string[] arguments = null;
if (!ContainsCommand(command)) {
userOutput.Write("Unable to find command. Type \"help\" for more information.");
return;
}
if (commandAndArguments.Contains(" "))
{
command = command.Remove(command.IndexOf(' '));
string[] argumentsSplit = commandAndArguments.Substring(command.Length + 1).Split(' ');
List<string> argumentsList = new List<string>();
for (int i = 0; i < argumentsSplit.Length; i++)
{
if (argumentsSplit[i].Contains("\"") && !argumentsSplit[i].EndsWith("\""))
{
StringBuilder quoteBuilder = new StringBuilder();
do
{
quoteBuilder.Append(' ');
quoteBuilder.Append(argumentsSplit[i]);
i++;
if (i >= argumentsSplit.Length)
{
userOutput.Write("Argument is missing terminating \'\"\'");
}
} while (!argumentsSplit[i].Contains("\""));
quoteBuilder.Append(" ");
quoteBuilder.Append(argumentsSplit[i]);
argumentsList.Add(quoteBuilder.ToString().Replace("\"", "").Trim());
}
else
{
argumentsList.Add(argumentsSplit[i]);
}
}
arguments = argumentsList.ToArray();
}
if (!GetCommand(command).Run(userInput, userOutput, arguments)) {
userOutput.Write("Command {0} was not used correctly. Please refer to \"help\" for more information.");
}
}
/// <summary>
/// Check if the command exists using it's invokes string.
/// </summary>
/// <param name="command">A string that will invoke the command.</param>
/// <returns>Returns true if the given invoke string exists as a command and false if command parameter is null.</returns>
public bool ContainsCommand(string command)
{
if (command == null) return false;
for (int i = 0; i < commands.Count; i++)
{
if (commands[i].IsInvoked(command)) return true;
}
return false;
}
public EngineCommand GetCommand(string command)
{
for (int i = 0; i < commands.Count; i++)
{
if (commands[i].IsInvoked(command)) return commands[i];
}
return null;
}
}
}