From 2d9f7617aa1ca1f2b29dc692fd863227b57d551e Mon Sep 17 00:00:00 2001 From: Harrison Date: Tue, 26 May 2020 21:06:31 -0500 Subject: [PATCH] Added basic help and quit functions to tools. --- .../Commands/HelpCommand.cs | 56 +++++++++++++++ .../Commands/StopCommand.cs | 31 +++++++++ .../{Program.cs => ConsoleProgram.cs} | 24 ++++--- .../System/CommandMap.cs | 69 ++++++++++++++++--- .../System/CommandProcessor.cs | 4 +- .../System/IInvocable.cs | 14 +++- ...oleInteracter.cs => ConsoleInteraction.cs} | 6 +- .../System/Interaction/IInteractable.cs | 2 +- 8 files changed, 181 insertions(+), 25 deletions(-) create mode 100644 src/SlatedGameToolkit.Tools/Commands/HelpCommand.cs create mode 100644 src/SlatedGameToolkit.Tools/Commands/StopCommand.cs rename src/SlatedGameToolkit.Tools/{Program.cs => ConsoleProgram.cs} (56%) rename src/SlatedGameToolkit.Tools/System/Interaction/{ConsoleInteracter.cs => ConsoleInteraction.cs} (76%) diff --git a/src/SlatedGameToolkit.Tools/Commands/HelpCommand.cs b/src/SlatedGameToolkit.Tools/Commands/HelpCommand.cs new file mode 100644 index 0000000..fe25e82 --- /dev/null +++ b/src/SlatedGameToolkit.Tools/Commands/HelpCommand.cs @@ -0,0 +1,56 @@ +using System; +using System.Text; +using SlatedGameToolkit.Tools.System; +using SlatedGameToolkit.Tools.System.Interaction; + +namespace SlatedGameToolkit.Tools.Commands +{ + public class HelpCommand : IInvocable + { + private readonly string[] invokers = new string[] {"help"}; + private CommandMap commandMap; + + public HelpCommand(CommandMap commandMap) { + this.commandMap = commandMap; + } + + public bool Execute(IInteractable interactable, string[] args) + { + if (args.Length > 0) { + IInvocable invocable = commandMap[args[0]]; + if (invocable == null) interactable.Tell("Unable to find command {0}. Please type \"help\" for more a list of commands."); + StringBuilder builder = new StringBuilder(); + builder.AppendJoin(", ", invocable.GetInvokers()); + interactable.Tell("Possible aliases: " + builder.ToString() + ": "); + interactable.Tell("Description: " + invocable.getDescription()); + interactable.Tell("Usage: " + invocable.getUsage(args.Length > 0 ? args[0] : null)); + } else { + interactable.Tell("--- Help ---"); + foreach (IInvocable invocable in commandMap) + { + interactable.Separate(); + StringBuilder builder = new StringBuilder(); + builder.AppendJoin(", ", invocable.GetInvokers()); + interactable.Tell(builder.ToString() + ": "); + interactable.Tell(invocable.getDescription()); + } + } + return true; + } + + public string getDescription() + { + return "Displays the help message. You're looking at it."; + } + + public string getUsage(string arg) + { + return "Usage: \"help [command]\" where [command] is a specific command you want to see usage for."; + } + + public string[] GetInvokers() + { + return invokers; + } + } +} \ No newline at end of file diff --git a/src/SlatedGameToolkit.Tools/Commands/StopCommand.cs b/src/SlatedGameToolkit.Tools/Commands/StopCommand.cs new file mode 100644 index 0000000..77c81ce --- /dev/null +++ b/src/SlatedGameToolkit.Tools/Commands/StopCommand.cs @@ -0,0 +1,31 @@ +using SlatedGameToolkit.Tools.System; +using SlatedGameToolkit.Tools.System.Interaction; + +namespace SlatedGameToolkit.Tools.Commands +{ + public class StopCommand : IInvocable + { + private readonly string[] invokers = new string[] {"stop", "exit", "q", "quit"}; + public bool Execute(IInteractable interactable, string[] args) + { + if (args.Length > 1) return false; + ConsoleProgram.Stop(); + return true; + } + + public string getDescription() + { + return "Exits the tool."; + } + + public string getUsage(string arg) + { + return "This command exits the tool and has no additional arguments."; + } + + public string[] GetInvokers() + { + return invokers; + } + } +} \ No newline at end of file diff --git a/src/SlatedGameToolkit.Tools/Program.cs b/src/SlatedGameToolkit.Tools/ConsoleProgram.cs similarity index 56% rename from src/SlatedGameToolkit.Tools/Program.cs rename to src/SlatedGameToolkit.Tools/ConsoleProgram.cs index 01a8ab6..1c72c8f 100644 --- a/src/SlatedGameToolkit.Tools/Program.cs +++ b/src/SlatedGameToolkit.Tools/ConsoleProgram.cs @@ -1,25 +1,33 @@ using System; using System.Reflection; +using SlatedGameToolkit.Tools.Commands; using SlatedGameToolkit.Tools.System; using SlatedGameToolkit.Tools.System.Interaction; namespace SlatedGameToolkit.Tools { - class Program + class ConsoleProgram { + static private bool running; static void Main(string[] args) { - string input = null; - CommandMap commands = new CommandMap(); + CommandMap commands = new CommandMap(new StopCommand()); + commands.Add(new HelpCommand(commands)); CommandProcessor processor = new CommandProcessor("The command \"{input}\" was not understood. Please type \"help\" for more information.", commands); AssemblyName name = Assembly.GetExecutingAssembly().GetName(); - ConsoleInteracter consoleInteracter = new ConsoleInteracter("Tools"); + ConsoleInteraction consoleInteracter = new ConsoleInteraction("Tools"); consoleInteracter.Tell(String.Format("{0} Version: {1}", name.Name, name.Version)); - consoleInteracter.Tell("Welcome to SlatedGameToolkit.Tools! These tools are meant for the developers using the SlatedGameToolkit. Type \"help\" for a list of things this tool can currently do!"); - while (!(input = consoleInteracter.Listen()).ToLower().Equals("exit")) { - + consoleInteracter.Tell("Welcome to SlatedGameToolkit.Tools! These tools are meant for the developers using the SlatedGameToolkit. Type \"help\" for a list of things this tool can currently do."); + running = true; + while (running) { + consoleInteracter.Separate(); + processor.Process(consoleInteracter); } - consoleInteracter.Tell("Goodbye!"); + consoleInteracter.Tell("Exiting tool."); + } + + public static void Stop() { + running = false; } } } diff --git a/src/SlatedGameToolkit.Tools/System/CommandMap.cs b/src/SlatedGameToolkit.Tools/System/CommandMap.cs index 30837c9..bb35897 100644 --- a/src/SlatedGameToolkit.Tools/System/CommandMap.cs +++ b/src/SlatedGameToolkit.Tools/System/CommandMap.cs @@ -1,11 +1,18 @@ using System; +using System.Collections; using System.Collections.Generic; using SlatedGameToolkit.Tools.System.Interaction; namespace SlatedGameToolkit.Tools.System { - public class CommandMap { + public class CommandMap : ICollection { Dictionary invocations; + HashSet values; + + public int Count => invocations.Count; + + public bool IsReadOnly => false; + public IInvocable this[string invocation] { get { IInvocable result = null; @@ -15,18 +22,62 @@ namespace SlatedGameToolkit.Tools.System } public CommandMap(params IInvocable[] invokables) { invocations = new Dictionary(); + values = new HashSet(); foreach (IInvocable item in invokables) { - string[] invokers = item.GetInvokers(); - foreach (string invoker in invokers) - { - try { - invocations.Add(invoker, item); - } catch (ArgumentException e) { - throw new ArgumentException("A duplicate invocation string was found!", e); - } + Add(item); + } + } + + public IEnumerator GetEnumerator() + { + return values.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return values.GetEnumerator(); + } + + public void Add(IInvocable item) + { + values.Add(item); + string[] invokers = item.GetInvokers(); + foreach (string invoker in invokers) + { + try { + invocations.Add(invoker, item); + } catch (ArgumentException e) { + throw new ArgumentException("A duplicate invocation string was found!", e); } } } + + public void Clear() + { + invocations.Clear(); + values.Clear(); + } + + public bool Contains(IInvocable item) + { + return values.Contains(item); + } + + public void CopyTo(IInvocable[] array, int arrayIndex) + { + values.CopyTo(array, arrayIndex); + } + + public bool Remove(IInvocable item) + { + string[] invokers = item.GetInvokers(); + foreach (string invoker in invokers) + { + if (!invocations.Remove(invoker)) return false; + } + values.Remove(item); + return true; + } } } \ No newline at end of file diff --git a/src/SlatedGameToolkit.Tools/System/CommandProcessor.cs b/src/SlatedGameToolkit.Tools/System/CommandProcessor.cs index cd25d59..733375f 100644 --- a/src/SlatedGameToolkit.Tools/System/CommandProcessor.cs +++ b/src/SlatedGameToolkit.Tools/System/CommandProcessor.cs @@ -27,11 +27,11 @@ namespace SlatedGameToolkit.Tools.System if (invocable != null) { string[] args = new string[splitMessage.Length - 1]; Array.Copy(splitMessage, 1, args, 0, splitMessage.Length - 1); - if (invocable.Execute(args)) { + if (invocable.Execute(interactable, args)) { return; } } - interactable.Tell(generalHelpMessage); + interactable.Tell(generalHelpMessage.Replace("{input}", invocation)); } } } \ No newline at end of file diff --git a/src/SlatedGameToolkit.Tools/System/IInvocable.cs b/src/SlatedGameToolkit.Tools/System/IInvocable.cs index 815d06e..6beb0c0 100644 --- a/src/SlatedGameToolkit.Tools/System/IInvocable.cs +++ b/src/SlatedGameToolkit.Tools/System/IInvocable.cs @@ -1,3 +1,5 @@ +using SlatedGameToolkit.Tools.System.Interaction; + namespace SlatedGameToolkit.Tools.System { public interface IInvocable @@ -12,16 +14,24 @@ namespace SlatedGameToolkit.Tools.System /// /// The help should be a description of how to properly use this invokable. /// If an argument is specified, the help should cater to that specific argument. + /// Information in the description does not need to be repeated. /// /// An argument this invokable should describe. May be null, to which should return a string that describes this invokable in general. /// - string getHelp(string arg); + string getUsage(string arg); /// /// Executes this invokable. /// + /// The interactable object. /// The arguments that followed the invokable. /// True if the invokable was successful, false otherwise to display a generic help message. - bool Execute(string[] args); + bool Execute(IInteractable interactable, string[] args); + + /// + /// Gets a simple description of the command. + /// + /// Return a string with a short description of the command. + string getDescription(); } } \ No newline at end of file diff --git a/src/SlatedGameToolkit.Tools/System/Interaction/ConsoleInteracter.cs b/src/SlatedGameToolkit.Tools/System/Interaction/ConsoleInteraction.cs similarity index 76% rename from src/SlatedGameToolkit.Tools/System/Interaction/ConsoleInteracter.cs rename to src/SlatedGameToolkit.Tools/System/Interaction/ConsoleInteraction.cs index b64063e..b8f0064 100644 --- a/src/SlatedGameToolkit.Tools/System/Interaction/ConsoleInteracter.cs +++ b/src/SlatedGameToolkit.Tools/System/Interaction/ConsoleInteraction.cs @@ -2,14 +2,14 @@ using System; namespace SlatedGameToolkit.Tools.System.Interaction { - public class ConsoleInteracter : IInteractable + public class ConsoleInteraction : IInteractable { string prefix; - public ConsoleInteracter(string prefix) { + public ConsoleInteraction(string prefix) { this.prefix = prefix; } - public void LineBreak() + public void Separate() { Console.WriteLine(); } diff --git a/src/SlatedGameToolkit.Tools/System/Interaction/IInteractable.cs b/src/SlatedGameToolkit.Tools/System/Interaction/IInteractable.cs index 84df2d7..0aa362c 100644 --- a/src/SlatedGameToolkit.Tools/System/Interaction/IInteractable.cs +++ b/src/SlatedGameToolkit.Tools/System/Interaction/IInteractable.cs @@ -3,7 +3,7 @@ namespace SlatedGameToolkit.Tools.System.Interaction public interface IInteractable { void Tell(string message); - void LineBreak(); + void Separate(); string Listen(); }