Restructed project in preparation for unit testing.
This commit is contained in:
@@ -1,97 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace RecrownedGTK.Tools.CommandProcessor
|
||||
{
|
||||
internal class CommandEngine
|
||||
{
|
||||
public bool running = true;
|
||||
public readonly List<EngineCommand> commands;
|
||||
|
||||
public CommandEngine()
|
||||
{
|
||||
commands = new List<EngineCommand>();
|
||||
}
|
||||
|
||||
internal void Run()
|
||||
{
|
||||
while (running)
|
||||
{
|
||||
ConsoleUtilities.WriteWrappedLine("\nAwaiting command.");
|
||||
string command = Console.ReadLine();
|
||||
try
|
||||
{
|
||||
Process(command);
|
||||
|
||||
}
|
||||
catch (ArgumentException ae)
|
||||
{
|
||||
ConsoleUtilities.WriteWrappedLine("Error: " + ae.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Process(string commandAndArguments)
|
||||
{
|
||||
string command = commandAndArguments;
|
||||
string[] arguments = null;
|
||||
|
||||
if (commandAndArguments.Contains(' '))
|
||||
{
|
||||
command = command.Remove(command.IndexOf(' '));
|
||||
if (!ContainsCommand(command)) throw new ArgumentException("Command not found.");
|
||||
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)
|
||||
{
|
||||
throw new ArgumentException("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 (!ContainsCommand(command)) throw new ArgumentException("Command not found. Type \"help\" for a list of commands.");
|
||||
GetCommand(command).Run(arguments);
|
||||
}
|
||||
|
||||
public bool ContainsCommand(string command)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace RecrownedGTK.Tools.CommandProcessor.Commands
|
||||
{
|
||||
internal class ClearConsoleCommand : EngineCommand
|
||||
{
|
||||
public ClearConsoleCommand() : base("clear")
|
||||
{
|
||||
help = "Clears the console.";
|
||||
}
|
||||
|
||||
public override void Run(string[] arguments = null)
|
||||
{
|
||||
Console.Clear();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace RecrownedGTK.Tools.CommandProcessor.Commands
|
||||
{
|
||||
internal class HelpCommand : EngineCommand
|
||||
{
|
||||
CommandEngine commandEngine;
|
||||
|
||||
public HelpCommand(CommandEngine commandEngine) : base("help")
|
||||
{
|
||||
this.commandEngine = commandEngine;
|
||||
help = "help [command] [arg]";
|
||||
}
|
||||
|
||||
|
||||
public override void Run(string[] arguments)
|
||||
{
|
||||
if (arguments != null)
|
||||
{
|
||||
if (commandEngine.ContainsCommand(arguments[0]))
|
||||
{
|
||||
if (arguments.Length < 2) ConsoleUtilities.WriteWrappedLine(commandEngine.GetCommand(arguments[0]).Help(null));
|
||||
for (int i = 1; i < arguments.Length; i++)
|
||||
{
|
||||
ConsoleUtilities.WriteWrappedLine(commandEngine.GetCommand(arguments[0]).Help(arguments[i]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException(arguments[0] + " not a command. Type \"help\" for a list of commands.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleUtilities.WriteWrappedLine("Tools for RecrownedGTK library. Possible commands are as follows:\n");
|
||||
foreach (EngineCommand engineCommand in commandEngine.commands)
|
||||
{
|
||||
for (int i = 0; i < engineCommand.InvokeStrings.Length; i++)
|
||||
{
|
||||
ConsoleUtilities.WriteWrapped(engineCommand.InvokeStrings[i]);
|
||||
if (i + 1 < engineCommand.InvokeStrings.Length)
|
||||
{
|
||||
ConsoleUtilities.WriteWrapped(", ");
|
||||
}
|
||||
}
|
||||
ConsoleUtilities.WriteWrapped(" : ");
|
||||
ConsoleUtilities.WriteWrapped(engineCommand.Help().Replace("\n", "\n\t"), true);
|
||||
Console.WriteLine("--------");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
namespace RecrownedGTK.Tools.CommandProcessor.Commands
|
||||
{
|
||||
internal class StopCommand : EngineCommand
|
||||
{
|
||||
CommandEngine commandEngine;
|
||||
|
||||
public StopCommand(CommandEngine commandEngine) : base("quit", "stop", "q", "exit")
|
||||
{
|
||||
this.commandEngine = commandEngine;
|
||||
help = "Exits the tool.";
|
||||
}
|
||||
|
||||
public override void Run(string[] arguments = null)
|
||||
{
|
||||
commandEngine.running = false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,183 +0,0 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace RecrownedGTK.Tools.CommandProcessor
|
||||
{
|
||||
public abstract class EngineCommand
|
||||
{
|
||||
|
||||
bool caseSensitiveName = false;
|
||||
|
||||
/// <summary>
|
||||
/// the words a user can type that will invoke this command.
|
||||
/// </summary>
|
||||
protected string[] invokeStrings;
|
||||
public string[] InvokeStrings { get { return invokeStrings; } }
|
||||
|
||||
/// <summary>
|
||||
/// Arguments that this command should accept and take into account.
|
||||
/// </summary>
|
||||
protected EngineCommandArgument[] commandArguments;
|
||||
protected string help;
|
||||
|
||||
public EngineCommand(params string[] invokeStrings)
|
||||
{
|
||||
this.invokeStrings = invokeStrings ?? throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not this command should be invoked given the string.
|
||||
/// </summary>
|
||||
/// <param name="command">The string that acts as the command.</param>
|
||||
/// <returns>whether or not this command is invoked.</returns>
|
||||
public bool IsInvoked(string command)
|
||||
{
|
||||
if (!caseSensitiveName) command = command.ToLower();
|
||||
for (int i = 0; i < invokeStrings.Length; i++)
|
||||
{
|
||||
if (!caseSensitiveName)
|
||||
{
|
||||
if (invokeStrings[i].ToLower() == command) return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (invokeStrings[i] == command) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the command.
|
||||
/// </summary>
|
||||
/// <param name="arguments">arguments to be used. May be null.</param>
|
||||
public abstract void Run(string[] arguments = null);
|
||||
|
||||
/// <summary>
|
||||
/// Check if given argument is viable for command.
|
||||
/// </summary>
|
||||
/// <param name="argument">Argument to check.</param>
|
||||
/// <returns>True if valid.</returns>
|
||||
public bool Validate(string argument)
|
||||
{
|
||||
return EngineCommandArgumentOf(argument) == null ? false : true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="EngineCommandArgument"/> of the given argument or null if the string is an invalid argument.
|
||||
/// </summary>
|
||||
/// <param name="argument">The argument string.</param>
|
||||
/// <returns>null if not viable or the <see cref="EngineCommandArgumentOf(argument)"/> if viable.</returns>
|
||||
public EngineCommandArgument EngineCommandArgumentOf(string argument)
|
||||
{
|
||||
for (int i = 0; i < commandArguments.Length; i++)
|
||||
{
|
||||
if (commandArguments[i].invokeString == argument)
|
||||
{
|
||||
return commandArguments[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the index of the argument given in an array of arguments for the command.
|
||||
/// </summary>
|
||||
/// <param name="argument">The argument to find the index of.</param>
|
||||
/// <param name="arguments">The array containing all arguments.</param>
|
||||
/// <returns>The index or throws argument exception if it doesn't exist.</returns>
|
||||
public int IndexOfArgument(string argument, string[] arguments)
|
||||
{
|
||||
if (arguments != null)
|
||||
{
|
||||
for (int i = 0; i < arguments.Length; i++)
|
||||
{
|
||||
if (arguments[i] == argument)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new ArgumentException("Expected argument " + argument + " is missing. Type \"help\" for more information.");
|
||||
}
|
||||
|
||||
public bool HasArgument(string argument, string[] arguments)
|
||||
{
|
||||
try
|
||||
{
|
||||
IndexOfArgument(argument, arguments);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool HasArgument(EngineCommandArgument argument, string[] arguments)
|
||||
{
|
||||
return HasArgument(argument.invokeString, arguments);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the index of the argument given in an array of arguments for the command.
|
||||
/// </summary>
|
||||
/// <param name="argument">The argument to find the index of.</param>
|
||||
/// <param name="arguments">The array containing all arguments.</param>
|
||||
/// <returns>The index or throws argument exception if it doesn't exist.</returns>
|
||||
public int IndexOfArgumentIn(EngineCommandArgument argument, string[] arguments)
|
||||
{
|
||||
return IndexOfArgument(argument.invokeString, arguments);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when help "command trigger" [argument] is invoked. Argument is optional and therefore, may be null. If the valid arguments are properly registered, this command will take care of it. If no arguments are provided, it will return the general help defined for this command.
|
||||
/// </summary>
|
||||
/// <param name="argument">Potential argument to request help for.</param>
|
||||
/// <returns>The string for the help.</returns>
|
||||
public string Help(string argument = null)
|
||||
{
|
||||
if (argument != null && commandArguments != null)
|
||||
{
|
||||
if (Validate(argument))
|
||||
{
|
||||
EngineCommandArgument eca = EngineCommandArgumentOf(argument);
|
||||
string helpString = eca.help;
|
||||
if (eca.required) helpString = helpString + " required.";
|
||||
return EngineCommandArgumentOf(argument).help;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "The argument " + argument + " does not exist. Type \"help " + invokeStrings[0] + "\" (or any of its aliases) for a list of arguments.";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder helpBuilder = new StringBuilder();
|
||||
helpBuilder.Append(help);
|
||||
if (commandArguments != null)
|
||||
{
|
||||
helpBuilder.AppendLine();
|
||||
helpBuilder.Append("Possible arguments are: ");
|
||||
for (int i = 0; i < commandArguments.Length; i++)
|
||||
{
|
||||
helpBuilder.Append(commandArguments[i].invokeString);
|
||||
if (commandArguments[i].required) helpBuilder.Append('*');
|
||||
if (i == commandArguments.Length - 2)
|
||||
{
|
||||
helpBuilder.Append(", and ");
|
||||
}
|
||||
else if (i < commandArguments.Length - 2)
|
||||
{
|
||||
helpBuilder.Append(", ");
|
||||
}
|
||||
}
|
||||
helpBuilder.Append('.');
|
||||
helpBuilder.AppendLine(" [* are required arguments.]");
|
||||
}
|
||||
return helpBuilder.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,15 +0,0 @@
|
||||
namespace RecrownedGTK.Tools.CommandProcessor
|
||||
{
|
||||
public class EngineCommandArgument
|
||||
{
|
||||
public string invokeString;
|
||||
public string help;
|
||||
public bool required;
|
||||
public EngineCommandArgument(string invokeString, string help, bool required = false)
|
||||
{
|
||||
this.invokeString = invokeString;
|
||||
this.help = help;
|
||||
this.required = required;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user