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

View File

@ -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<IInvocable> {
Dictionary<string, IInvocable> invocations;
HashSet<IInvocable> 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<string, IInvocable>();
values = new HashSet<IInvocable>();
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<IInvocable> 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;
}
}
}

View File

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

View File

@ -1,3 +1,5 @@
using SlatedGameToolkit.Tools.System.Interaction;
namespace SlatedGameToolkit.Tools.System
{
public interface IInvocable
@ -12,16 +14,24 @@ namespace SlatedGameToolkit.Tools.System
/// <summary>
/// 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.
/// </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>
/// <returns></returns>
string getHelp(string arg);
string getUsage(string arg);
/// <summary>
/// Executes this invokable.
/// </summary>
/// <param name="interactable">The interactable object.</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>
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
{
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();
}

View File

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