Added basic help and quit functions to tools.

This commit is contained in:
Harrison Deng 2020-05-26 21:06:31 -05:00
parent d149e12433
commit 2d9f7617aa
8 changed files with 181 additions and 25 deletions

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -1,25 +1,33 @@
using System; using System;
using System.Reflection; using System.Reflection;
using SlatedGameToolkit.Tools.Commands;
using SlatedGameToolkit.Tools.System; using SlatedGameToolkit.Tools.System;
using SlatedGameToolkit.Tools.System.Interaction; using SlatedGameToolkit.Tools.System.Interaction;
namespace SlatedGameToolkit.Tools namespace SlatedGameToolkit.Tools
{ {
class Program class ConsoleProgram
{ {
static private bool running;
static void Main(string[] args) static void Main(string[] args)
{ {
string input = null; CommandMap commands = new CommandMap(new StopCommand());
CommandMap commands = new CommandMap(); commands.Add(new HelpCommand(commands));
CommandProcessor processor = new CommandProcessor("The command \"{input}\" was not understood. Please type \"help\" for more information.", commands); CommandProcessor processor = new CommandProcessor("The command \"{input}\" was not understood. Please type \"help\" for more information.", commands);
AssemblyName name = Assembly.GetExecutingAssembly().GetName(); 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(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!"); 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")) { running = true;
while (running) {
consoleInteracter.Separate();
processor.Process(consoleInteracter);
} }
consoleInteracter.Tell("Goodbye!"); consoleInteracter.Tell("Exiting tool.");
}
public static void Stop() {
running = false;
} }
} }
} }

View File

@ -1,11 +1,18 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using SlatedGameToolkit.Tools.System.Interaction; using SlatedGameToolkit.Tools.System.Interaction;
namespace SlatedGameToolkit.Tools.System namespace SlatedGameToolkit.Tools.System
{ {
public class CommandMap { public class CommandMap : ICollection<IInvocable> {
Dictionary<string, IInvocable> invocations; Dictionary<string, IInvocable> invocations;
HashSet<IInvocable> values;
public int Count => invocations.Count;
public bool IsReadOnly => false;
public IInvocable this[string invocation] { public IInvocable this[string invocation] {
get { get {
IInvocable result = null; IInvocable result = null;
@ -15,18 +22,62 @@ namespace SlatedGameToolkit.Tools.System
} }
public CommandMap(params IInvocable[] invokables) { public CommandMap(params IInvocable[] invokables) {
invocations = new Dictionary<string, IInvocable>(); invocations = new Dictionary<string, IInvocable>();
values = new HashSet<IInvocable>();
foreach (IInvocable item in invokables) foreach (IInvocable item in invokables)
{ {
string[] invokers = item.GetInvokers(); Add(item);
foreach (string invoker in invokers) }
{ }
try {
invocations.Add(invoker, item); public IEnumerator<IInvocable> GetEnumerator()
} catch (ArgumentException e) { {
throw new ArgumentException("A duplicate invocation string was found!", e); 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;
}
} }
} }

View File

@ -27,11 +27,11 @@ namespace SlatedGameToolkit.Tools.System
if (invocable != null) { if (invocable != null) {
string[] args = new string[splitMessage.Length - 1]; string[] args = new string[splitMessage.Length - 1];
Array.Copy(splitMessage, 1, args, 0, splitMessage.Length - 1); Array.Copy(splitMessage, 1, args, 0, splitMessage.Length - 1);
if (invocable.Execute(args)) { if (invocable.Execute(interactable, args)) {
return; return;
} }
} }
interactable.Tell(generalHelpMessage); interactable.Tell(generalHelpMessage.Replace("{input}", invocation));
} }
} }
} }

View File

@ -1,3 +1,5 @@
using SlatedGameToolkit.Tools.System.Interaction;
namespace SlatedGameToolkit.Tools.System namespace SlatedGameToolkit.Tools.System
{ {
public interface IInvocable public interface IInvocable
@ -12,16 +14,24 @@ namespace SlatedGameToolkit.Tools.System
/// <summary> /// <summary>
/// The help should be a description of how to properly use this invokable. /// 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. /// If an argument is specified, the help should cater to that specific argument.
/// Information in the description does not need to be repeated.
/// </summary> /// </summary>
/// <param name="arg">An argument this invokable should describe. May be null, to which should return a string that describes this invokable in general.</param> /// <param name="arg">An argument this invokable should describe. May be null, to which should return a string that describes this invokable in general.</param>
/// <returns></returns> /// <returns></returns>
string getHelp(string arg); string getUsage(string arg);
/// <summary> /// <summary>
/// Executes this invokable. /// Executes this invokable.
/// </summary> /// </summary>
/// <param name="interactable">The interactable object.</param>
/// <param name="args">The arguments that followed the invokable.</param> /// <param name="args">The arguments that followed the invokable.</param>
/// <returns>True if the invokable was successful, false otherwise to display a generic help message.</returns> /// <returns>True if the invokable was successful, false otherwise to display a generic help message.</returns>
bool Execute(string[] args); bool Execute(IInteractable interactable, string[] args);
/// <summary>
/// Gets a simple description of the command.
/// </summary>
/// <returns>Return a string with a short description of the command.</returns>
string getDescription();
} }
} }

View File

@ -2,14 +2,14 @@ using System;
namespace SlatedGameToolkit.Tools.System.Interaction namespace SlatedGameToolkit.Tools.System.Interaction
{ {
public class ConsoleInteracter : IInteractable public class ConsoleInteraction : IInteractable
{ {
string prefix; string prefix;
public ConsoleInteracter(string prefix) { public ConsoleInteraction(string prefix) {
this.prefix = prefix; this.prefix = prefix;
} }
public void LineBreak() public void Separate()
{ {
Console.WriteLine(); Console.WriteLine();
} }

View File

@ -3,7 +3,7 @@ namespace SlatedGameToolkit.Tools.System.Interaction
public interface IInteractable public interface IInteractable
{ {
void Tell(string message); void Tell(string message);
void LineBreak(); void Separate();
string Listen(); string Listen();
} }