예제 #1
0
 public bool AddSubCommand(CommandTable subCommand)
 {
     if (!subCommands.Any(arg => arg.command == subCommand.Command))
     {
         subCommands.Add(subCommand);
         return(true);
     }
     return(false);
 }
예제 #2
0
파일: Terminal.cs 프로젝트: gmich/Gem
        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;
            }));
        }