当前位置: 首页 > news >正文

LogicMethod讲解

LogicMethod()

内容按四种场景拆开讲:

  1. 条件分支如果失败跳到下一个否则如果/否则/结束;成功后跳过剩余的 else 链
  2. 循环工具循环开始失败时跳出循环体;循环结束时回头重跑
  3. 停止循环— 循环体内的 break,找到最近的循环结束并停掉对应的循环开始
  4. 末尾跳过 else— 当动作执行成功后,自动跳过跟在后面的所有否则如果否则

每个场景都配了流程图示意,最后的总结图把四个判断的入口和跳转方向画在一起了。核心就是两样东西:ModuleTreeNodeMap树结构(告诉你谁是谁的兄弟),以及ExeModuleName+IsNextModuleUpdate(告示主循环接下来该往哪走)。

它在哪里被调用?

每次执行完一个模块后,主循环会问 LogicMethod:「接下来我应该执行哪个模块?」

┌─────────────────────────────────────────────┐ │ 主循环 (while true): │ │ 1. 执行当前模块 → 拿到 flag (成功/失败) │ │ 2. 调用 LogicMethod(flag) │ │ 3. LogicMethod 可能会改写 ExeModuleName │ │ 4. 如果 LogicMethod 没改写, 默认走下一个 │ │ 5. 重复 │ └─────────────────────────────────────────────┘

LogicMethod 通过改写ExeModuleName(下一步执行谁)和IsNextModuleUpdate(是否允许改写)来控制跳转。

如果IsNextModuleUpdate = false:LogicMethod 放弃干预,让主循环默认走扁平列表的下一个。
如果IsNextModuleUpdate = true:LogicMethod 说「听我的」,主循环就用它改过的ExeModuleName


四种判断,逐个击破

LogicMethod 内部就干四件事,按顺序判断:

1. 条件分支(如果你/否则如果/否则/结束)

用户拖出来的流程: ┌──────────────┐ │ 如果 检测到瑕疵 │ ← 条件A ├──────────────┤ │ 打标瑕疵 │ ← 动作A(条件A的孩子) ├──────────────┤ │ 否则如果 尺寸NG │ ← 条件B ├──────────────┤ │ 报警 │ ← 动作B(条件B的孩子) ├──────────────┤ │ 否则 │ ← 兜底 ├──────────────┤ │ 忽略 │ ← 动作C(否则的孩子) ├──────────────┤ │ 结束 │ └──────────────┘

情况A:条件失败 (flag=false)

如果当前是 “如果” 且执行结果是 false,LogicMethod 做这件事:

  1. 通过ModuleTreeNodeMap[当前模块].Parent.ChildList拿到同级兄弟列表
  2. 从自己的位置往后扫,找到最近的一个「否则如果」「否则」或「结束」
  3. 直接跳到那里
如果检测到瑕疵 (flag=false) → 跳转到 "否则如果尺寸NG" 否则如果尺寸NG (flag=false) → 跳转到 "否则"

就像电梯一样,按「关门」键不会每层都停,直接到下一个有效层。

情况B:条件成功 (flag=true)

条件成功后执行完动作模块(如 “打标瑕疵”),LogicMethod 发现下一个扁平模块是「否则如果」或「否则」,就知道该跳过剩余的分支了——跳转到「结束」。

打标瑕疵 (flag=true) → 跳过 "否则如果" "动作B" "否则" "动作C" → 跳转到 "结束"

这是 LogicMethod 末尾那一段if (moduleParam.PluginName != "条件分支" || flag == true)做的事。


2. 循环工具(循环开始 / 循环结束)

用户拖出来的流程: ┌──────────────┐ │ 循环开始(3次) │ ← 循环体从这里开始 ├──────────────┤ │ 拍照 │ ← 循环体内的模块 ├──────────────┤ │ 检测 │ ← 循环体内的模块 ├──────────────┤ │ 循环结束 │ ← 循环体在这里回头 └──────────────┘ │ ▼ 循环结束后继续往下走

情况A:循环开始失败或被禁用

如果 “循环开始” 返回 false(比如循环次数到了),或者模块被禁用了:

  1. 拿到同级兄弟列表
  2. 往后找到 “循环结束”
  3. 跳到 “循环结束”
  4. IsNextModuleUpdate = false(故意设 false)

注意最后一步很巧妙:设 false 意味着 “循环结束” 执行完后,走默认的「下一个」,也就是循环体外面的模块——完美退出循环。

情况B:循环结束——回头重来

当执行到 “循环结束”:

  1. 拿到同级兄弟列表
  2. 往前找到 “循环开始”
  3. 跳回去
  4. IsNextModuleUpdate = true(覆盖默认的下一个)

3. 停止循环(break)

这是循环体内的「立刻跳出」按钮,类似 C# 的break

┌──────────────┐ │ 文件夹开始 │ ├──────────────┤ │ 循环开始(10次) │ ├──────────────┤ │ 拍照 │ ├──────────────┤ │ 检测 │ ├──────────────┤ │ 停止循环 ←── │ 检测到OK就跳出,不等10次跑完 ├──────────────┤ │ 循环结束 │ ├──────────────┤ │ 文件夹结束 │ └──────────────┘

