improved command argument system.

This commit is contained in:
Harrison Deng 2018-12-28 18:52:52 -06:00
parent d2ac5196cb
commit 960bf76802
8 changed files with 191 additions and 152 deletions

View File

@ -8,12 +8,7 @@ namespace RecrownedAthenaeum.Tools.CommandProcessor.Commands
{
public ClearConsoleCommand() : base("clear")
{
}
public override string Help(string argument = null)
{
return "Clears the console.";
help = "Clears the console.";
}
public override void Run(string[] arguments = null)

View File

@ -11,11 +11,7 @@ namespace RecrownedAthenaeum.Tools.CommandProcessor.Commands
public HelpCommand(CommandEngine commandEngine) : base("help")
{
this.commandEngine = commandEngine;
}
public override string Help(string argument)
{
return "help [command] [arg]";
help = "help [command] [arg]";
}
@ -41,10 +37,10 @@ namespace RecrownedAthenaeum.Tools.CommandProcessor.Commands
ConsoleUtilities.WriteWrappedLine("Tools for RecrownedAthenaeum library. Possible commands are as follows:\n");
foreach (EngineCommand engineCommand in commandEngine.commands)
{
for (int i = 0; i < engineCommand.invokeStrings.Length; i++)
for (int i = 0; i < engineCommand.InvokeStrings.Length; i++)
{
ConsoleUtilities.WriteWrapped(engineCommand.invokeStrings[i]);
if (i + 1 < engineCommand.invokeStrings.Length)
ConsoleUtilities.WriteWrapped(engineCommand.InvokeStrings[i]);
if (i + 1 < engineCommand.InvokeStrings.Length)
{
ConsoleUtilities.WriteWrapped(", ");
}

View File

@ -11,11 +11,7 @@ namespace RecrownedAthenaeum.Tools.CommandProcessor.Commands
public StopCommand(CommandEngine commandEngine) : base("quit", "stop", "q", "exit")
{
this.commandEngine = commandEngine;
}
public override string Help(string argument = null)
{
return "Exits the tool.";
help = "Exits the tool.";
}
public override void Run(string[] arguments = null)

View File

@ -1,39 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace RecrownedAthenaeum.Tools.CommandProcessor.Commands
{
class TestCommand : EngineCommand
{
public TestCommand() : base("test")
{
}
public override string Help(string argument = null)
{
switch (argument)
{
case null:
return "Test command. Meant for testing random stuff. Current arguments: \"-textWrap\".\n" +
"Its ironic that the help section is also meant to test things.";
case "-textWrap":
return "-textWrap prints a large amount of text to test the text wrap.";
}
return "Test command.";
}
public override void Run(string[] arguments = null)
{
if (arguments != null && arguments[0] == "-textWrap")
{
ConsoleUtilities.WriteWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit.[here]\n Duis semper lacinia nisl, eget efficitur massa feugiat vel. Ut egestas elit id sollicitudin pellentesque.[here no space after break.]\nFusce ullamcorper nec turpis at aliquam. Donec cursus mi nec porttitor convallis. Nullam condimentum sollicitudin volutpat. Pellentesque tellus ligula, eleifend sit amet ante ac, accumsan volutpat lorem. Suspendisse potenti. Vestibulum at sodales ipsum. Mauris dignissim maximus purus sagittis elementum.", true);
ConsoleUtilities.WriteWrapped("test");
ConsoleUtilities.WriteWrapped(". ");
ConsoleUtilities.WriteWrapped("test.");
}
base.Run(arguments);
}
}
}

View File

@ -6,12 +6,20 @@ namespace RecrownedAthenaeum.Tools.CommandProcessor
{
public abstract class EngineCommand
{
bool CaseSensitiveName = false;
bool caseSensitiveName = false;
/// <summary>
/// the words a user can type that will invoke this command.
/// </summary>
public string[] invokeStrings;
protected string[] invokeStrings;
public string[] InvokeStrings { get { return invokeStrings; } }
/// <summary>
/// Arguments that this command should accept and take into account.
/// </summary>
protected EngineCommandArgument[] arguments;
protected string help;
public EngineCommand(params string[] invokeStrings)
{
@ -25,13 +33,14 @@ namespace RecrownedAthenaeum.Tools.CommandProcessor
/// <returns>whether or not this command is invoked.</returns>
public bool IsInvoked(string command)
{
if (!CaseSensitiveName) command = command.ToLower();
if (!caseSensitiveName) command = command.ToLower();
for (int i = 0; i < invokeStrings.Length; i++)
{
if (!CaseSensitiveName)
if (!caseSensitiveName)
{
if (invokeStrings[i].ToLower() == command) return true;
} else
}
else
{
if (invokeStrings[i] == command) return true;
}
@ -49,16 +58,116 @@ namespace RecrownedAthenaeum.Tools.CommandProcessor
}
/// <summary>
/// Returns the help for the given argument for this command. If no argument is defined, general help for the command should be given.
/// If no argument is given (null), then returns overall help statement.
/// Overall help should list possible arguments for user to use "help [command] [arg]" format.
/// Arguments can then be separately returned from help as the help command will pass in the argument the user requests to see in detail in the parameter.
/// Check if given argument is viable for command.
/// </summary>
/// <param name="argument">The argument the help string is for. Can be null for overall command help.</param>
/// <returns>The text to help understand the argument or the overall command.</returns>
public virtual string Help(string argument = null)
/// <param name="argument">Argument to check.</param>
/// <returns>True if valid.</returns>
public bool Validate(string argument)
{
return "This command doesn't define a help string. Shame on it.";
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 < arguments.Length; i++)
{
if (arguments[i].invokeString == argument)
{
return arguments[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 IndexOfArgumentIn(string argument, string[] arguments)
{
for (int i = 0; i < arguments.Length; i++)
{
if (arguments[i] == argument)
{
return i;
}
}
throw new ArgumentException("Argument " + argument + " is missing. Type \"help\" for more information.");
}
public bool HasArgument(string argument, string[] arguments)
{
try
{
IndexOfArgumentIn(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 IndexOfArgumentIn(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 (arguments != null)
{
if (Validate(argument))
{
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.";
}
}
StringBuilder helpBuilder = new StringBuilder();
helpBuilder.Append(help);
helpBuilder.AppendLine();
helpBuilder.Append("Possible arguments are: ");
for (int i = 0; i < arguments.Length; i++)
{
helpBuilder.Append(arguments[i].invokeString);
if (i + 2 > arguments.Length)
{
helpBuilder.Append(", and ");
}
else
{
helpBuilder.Append(", ");
}
}
helpBuilder.Append('.');
return helpBuilder.ToString();
}
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace RecrownedAthenaeum.Tools.CommandProcessor
{
public class EngineCommandArgument
{
public string invokeString;
public string help;
public EngineCommandArgument(string invokeString, string help)
{
this.invokeString = invokeString;
this.help = help;
}
}
}

View File

@ -10,33 +10,23 @@ namespace RecrownedAthenaeum.Tools.TextureAtlasTools
class TexturePackerCommand : EngineCommand
{
public TexturePackerCommand() : base("texturepacker") { }
public override string Help(string argument)
public TexturePackerCommand() : base("texturepacker")
{
switch (argument)
{
case null:
return "Packs a given directory composed of png and jpg files into an atlas. Can also add 9patch properties. Possible arguments are \"-i\", \"-o\", \"-mp\", \"-dau\", and \"-9p\". Refer to \"help\" for more info.";
case "-i":
return "-i : Path for input directory containing the textures. Required.";
case "-o":
return "-o : Path for output files. Points to non-existent file. Will create texture and definitions file with name. Required.";
case "-9p":
return "-9p : Can be used multiple times for defining a 9patch. This parameter requires a name, left patch, right patch, top patch, and bottom patch in the format name,a,b,c,d. Optional.";
case "-sp":
return "-sp : starting power for one side of the texture. Default is 8.";
case "-mp":
return "-mp : Maximum power for one side of the texture. Default is 8.";
case "-dau":
return "-dau : disables automatically upscaling the texture.";
default:
return argument + " is not a valid argument. Type \"help texturepacker to see general help and list of arguments.\"";
}
arguments = new EngineCommandArgument[6] {
new EngineCommandArgument("-i", "for input directory containing the textures. Required."),
new EngineCommandArgument("-o", "Path for output files. Points to non-existent file. Will create texture and definitions file with name. Required."),
new EngineCommandArgument("-9p", "Can be used multiple times for defining a 9patch. This parameter requires a name, left patch, right patch, top patch, and bottom patch in the format name,a,b,c,d. Optional."),
new EngineCommandArgument("-sp", "Starting power for one side of the texture. Default is 8."),
new EngineCommandArgument("-mp", "Maximum power for one side of the texture. Default is 8."),
new EngineCommandArgument("-dau", "Disables automatically upscaling the texture."),
};
help = "Packs a given directory composed of png and jpg files into an atlas. Can also add 9patch properties. Runnig without arguments triggers interactive mode.";
}
public override void Run(string[] arguments)
{
TexturePacker texturePacker = null;
string path = null;
int mp = 8;
@ -44,72 +34,47 @@ namespace RecrownedAthenaeum.Tools.TextureAtlasTools
bool dau = false;
string output = null;
if (arguments == null) throw new ArgumentException("Requires arguments. Type \"help texturepacker\" for more info.");
if (arguments == null)
{
}
path = arguments[1 + IndexOfArgumentIn("-i", arguments)];
int.TryParse(arguments[IndexOfArgumentIn("-mp", arguments) + 1], out mp);
int.TryParse(arguments[IndexOfArgumentIn("-sp", arguments) + 1], out sp);
output = arguments[IndexOfArgumentIn("-o", arguments) + 1];
if (HasArgument("-dau", arguments)) dau = true;
texturePacker = new TexturePacker(path, mp, sp);
ConsoleUtilities.WriteWrappedLine("Calculated minimum texture size: " + texturePacker.TextureLength + "x" + texturePacker.TextureLength + " with a total of " + texturePacker.TexturesFound + " textures.");
try
{
texturePacker.Build(!dau);
}
catch (InvalidOperationException e)
{
throw new ArgumentException(e.Message);
}
for (int i = 0; i < arguments.Length; i++)
{
if (arguments[i] == "-i")
if (arguments[i] == "-9p")
{
if (i + 1 == arguments.Length) throw new ArgumentException("-i is not followed by path for input directory.");
path = arguments[i + 1];
}
if (arguments[i] == "-mp")
{
if (i + 1 >= arguments.Length || !int.TryParse(arguments[i + 1], out mp)) throw new ArgumentException("mp is not followed by maximum power.");
}
if (arguments[i] == "-sp")
{
if (i + 1 >= arguments.Length || !int.TryParse(arguments[i + 1], out sp)) throw new ArgumentException("sp is not followed by maximum power.");
}
if (arguments[i] == "-o")
{
if (i + 1 >= arguments.Length) throw new ArgumentException("-o is not followed by path for output files. (eg. path/to/file where file is the name for the atlas.)");
output = arguments[i + 1];
}
if (i == arguments.Length - 1 && output == null)
{
throw new ArgumentException("no -o argument found to specify output.");
}
if (arguments[i] == "-dau") dau = true;
}
texturePacker = new TexturePacker(path, mp, sp);
ConsoleUtilities.WriteWrappedLine("Calculated minimum texture size: " + texturePacker.TextureLength + "x" + texturePacker.TextureLength + " with a total of " + texturePacker.TexturesFound + " textures.");
if (texturePacker != null)
{
try
{
texturePacker.Build(!dau);
}
catch (InvalidOperationException e)
{
throw new ArgumentException(e.Message);
}
for (int i = 0; i < arguments.Length; i++)
{
if (arguments[i] == "-9p")
if (i + 5 >= arguments.Length) throw new ArgumentException("-9p is not followed by proper specifiers for a 9Patch (format: \"-9p textureName,a,b,c,d\" where a, b, c, and d are integers definining the border regions for the 9patch.)");
string[] nPatchArgs = arguments[i + 1].Split(',');
try
{
if (i + 5 >= arguments.Length) throw new ArgumentException("-9p is not followed by proper specifiers for a 9Patch (format: \"-9p textureName,a,b,c,d\" where a, b, c, and d are integers definining the border regions for the 9patch.)");
string[] nPatchArgs = arguments[i + 1].Split(',');
try
{
texturePacker.SetNinePatch(nPatchArgs[0], int.Parse(nPatchArgs[1]), int.Parse(nPatchArgs[2]), int.Parse(nPatchArgs[3]), int.Parse(nPatchArgs[4]));
}
catch (FormatException)
{
throw new ArgumentException("-9p argument parameters must be in the format \"-9p textureName,a,b,c,d\" where a, b, c, and d are integers definining the border regions for the 9patch.");
}
texturePacker.SetNinePatch(nPatchArgs[0], int.Parse(nPatchArgs[1]), int.Parse(nPatchArgs[2]), int.Parse(nPatchArgs[3]), int.Parse(nPatchArgs[4]));
}
catch (FormatException)
{
throw new ArgumentException("-9p argument parameters must be in the format \"-9p textureName,a,b,c,d\" where a, b, c, and d are integers definining the border regions for the 9patch.");
}
}
texturePacker.Save(Path.GetDirectoryName(output), Path.GetFileName(output));
Console.WriteLine("Complete. Final texture size: " + texturePacker.TextureLength + "x" + texturePacker.TextureLength + ".");
}
else
{
throw new ArgumentException("-i not specified.");
}
texturePacker.Save(Path.GetDirectoryName(output), Path.GetFileName(output));
Console.WriteLine("Complete. Final texture size: " + texturePacker.TextureLength + "x" + texturePacker.TextureLength + ".");
}
}
}

View File

@ -18,7 +18,6 @@ namespace RecrownedAthenaeum.Tools
ce.commands.Add(new HelpCommand(ce));
ce.commands.Add(new TexturePackerCommand());
ce.commands.Add(new StopCommand(ce));
ce.commands.Add(new TestCommand());
ce.commands.Add(new ClearConsoleCommand());
if (args.Length > 0)