diff --git a/Mage/Module.cs b/Mage/Module.cs index 460aeff..eeecf06 100644 --- a/Mage/Module.cs +++ b/Mage/Module.cs @@ -8,29 +8,45 @@ namespace Wizcorp.MageSDK.MageClient { - - public class Module : Singleton where T : class, new() + using MageCommandAction = Action>; + using MageCommandFunction = Func; + + public abstract class Module : Singleton where T : class, new() { - // + // Tells us if the module was set up + private bool _SetupCompleted = false; + public bool SetupCompleted { + get { return _SetupCompleted; } + private set { _SetupCompleted = value; } + } + + + // Mage singleton accessor protected Mage Mage { get { return Mage.Instance; } } + // Contextualized logger protected Logger Logger { get { return Mage.Logger(GetType().Name); } } - - // + // List of static topics to load during setup protected virtual List StaticTopics { get { return null; } } + // Static data container public JToken StaticData; + // Static data setup + // + // Note that topics are not tied to MAGE modules; they are + // essentially global to the MAGE server instance. This is + // simply a convenience function for loading data at setup time. public void SetupStaticData(Action cb) { Logger.Info("Setting up static data"); @@ -67,28 +83,50 @@ public void SetupStaticData(Action cb) } - // - protected virtual string CommandPrefix - { - get { return null; } - } + // The module name as defined on the remote MAGE server + protected abstract string CommandPrefix { get; } + + // The list of available user commands on the remote MAGE server + protected abstract List Commands { get; } - protected virtual List Commands + private Dictionary commandHandlerActions; + private Dictionary commandHandlerFuncs; + + private void AssertSetupCompleted() { - get { return null; } + if (SetupCompleted == false) + { + throw new Exception("Module was not setup: " + CommandPrefix); + } } - private Dictionary>> commandHandlerActions; - private Dictionary> commandHandlerFuncs; + private M GetCommand(Dictionary list, string commandName) { + AssertSetupCompleted(); + + if (list == null) { + throw new Exception("Module does not define any user commands: " + CommandPrefix); + } + + var command = list[commandName]; + + if (command == null) + { + throw new Exception("User command not found: " + CommandPrefix + "." + commandName); + } + + return command; + } public void Command(string commandName, JObject arguments, Action cb) { - commandHandlerActions[commandName](arguments, cb); + var action = GetCommand(commandHandlerActions, commandName); + action(arguments, cb); } public UserCommandStatus Command(string commandName, JObject arguments) { - return commandHandlerFuncs[commandName](arguments); + var action = GetCommand(commandHandlerFuncs, commandName); + return action(arguments); } private void RegisterCommand(string command) @@ -123,20 +161,21 @@ public void SetupUsercommands(Action cb) { Logger.Info("Setting up usercommands"); - commandHandlerActions = new Dictionary>>(); - commandHandlerFuncs = new Dictionary>(); - - if (Commands == null) - { + if (Commands == null) { + SetupCompleted = true; cb(null); return; } + commandHandlerActions = new Dictionary>>(); + commandHandlerFuncs = new Dictionary>(); + foreach (string command in Commands) { RegisterCommand(command); } + SetupCompleted = true; cb(null); } }