当执行到 “停止循环”:

  1. 检查有没有父级和祖父级(没有的话说明不在循环里,非法)
  2. 从父级位置往后扫,找 “循环结束”
  3. 如果先找到 “循环开始”(说明停止循环放错位置了),放弃
  4. 找到 “循环结束” → 跳过去
  5. 同时往前找最近的 “循环开始”,停止它的循环计数(让它不再迭代)
  6. IsNextModuleUpdate = false(让循环结束之后走外面)

4. 成功后跳过 else 链(末尾那段)

这是最后一段兜底逻辑,处理一个常见场景:

如果条件A (true) 动作A ← 执行成功 否则 ← 应该跳过! 动作B 否则 ← 也应该跳过! 动作C 结束

当 “动作A” 执行成功,LogicMethod 发现扁平列表的下一个是「否则」,就通过Parent.Parent.ChildList找到 “结束”,跳过去。

如果当前模块本身就是条件分支(如 “如果”),且 flag=true,也一样:下一个是「否则如果」就直接跳到「结束」。


一张图总结全流程

执行完一个模块 │ ▼ ┌─────────────────────┐ │ LogicMethod() │ └─────────────────────┘ │ ┌───────────────┼───────────────┐ ▼ ▼ ▼ 是条件分支? 是循环工具? 是停止循环? │ │ │ ┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐ │失败→跳到 │ │开始失败→ │ │跳到循环结束│ │下一个否则/ │ │跳到循环结束│ │并停止循环 │ │结束 │ │ │ │开始 │ │ │ │结束→回头 │ │ │ │成功→末尾 │ │到循环开始 │ │ │ │跳过else │ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ │ ▼ ┌─────────────────────┐ │ 末尾检查: 成功时 │ │ 跳过否则/否则如果 │ └─────────────────────┘ │ ▼ 主循环根据 IsNextModuleUpdate 决定用新 ExeModuleName 还是默认下一个

为什么注释说「不要轻易修改」?

因为这个方法处理了四种控制流的六种跳转场景,而且它们可以嵌套——循环里可以有 if,if 里可以有循环,停止循环可以在多层嵌套里。每改一个跳转逻辑,就可能破坏另一个场景。

理解它的关键在于牢记两样东西:

  • ModuleTreeNodeMap:告诉你谁是谁的爹、谁是谁的兄弟
  • ExeModuleName+IsNextModuleUpdate:LogicMethod 的输出,告诉主循环接下来该往哪走
http://www.gsyq.cn/news/1506950.html

相关文章:

  • 用STC89C52单片机解码家里遥控器:从NEC协议到电机调速的保姆级实战
  • 163MusicLyrics:高效歌词下载工具,轻松获取网易云和QQ音乐歌词
  • ShawzinBot终极指南:如何将MIDI音乐转换为Warframe游戏内演奏
  • 山东大学软件学院项目实训【个人8】
  • 15分钟搞定专业级黑苹果EFI配置:OpCore-Simplify终极指南
  • MPC7447A处理器硬件设计实战:从规格书解读到电源、时钟与热设计
  • Claude Fable 5 和 Opus 4.8 怎么选:性能、价格和场景一次讲清
  • 超越基础地图:用微信小程序map组件打造一个交互式区域标注工具
  • MPC852T PowerQUICC双核架构解析与嵌入式通信系统实战指南
  • 别再手动摆Off-Page了!用Tcl脚本给OrCAD Capture加个‘智能连线助手’(附完整源码)
  • P89LPC9408增强型51单片机:双时钟架构与低功耗设计实战
  • Keil5 C51项目里extern用错,ERROR L104报错怎么破?手把手教你正确声明全局变量
  • 一线通协议实战:从引脚中断到数据帧解析
  • 【无人机三维路径规划】基于蚁群算法ACO无人机三维路径规划(目标函数:最优成本 路径 高度 威胁 转角)附Matlab代码
  • 2026年 重庆化工原料厂家推荐榜单:元明粉/小苏打/硫酸镁/片碱(食品级)/纯碱/盐酸/硝酸/乙二醇等工业与食品级原料实力品牌 - 品牌发掘
  • 别只刷题了!蓝桥杯EDA设计与开发,客观题高分攻略与PCB工程师面试题解析
  • 如何高效获取网盘直链:一站式跨平台下载解决方案
  • 用Python打造你的专属密码生成器:从XKCD风格到命令行工具
  • 深入浅出解析Si24R1无线芯片:从寄存器配置到Arduino SPI驱动G01-S模块的底层逻辑
  • DDrawCompat终极指南:让Windows经典游戏在现代系统上完美运行
  • 解密FreeBSD 13.2上的OpenMP与ImageMagick问题
  • 企业级数据集成平台架构:基于Kettle的微服务化ETL解决方案
  • 技术深度解析:.NET MAUI Community Toolkit - 跨平台开发效率提升的10个实战案例
  • 如何在5分钟内掌握Vue Json Pretty:Vue.js JSON数据可视化终极指南
  • 汽车级LCD段码驱动芯片PCA8543:原理、配置与硬件设计实战
  • MPC8343EA时钟与热管理设计:从PLL配置到散热器选型实战
  • 如何实现个性化定制:Mi-Create 为小米穿戴设备打造专属表盘的完整指南
  • Figma中文界面汉化插件:5分钟告别英文设计障碍
  • 2026年重庆市场知名小程序开发公司,哪家才是可靠之选? - 资讯纵览
  • okbiye 论文降重降 AIGC:双维度优化破解高校双重检测关卡