public bool AddSubCommand(CommandTable subCommand) { if (!subCommands.Any(arg => arg.command == subCommand.Command)) { subCommands.Add(subCommand); return(true); } return(false); }
public Task <Result <object> > ExecuteCommand(string command) { if (executioners.Count != 0) { return(CallExecutioner(command)); } var result = Result.Successful(null); List <ExecutionGraphEntry> executionGraph = new List <ExecutionGraphEntry>(); var commands = command.Split(commandSeparator); //loop through all the commands for (int commandIteration = 0; commandIteration < commands.Count(); commandIteration++) { var trimmed = commands[commandIteration].TrimStart(argumentSeparator).TrimEnd(argumentSeparator); var subCommands = commands[commandIteration].Split(subCommandSeparator); string currentCommand = string.Empty; CommandTable commandEntry = null; //var commandWithArguments = trimmed.Split(argumentSeparator); //if the command string is not long enough, fail //split the command to its0 subcommands for (int subCommandIteration = 0; subCommandIteration < subCommands.Count(); subCommandIteration++) { var trimmedSub = subCommands[subCommandIteration].TrimStart(argumentSeparator).TrimEnd(argumentSeparator); var subCommandWithArguments = trimmedSub.Split(argumentSeparator); if (subCommandWithArguments.Count() == 0) { return(ExecutionFailed("Invalid Command")); } if (subCommandIteration == 0) { currentCommand = subCommandWithArguments[0]; commandEntry = commandTable.Where(entry => entry.Command == currentCommand).FirstOrDefault(); if (commandEntry != null) { executionGraph.Add(new ExecutionGraphEntry(commandEntry.Callback, commandEntry.Rollback, subCommandWithArguments.Skip(1).ToList())); } //if the commandtable doesn't have a command match, fail else { return(ExecutionFailed("Invalid Command")); } continue; } //if the subcommand string is not long enough, fail if (subCommandWithArguments.Count() == 0) { return(ExecutionFailed("Invalid Command")); } commandEntry = commandTable.Where(entry => entry.Command == currentCommand) .SelectMany(x => x.SubCommand) .Where(cmd => cmd.Command == subCommandWithArguments[0]) .FirstOrDefault(); if (commandEntry != null) { executionGraph.Add(new ExecutionGraphEntry(commandEntry.Callback, null, subCommandWithArguments.Skip(1).ToList())); } //if no entries were found, fail else { return(ExecutionFailed("Invalid Command")); } } } //execute the graph return(Task <Result <object> > .Run(() => { Stack <ExecutionGraphEntry> callstack = new Stack <ExecutionGraphEntry>(); Result <object> executionResult = Result.Ok <object>(null); foreach (var entry in executionGraph) { if (!executionResult.Failure) { callstack.Push(entry); executionResult = entry.Callback(this, entry.Arguments, executionResult.Value); } else { //fallback foreach (var executedCommand in callstack) { if (executedCommand.Rollback != null) { executionResult = executedCommand.Rollback(this, entry.Arguments, executionResult.Value); } } return Result.Failed("Command execution failed " + executionResult.Error, executionResult.Value); } } return executionResult; })); }