recrownedgtk/RecrownedGTK.Tools/CommandProcessor/EngineCommand.cs

196 lines
7.9 KiB
C#
Raw Normal View History

2020-02-17 02:44:21 +00:00
using System;
using System.Text;
using RecrownedGTK.Tools.CommandProcessor;
2020-02-17 02:44:21 +00:00
namespace RecrownedGTK.Tools.CommandProcessor
{
public abstract class EngineCommand
{
bool caseSensitiveName = false;
/// <summary>
/// the words a user can type that will invoke this command.
/// </summary>
private string[] invokeStrings;
2020-02-17 02:44:21 +00:00
public string[] InvokeStrings { get { return invokeStrings; } }
/// <summary>
/// Arguments that this command should accept and take into account.
/// </summary>
2020-05-18 21:44:25 +00:00
protected EngineCommandArgument[] arguments;
protected readonly string help;
2020-02-17 02:44:21 +00:00
public EngineCommand(string help, params string[] invokeStrings)
2020-02-17 02:44:21 +00:00
{
this.help = help ?? throw new ArgumentNullException();
2020-02-17 02:44:21 +00:00
this.invokeStrings = invokeStrings ?? throw new ArgumentNullException();
for (int i = 0; i < invokeStrings.Length; i++) {
if (invokeStrings[i].Contains(" ")) {
throw new ArgumentException("Can't have spaces in command invocation strings.");
}
}
2020-02-17 02:44:21 +00:00
}
/// <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>
2020-05-18 21:44:25 +00:00
/// Runs the engine command.
2020-02-17 02:44:21 +00:00
/// </summary>
2020-05-18 21:44:25 +00:00
/// <param name="userInput">The user input object.</param>
/// <param name="userOutput">The user output object.</param>
/// <param name="arguments">The arguments.</param>
/// <returns>True if the command executed successfully, otherwise false to display a help message.</returns>
public abstract bool Run(IUserInput userInput, IUserOutput userOutput, params string[] arguments);
2020-02-17 02:44:21 +00:00
/// <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)
{
2020-05-18 21:44:25 +00:00
for (int i = 0; i < arguments.Length; i++)
2020-02-17 02:44:21 +00:00
{
2020-05-18 21:44:25 +00:00
if (arguments[i].invokeString == argument)
2020-02-17 02:44:21 +00:00
{
2020-05-18 21:44:25 +00:00
return arguments[i];
2020-02-17 02:44:21 +00:00
}
}
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 static int IndexOfArgument(string argument, string[] arguments)
2020-02-17 02:44:21 +00:00
{
if (argument == null) throw new ArgumentNullException("Parameter \"argument\" is null.");
if (arguments == null) throw new ArgumentNullException("Parameter \"arguments\" is null.");
for (int i = 0; i < arguments.Length; i++)
2020-02-17 02:44:21 +00:00
{
if (arguments[i] == argument)
2020-02-17 02:44:21 +00:00
{
return i;
2020-02-17 02:44:21 +00:00
}
}
throw new ArgumentException(String.Format("The argument \"{0}\" doesn't exist in the given array of arguments.", argument));
2020-02-17 02:44:21 +00:00
}
public static bool HasArgument(string argument, string[] arguments)
2020-02-17 02:44:21 +00:00
{
if (argument == null) throw new ArgumentNullException("Parameter \"argument\" is null.");
if (arguments == null) throw new ArgumentNullException("Parameter \"arguments\" is null.");
2020-02-17 02:44:21 +00:00
try
{
IndexOfArgument(argument, arguments);
}
catch (ArgumentException)
{
return false;
}
return true;
}
public static bool HasArgument(EngineCommandArgument argument, string[] arguments)
2020-02-17 02:44:21 +00:00
{
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 static int IndexOfArgument(EngineCommandArgument argument, string[] arguments)
2020-02-17 02:44:21 +00:00
{
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)
{
2020-05-18 21:44:25 +00:00
if (argument != null && arguments != null)
2020-02-17 02:44:21 +00:00
{
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);
2020-05-18 21:44:25 +00:00
if (arguments != null)
2020-02-17 02:44:21 +00:00
{
helpBuilder.AppendLine();
helpBuilder.Append("Possible arguments: ");
2020-05-18 21:44:25 +00:00
for (int i = 0; i < arguments.Length; i++)
2020-02-17 02:44:21 +00:00
{
2020-05-18 21:44:25 +00:00
helpBuilder.Append(arguments[i].invokeString);
if (arguments[i].required) helpBuilder.Append('*');
if (i == arguments.Length - 2)
2020-02-17 02:44:21 +00:00
{
helpBuilder.Append(", and ");
}
2020-05-18 21:44:25 +00:00
else if (i < arguments.Length - 2)
2020-02-17 02:44:21 +00:00
{
helpBuilder.Append(", ");
}
}
2020-05-18 21:44:25 +00:00
helpBuilder.Append(". (* are required arguments.)");
2020-02-17 02:44:21 +00:00
}
return helpBuilder.ToString();
}
}
}
}