Convert2ModuleNameTreeNode讲解
先看问题为什么需要这个东西程序里有一个ModuleList它是一份平铺的、顺序的模块清单。比如用户拖出来的流程可能是这样的[拍照] [如果 检测到瑕疵] [打标模块] [否则] [忽略模块] [结束] [保存结果]但在代码里这个ModuleList存的是一维数组没有父子关系索引0: 拍照 索引1: 如果 检测到瑕疵 索引2: 打标模块 索引3: 否则 索引4: 忽略模块 索引5: 结束 索引6: 保存结果如果只是从头到尾跑一遍那很简单。但问题来了——执行时需要根据结果跳转。比如如果 检测到瑕疵结果是 false就要跳过打标模块和否则和忽略模块直接跳到结束后面的保存结果。这时候系统需要知道打标模块的父级是谁“如果”打标模块的同级兄弟有哪些“打标模块”、否则等“结束之后是什么跳到父级的兄弟保存结果”Convert2ModuleNameTreeNode()就是把平铺列表变成一棵树让程序能回答上面这些问题。核心数据结构就两个东西StackModuleNameTreeNode— 一个栈栈顶永远指向当前我属于哪个父级ModuleNameTreeNode— 每个节点只存三样名字、父节点引用、子节点列表算法一步步模拟假设输入一维列表是[拍照] [如果瑕疵] [标记] [否则] [忽略] [结束] [保存]栈初始为空[]。逐个遍历步骤当前模块栈之前操作栈之后1拍照[]不是开始类型栈不变。父级BaseTreeNode根[]2如果瑕疵[]是如果→压栈。父级BaseTreeNode[如果]3标记[如果]不是开始类型。父级栈顶即如果[如果]4否则[如果]是否则→先弹栈结束如果分支再压栈。父级[]即根[否则]5忽略[否则]不是开始类型。父级栈顶即否则[否则]6结束[否则]是结束→弹栈。父级[]即根[]7保存[]不是开始类型。父级根[]最终构建出的树结构(根 BaseTreeNode) ├── 拍照 (Parent根) ├── 如果瑕疵 (Parent根, ChildList[标记]) │ └── 标记 (Parent如果) ├── 否则 (Parent根, ChildList[忽略]) │ └── 忽略 (Parent否则) ├── 结束 (Parent根) └── 保存 (Parent根)这东西实际怎么被使用的在项目执行的主循环中ModuleTreeNodeMap被频繁查询条件分支跳转— [Project.cs:595](/D:\JGTechVision\GJTechVisionV1.0.0\01_Sourse - 0604-2\VM\01Main\VM.Start\Services\Project.cs:595)ModuleTreeNodeMap[打标模块].Parent.ChildList → 得到 [标记, 否则, 忽略, 结束]条件失败时遍历这个列表跳过所有兄弟找到结束之后继续。循环跳转— [Project.cs:620](/D:\JGTechVision\GJTechVisionV1.0.0\01_Sourse - 0604-2\VM\01Main\VM.Start\Services\Project.cs:620)同理停止循环模块通过ModuleTreeNodeMap[name].Parent.Parent.ChildList找到循环结束的位置然后跳出。一句话总结把用户可视化的嵌套流程如果/否则/循环/文件夹翻译成代码能理解的树结构让执行引擎知道谁是谁的孩子、谁是谁的兄弟从而正确跳转。