Created
August 17, 2017 04:29
-
-
Save pigeonhands/92fb20cc7b28d23931ba6ea200a31360 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace Assets.scripts { | |
class ActionHandler : IEnumerable { | |
/// <summary> | |
/// List of inner commands | |
/// e.g. | |
/// the "left" in "move left" | |
/// </summary> | |
private List<ActionHandler> SubHandlers = new List<ActionHandler>(); | |
/// <summary> | |
/// handler for actions with no \adverb\ | |
/// e.g. | |
/// "look" | |
/// </summary> | |
private ActionHandler DefaultHandler = null; | |
/// <summary> | |
/// Keywords that is used to identify the command | |
/// e.g. | |
/// "move" and "go" | |
/// </summary> | |
public string[] Triggers { get; private set; } | |
/// <summary> | |
/// new instance of an action handler and setting the <see cref="Triggers"/> | |
/// </summary> | |
/// <param name="commandTriggers"><see cref="Triggers"/> to be set</param> | |
public ActionHandler(params string[] commandTriggers) { | |
Triggers = commandTriggers; | |
} | |
/// <summary> | |
/// new instance of an action with no <see cref="Triggers"/> | |
/// </summary> | |
public ActionHandler() : this(string.Empty) { | |
} | |
/// <summary> | |
/// Add a subcommand/adverb | |
/// | |
/// e.g. | |
/// "up" in "look up" | |
/// </summary> | |
/// <param name="handler">The subhandler.</param> | |
public void Add(ActionHandler handler) { | |
SubHandlers.Add(handler); | |
} | |
/// <summary> | |
/// Add a method handler for an action | |
/// </summary> | |
/// <param name="cmd"><see cref="Triggers"/> for command to be identified by</param> | |
/// <param name="callback">Method callback</param> | |
public void Add(string[] cmd, Action<string> callback) { | |
SubHandlers.Add(new ActionMethodHandler(cmd, callback)); | |
} | |
/// <summary> | |
/// Add a method handler for an action with a single trigger | |
/// </summary> | |
/// <param name="cmd">The trigger</param> | |
/// <param name="callback">method callback</param> | |
public void Add(string cmd, Action<string> callback) { | |
Add(new string[] { cmd }, callback); | |
} | |
/// <summary> | |
/// Add a default method handler for when no adverb/subcommand is specified | |
/// </summary> | |
/// <param name="callback">method callback</param> | |
public void Add(Action<string> callback) { | |
DefaultHandler = new ActionMethodHandler(new string[] { string.Empty }, callback); | |
} | |
/// <summary> | |
/// Handle the command input | |
/// </summary> | |
/// <param name="subcommands"></param> | |
/// <returns></returns> | |
public virtual bool Handle(string subcommands) { | |
//Split the input string by " " but only on the first space. commandParts length will only ever be 1 or 2 | |
//e.g. | |
//"move up and down" -> "move", "up and down" | |
string[] commandParts = subcommands.Split(new char[] { ' ' }, 2); | |
string command = commandParts[0].Trim(); | |
//?: = ternary operator. (if) ? (then) : (else) | |
//So, if commandParts has a second item, set commandParameters to that item, else set it to "" | |
string commandParameters = commandParts.Length == 2 ? commandParts[1].Trim() : string.Empty; | |
//Find the handler in the SubHandlers where one of its Triggers macthes the command | |
ActionHandler handler = SubHandlers.FirstOrDefault(x => x.Triggers.Contains(command)); | |
if (handler != null) { | |
//If a subhandler was found, run its Handle method with the rest of the command | |
return handler.Handle(commandParameters); | |
} else { | |
//No handler found. Is there a default handler set? | |
if (DefaultHandler != null && string.IsNullOrEmpty(commandParameters)) { | |
//Ye, call it | |
return DefaultHandler.Handle(commandParameters); | |
} else { | |
//No | |
return false; | |
} | |
} | |
} | |
public IEnumerator GetEnumerator() { //Implimenting IEnumerable interface. Required for smooth interaction with the "Add" method. | |
return SubHandlers.GetEnumerator(); | |
} | |
#region " Private action handlers for methods " | |
/// <summary> | |
/// wraps a method with a void(string) signature to a ActionHandler so that it can be added to another handlers SubHandlers | |
/// </summary> | |
private class ActionMethodHandler : ActionHandler { | |
//Methdo that will be called when this method is Handled | |
private Action<string> handleCallBack; | |
/// <summary> | |
/// Create a new ActionMethodHandler | |
/// "base" is the constructor of the base type. In this case its ActionHandler | |
/// </summary> | |
/// <param name="cmd">the triggers</param> | |
/// <param name="_handleCallBack">the method to call</param> | |
public ActionMethodHandler(string[] cmd, Action<string> _handleCallBack) : base(cmd) { | |
handleCallBack = _handleCallBack; | |
} | |
/// <summary> | |
/// Override ActionHandler's Handle method. | |
/// </summary> | |
/// <param name="subcommands"></param> | |
/// <returns></returns> | |
public override bool Handle(string subcommands) { | |
if (handleCallBack != null) { //Has a method atcualy been set? | |
handleCallBack(subcommands); //Call it | |
} | |
return true; | |
} | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment