/// <summary> /// 调度命令,可以是命令的一部分 /// </summary> /// <param name="stringReader">原始字符流</param> /// <param name="env">环境</param> /// <param name="result">调度结果</param> /// <returns>是否调度成功</returns> public bool Dispatch(StringReader stringReader, TEnv env, out ICmdResult result) { StringReader reader = stringReader; // 跳过空白 reader.Skip(Config.ListSeps); // 记录位置,应为之后可能会读取别名,也用于解析失败,恢复用 int start = reader.Cursor; // 读取命令头,或者别名 string alias = stringReader.Read(ArgUtil.IsNameChar); int offset = 0; // 查找替换项,并计算偏移 if (!string.IsNullOrEmpty(alias) && aliases.TryGetValue(alias, out string replacement)) { reader = new StringReader(replacement + reader.ReadRest()); offset = alias.Length - replacement.Length; } else { // 恢复原始字符流 stringReader.Cursor = start; reader = new StringReader(reader.ReadRest()); } // 恢复原始字符流 stringReader.Cursor = start; List <ICmdResult> res = new List <ICmdResult>(); // 开始调度 bool ret = Root.Dispatch(this, reader, env, new Args(), 0, res); // 查找匹配成功的最长命令 List <ICmdResult> matched = new List <ICmdResult>(); List <ICmdResult> errors = new List <ICmdResult>(); foreach (var cc in res) { (cc.IsError ? errors : matched).Add(cc); } if (ret && matched.Count > 0) { result = GetLongestCmd(matched); } else if (!ret && errors.Count > 0) { // 如果没有最长成功命令,则返回最长错误 result = GetLongestCmd(errors); } else { // 否则出错 result = new ErrorResult(0, 0, "未知错误"); reader.Cursor = start; return(false); } reader.Skip(result.MatchedLength); // 此时reader已经不是原来的reader了,这样一来就要重新计算原始字符流的读取长度 stringReader.Skip(reader.Cursor + offset); return(ret); }
/// <summary> /// Shedule a command to send /// </summary> /// <param name="command">Serial Command, without newline</param> /// <param name="callback">Callback to get result</param> public void SheduleCommand(string command, ICmdResult callback) { Console.WriteLine("Shedule send command: \"" + command + "\""); lock (queue) { QueueEntry cmd = new QueueEntry(); cmd.Command = command; cmd.ResultListener = callback; queue.Enqueue(cmd); System.Threading.Monitor.Pulse(queue); } }
private ICmdResult DetectionObstacles(IPosition inputPosition) { ICmdResult cmdResult = Mef.Instance.GetCmdResult(); if (Obstacles.Count(o => o.Equals(inputPosition)) > 0) { cmdResult.Completed = false; cmdResult.DetectedObstacle = true; cmdResult.ObstaclePosition = inputPosition; } return(cmdResult); }
private ICmdResult GetLongestCmd(List <ICmdResult> list) { ICmdResult result = list[0]; foreach (var cc in list) { if (cc != result && cc.ArgLength > result.ArgLength) { result = cc; } } return(result); }
public ICmdResult Execute() { ICmdResult cmdResult = Mef.Instance.GetCmdResult(); foreach (var cmd in _commandList) { cmdResult = cmd.Execute(); if (cmdResult.DetectedObstacle) { break; } } return(cmdResult); }
/// <summary> /// 调度命令,必须是完整命令,不能多,也不能少 /// </summary> /// <param name="raw">原始字符串</param> /// <param name="env">环境</param> /// <param name="result">结果,可能是编译成功的指令或错误信息</param> /// <returns>是否调度成功</returns> public bool Dispatch(string raw, TEnv env, out ICmdResult result) { raw = raw.TrimStart(); StringReader reader = new StringReader(raw); if (!Dispatch(reader, env, out result)) { return(false); } else if (reader.SkipWhiteSpace()) { result = new ErrorResult( result.MatchedLength, 0, "未能识别的部分:" + reader.ReadToEndOrMaxOrEmpty(Config.MaxCut, Config.EmptyStrTip)); return(false); } return(true); }