private static E <string> InsertInto(CommandGroup group, ICommand com, string name) { var subCommand = group.GetCommand(name); switch (subCommand) { case null: // the group we are trying to insert has no element with the current // name, so just insert it group.AddCommand(name, com); return(R.Ok); case CommandGroup insertCommand: // to add a command to CommandGroup will have to treat it as a subcommand // with an empty string as a name var noparamCommand = insertCommand.GetCommand(string.Empty); if (noparamCommand is null) { insertCommand.AddCommand(string.Empty, com); if (com is BotCommand botCom && botCom.NormalParameters > 0) { Log.Warn("\"{0}\" has at least one parameter and won't be reachable due to an overloading function.", botCom.FullQualifiedName); } return(R.Ok); } else { return("An empty named function under a group cannot be overloaded."); } } if (!(com is FunctionCommand funcCom)) { return($"The command cannot be inserted into a complex node ({name})."); } switch (subCommand) { case FunctionCommand subFuncCommand: // if we have is a simple function, we need to create a overlaoder // and then add both functions to it group.RemoveCommand(name); var overloader = new OverloadedFunctionCommand(); overloader.AddCommand(subFuncCommand); overloader.AddCommand(funcCom); group.AddCommand(name, overloader); break; case OverloadedFunctionCommand insertCommand: // if we have a overloaded function, we can simply add it insertCommand.AddCommand(funcCom); break; default: return("Unknown node to insert to."); } return(R.Ok); }
private R <CommandGroup, string> BuildAndGet(IEnumerable <string> comPath) { CommandGroup group = CommandSystem.RootCommand; // this for loop iterates through the separate names of // the command to be added. foreach (var comPathPart in comPath) { ICommand currentCommand = group.GetCommand(comPathPart); // if a group to hold the next level command doesn't exist // it will be created here if (currentCommand is null) { var nextGroup = new CommandGroup(); group.AddCommand(comPathPart, nextGroup); group = nextGroup; } // if the group already exists we can take it. else if (currentCommand is CommandGroup cgCommand) { group = cgCommand; } // if the element is anything else, we have to replace it // with a group and put the old element back into it. else if (currentCommand is FunctionCommand) { var subGroup = new CommandGroup(); group.RemoveCommand(comPathPart); group.AddCommand(comPathPart, subGroup); var insertResult = InsertInto(group, currentCommand, comPathPart); if (!insertResult.Ok) { return(insertResult.Error); } group = subGroup; } else { return("An overloaded command cannot be replaced by a CommandGroup"); } } return(group); }
private R <CommandGroup, string> BuildAndGet(IEnumerable <string> comPath) { CommandGroup group = RootGroup; // this for loop iterates through the separate names of // the command to be added. foreach (var comPathPart in comPath) { switch (group.GetCommand(comPathPart)) { // if a group to hold the next level command doesn't exist // it will be created here case null: var nextGroup = new CommandGroup(); group.AddCommand(comPathPart, nextGroup); group = nextGroup; break; // if the group already exists we can take it. case CommandGroup cgCommand: group = cgCommand; break; // if the element is anything else, we have to replace it // with a group and put the old element back into it. case FunctionCommand fnCommand: var subGroup = new CommandGroup(); group.RemoveCommand(comPathPart); group.AddCommand(comPathPart, subGroup); var insertResult = InsertInto(group, fnCommand, comPathPart); if (!insertResult.Ok) { return(insertResult.Error); } group = subGroup; break; default: return("An overloaded command cannot be replaced by a CommandGroup"); } } return(group); }
// TODO: prevent stupid behaviour like: // string A(int b) // string A(ExecutionInformation i, int b) // since the CommandManager can't distinguish these two, when calling private void LoadCommand(BotCommand com) // TODO test { if (!CommandNamespaceValidator.IsMatch(com.InvokeName)) { throw new InvalidOperationException("BotCommand has an invalid invoke name: " + com.InvokeName); } if (CommandPaths.Contains(com.FullQualifiedName)) { throw new InvalidOperationException("Command already exists: " + com.InvokeName); } CommandPaths.Add(com.FullQualifiedName); var comPath = com.InvokeName.Split(' '); CommandGroup group = CommandSystem.RootCommand; // this for loop iterates through the seperate names of // the command to be added. for (int i = 0; i < comPath.Length - 1; i++) { ICommand currentCommand = group.GetCommand(comPath[i]); // if a group to hold the next level command doesn't exist // it will be created here if (currentCommand == null) { var nextGroup = new CommandGroup(); group.AddCommand(comPath[i], nextGroup); group = nextGroup; } // if the group already exists we can take it. else if (currentCommand is CommandGroup) { group = (CommandGroup)currentCommand; } // if the element is anything else, we have to replace it // with a group and put the old element back into it. else if (currentCommand is FunctionCommand) { var subGroup = new CommandGroup(); group.RemoveCommand(comPath[i]); group.AddCommand(comPath[i], subGroup); var botCom = currentCommand as BotCommand; if (botCom != null && botCom.NormalParameters > 0) { Log.Write(Log.Level.Warning, "\"{0}\" has at least one parameter and won't be reachable due to an overloading function.", botCom.InvokeName); } subGroup.AddCommand(string.Empty, currentCommand); group = subGroup; } else { throw new InvalidOperationException("An overloaded command cannot be replaced by a CommandGroup: " + com.InvokeName); } } ICommand subCommand = group.GetCommand(comPath.Last()); // the group we are trying to insert has no element with the current // name, so just insert it if (subCommand == null) { group.AddCommand(comPath.Last(), com); return; } // if we have a simple function, we need to create a overlaoder // and then add both functions to it else if (subCommand is FunctionCommand) { group.RemoveCommand(comPath.Last()); var overloader = new OverloadedFunctionCommand(); overloader.AddCommand((FunctionCommand)subCommand); overloader.AddCommand(com); group.AddCommand(comPath.Last(), overloader); } // if we have a overloaded function, we can simply add it else if (subCommand is OverloadedFunctionCommand) { var insertCommand = (OverloadedFunctionCommand)subCommand; insertCommand.AddCommand(com); } // to add a command to CommandGroup will have to treat it as a subcommand // with an empty string as a name else if (subCommand is CommandGroup) { var insertCommand = (CommandGroup)subCommand; var noparamCommand = insertCommand.GetCommand(string.Empty); if (noparamCommand == null) { insertCommand.AddCommand(string.Empty, com); if (com.NormalParameters > 0) { Log.Write(Log.Level.Warning, "parameter of an empty named function under a group will be ignored!!"); } } else { throw new InvalidOperationException("An empty named function under a group cannot be overloaded (" + com.InvokeName + ")"); } } else { throw new InvalidOperationException("Unknown insertion error with " + com.FullQualifiedName); } }
private static R InsertInto(CommandGroup group, ICommand com, string name) { ICommand subCommand = group.GetCommand(name); // the group we are trying to insert has no element with the current // name, so just insert it if (subCommand == null) { group.AddCommand(name, com); return(R.OkR); } // to add a command to CommandGroup will have to treat it as a subcommand // with an empty string as a name else if (subCommand is CommandGroup) { var insertCommand = (CommandGroup)subCommand; var noparamCommand = insertCommand.GetCommand(string.Empty); if (noparamCommand == null) { insertCommand.AddCommand(string.Empty, com); var botCom = com as BotCommand; if (botCom != null && botCom.NormalParameters > 0) { Log.Write(Log.Level.Warning, $"\"{botCom.FullQualifiedName}\" has at least one parameter and won't be reachable due to an overloading function."); } return(R.OkR); } else { return("An empty named function under a group cannot be overloaded."); } } var funcCom = com as FunctionCommand; if (funcCom == null) { return($"The command cannot be inserted into a complex node ({name})."); } // if we have is a simple function, we need to create a overlaoder // and then add both functions to it if (subCommand is FunctionCommand) { group.RemoveCommand(name); var overloader = new OverloadedFunctionCommand(); overloader.AddCommand((FunctionCommand)subCommand); overloader.AddCommand(funcCom); group.AddCommand(name, overloader); } // if we have a overloaded function, we can simply add it else if (subCommand is OverloadedFunctionCommand) { var insertCommand = (OverloadedFunctionCommand)subCommand; insertCommand.AddCommand(funcCom); } else { return("Unknown node to insert to."); } return(R.OkR); }