using LB_VisionProcesses; using System; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Text.Json.Nodes; using System.Threading; using static System.Windows.Forms.VisualStyles.VisualStyleElement.TreeView; namespace LB_VisionFlowNode { /// /// 插件节点方法信息 /// public class PluginNodeMethodInfo { public string DisplayName { get; set; } public string FullTypeName { get; set; } public string Category { get; set; } public string Group { get; set; } public string Description { get; set; } } public abstract class IFlowContext { public readonly Dictionary _nodeMethods = new Dictionary(); public readonly Dictionary> _groupedMethods = new Dictionary>(); public readonly Dictionary> _nodeDelegates = new Dictionary>(); // 自动生成的插件节点方法信息 public readonly Dictionary _pluginNodeMethods = new Dictionary(); // 动态方法的包装(用于模拟MethodInfo) private readonly Dictionary _dynamicMethodWrappers = new Dictionary(); // 是否已自动生成插件节点 private bool _pluginNodesGenerated = false; // 动态方法包装类 public class DynamicMethodWrapper { public string DisplayName { get; set; } public string Category { get; set; } public string Group { get; set; } public string Description { get; set; } public Func Execute { get; set; } // 模拟MethodInfo的必要属性 public string Name => DisplayName; } public void InitializeMethods() { // 1. 先处理自身的Node特性方法 var methods = GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance); foreach (var method in methods) { var nodeAttr = method.GetCustomAttribute(); if (nodeAttr != null) { // 使用描述作为键值 _nodeMethods[nodeAttr.Description] = method; // 按组分类 if (!_groupedMethods.ContainsKey(nodeAttr.Group)) { _groupedMethods[nodeAttr.Group] = new List(); } _groupedMethods[nodeAttr.Group].Add(method); } } // 2. 自动为IProcess工具生成动态节点方法 GeneratePluginNodeMethods(); } /// /// 自动为IProcess工具生成节点方法(核心方法) /// private void GeneratePluginNodeMethods() { if (_pluginNodesGenerated) return; try { // 确保IProcess的插件管理器已初始化 if (IProcess.dicProcesses == null || IProcess.dicProcesses.Count == 0) { var _ = IProcess.dicProcesses; // 触发初始化 } // 清空现有的插件节点方法 _pluginNodeMethods.Clear(); _dynamicMethodWrappers.Clear(); // 遍历所有IProcess工具 foreach (var processKvp in IProcess.dicProcesses) { string toolName = processKvp.Key; string className = processKvp.Value; // 获取工具的分类 string category = GetCategoryForTool(toolName); string group = GetGroupForCategory(category); // 根据分类确定组 string description = $"{toolName}"; // 创建插件节点方法信息 var pluginNode = new PluginNodeMethodInfo { DisplayName = toolName, FullTypeName = className, Category = category, Group = group, Description = description }; _pluginNodeMethods[toolName] = pluginNode; // 创建动态执行委托 Func executeDelegate = (node) => { try { // 创建IProcess实例 IProcess process = IProcess.CreateProcess(toolName); if (process == null) { Debug.WriteLine($"无法创建工具实例: {toolName}"); node.Result = false; return false; } // 初始化运行参数 process.InitRunParams(); // 执行工具的Run方法 bool runResult = process.Run(); // 设置节点结果 node.Result = runResult; node.BranchIndex = "0"; // 默认分支 // 释放资源 process.Dispose(); Debug.WriteLine($"插件工具 {toolName} 执行完成,结果: {runResult}"); return runResult; } catch (Exception ex) { Debug.WriteLine($"插件工具 {toolName} 执行失败: {ex.Message}"); node.Result = false; return false; } }; // 创建动态方法包装 var dynamicMethod = new DynamicMethodWrapper { DisplayName = toolName, Category = category, Group = group, Description = description, Execute = executeDelegate }; _dynamicMethodWrappers[description] = dynamicMethod; // ********** 关键:将动态方法添加到_nodeMethods和_groupedMethods ********** // 方式:生成动态MethodInfo(使用Emit),或者模拟(这里用Emit生成真实的MethodInfo) MethodInfo dynamicMethodInfo = CreateDynamicMethod(toolName, group, description); // 添加到_nodeMethods(键是description) _nodeMethods[description] = dynamicMethodInfo; // 添加到_groupedMethods if (!_groupedMethods.ContainsKey(group)) { _groupedMethods[group] = new List(); } _groupedMethods[group].Add(dynamicMethodInfo); // 添加到_nodeDelegates _nodeDelegates[description] = executeDelegate; Debug.WriteLine($"自动生成插件节点: {toolName} (分类: {category}, 组: {group})"); } _pluginNodesGenerated = true; } catch (Exception ex) { Debug.WriteLine($"自动生成插件节点方法失败: {ex.Message}"); } } /// /// 使用Reflection.Emit生成动态MethodInfo,模拟Node特性方法 /// /// 工具名称 /// 组名 /// 描述 /// 动态生成的MethodInfo private MethodInfo CreateDynamicMethod(string toolName, string group, string description) { // 1. 定义动态方法的参数和返回类型 Type flowNodeType = typeof(FlowNode); DynamicMethod dynamicMethod = new DynamicMethod( toolName, // 方法名 typeof(void), // 返回类型(和原有Node方法一致) new[] { typeof(FlowNode) }, // 参数类型 GetType(), // 所属类型 true); // 跳过JIT可见性检查 // 2. 生成IL代码,调用动态委托 ILGenerator il = dynamicMethod.GetILGenerator(); // 加载参数(FlowNode) il.Emit(OpCodes.Ldarg_1); // 注意:实例方法的第一个参数是this(Ldarg_0),这里动态方法是静态的,所以Ldarg_0是FlowNode // 调用委托(这里简化,直接设置Result为true) il.Emit(OpCodes.Ldflda, flowNodeType.GetProperty("Result").GetSetMethod()); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Callvirt, flowNodeType.GetProperty("Result").GetSetMethod()); // 设置BranchIndex il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldflda, flowNodeType.GetProperty("BranchIndex").GetSetMethod()); il.Emit(OpCodes.Ldstr, "0"); il.Emit(OpCodes.Callvirt, flowNodeType.GetProperty("BranchIndex").GetSetMethod()); // 返回 il.Emit(OpCodes.Ret); // 3. 将DynamicMethod包装为MethodInfo(DynamicMethod继承自MethodInfo) return dynamicMethod; } /// /// 根据工具名称推断分类(完善逻辑) /// private string GetCategoryForTool(string toolName) { if (string.IsNullOrWhiteSpace(toolName)) return "未分类"; toolName = toolName.ToLower(); if (toolName.Contains("相机") || toolName.Contains("取图")) return "相机工具"; else if (toolName.Contains("通讯") || toolName.Contains("command")) return "通讯工具"; else if (toolName.Contains("opencvsharp")) return "OpencvSharp算法"; else if (toolName.Contains("halcon")) return "Halcon算法"; else if (toolName.Contains("yolo") || toolName.Contains("tensorrt") || toolName.Contains("ocr") || toolName.Contains("deeplearning") || toolName.Contains("大模型")) return "深度学习"; else if (toolName.Contains("图像处理") || toolName.Contains("点云") || toolName.Contains("线线交点")) return "图像处理工具"; else if (toolName.Contains("测试") || toolName.Contains("检查") || toolName.Contains("端口") || toolName.Contains("屏幕") || toolName.Contains("工序") || toolName.Contains("转产")) return "自定义工具"; else if (toolName.Contains("脚本") || toolName.Contains("分支") || toolName.Contains("延时") || toolName.Contains("绘制")) return "工具"; else if (toolName.Contains("固定跟随") || toolName.Contains("fixture")) return "工具"; else return "插件工具"; } /// /// 根据分类确定组名 /// private string GetGroupForCategory(string category) { switch (category) { case "通讯工具": return "Basic"; case "算法": return "Basic"; case "深度学习": return "Basic"; case "图像处理工具": return "Basic"; case "自定义工具": return "Basic"; case "工具": return "Basic"; default: return "Plugin"; } } public void InitializeDelegates() { // 1. 处理自身的Node方法 foreach (var kvp in _nodeMethods) { var method = kvp.Value; var parameters = method.GetParameters(); //如果是动态方法(DynamicMethod),跳过(已经在GeneratePluginNodeMethods中添加了委托) if (method is DynamicMethod) { // 从动态方法包装中获取对应的委托 if (_dynamicMethodWrappers.TryGetValue(kvp.Key, out var wrapper)) { // 直接使用包装中的Execute委托 _nodeDelegates[kvp.Key] = wrapper.Execute; } else { // 如果没有找到包装,创建一个默认的执行委托 _nodeDelegates[kvp.Key] = (node) => { Debug.WriteLine($"执行动态方法: {kvp.Key}"); node.Result = true; node.BranchIndex = "0"; return true; }; } continue; } if (parameters.Length == 0) { var action = (Action)Delegate.CreateDelegate(typeof(Action), this, method); _nodeDelegates[kvp.Key] = (node) => { action(); return node.Result; }; } else if (parameters.Length == 1 && parameters[0].ParameterType == typeof(FlowNode)) { var action = (Action)Delegate.CreateDelegate(typeof(Action), this, method); _nodeDelegates[kvp.Key] = (node) => { action(node); return node.Result; }; } } // 2. 确保动态方法的委托已添加(GeneratePluginNodeMethods中已处理) } public virtual bool ExecuteNode(FlowNode node) { if (string.IsNullOrEmpty(node.Description)) return false; // 优先检查动态委托 if (_nodeDelegates.TryGetValue(node.Description, out var nodeDelegate)) { try { return nodeDelegate(node); } catch (Exception ex) { Debug.WriteLine($"执行节点失败: {ex.Message}"); return false; } } // 兼容原有逻辑 return false; } public Dictionary GetAvailableNodes() { return _nodeMethods.ToDictionary( kvp => kvp.Key, kvp => kvp.Value ); } // 获取按组分组的可用节点(包含动态生成的插件节点) public Dictionary> GetGroupedMenuItems(EventHandler clickHandler) { var groupedMenuItems = new Dictionary>(); foreach (var group in _groupedMethods) { var menuItems = new List(); foreach (var method in group.Value) { string menuText; string toolTip; // 判断是静态方法还是动态方法 if (method is DynamicMethod dynamicMethod) { // 动态方法(插件工具) var pluginNode = _pluginNodeMethods.Values.FirstOrDefault(p => p.DisplayName == dynamicMethod.Name); menuText = pluginNode?.DisplayName ?? dynamicMethod.Name; toolTip = pluginNode?.Description ?? $"动态工具: {dynamicMethod.Name}"; } else { // 静态方法(原有Node特性方法) var nodeAttr = method.GetCustomAttribute(); menuText = nodeAttr?.Name ?? method.Name; toolTip = nodeAttr?.Description ?? method.Name; } var menuItem = new ToolStripMenuItem { Text = menuText, Tag = menuText, // 存储描述作为标识 ToolTipText = toolTip }; if (clickHandler != null) { menuItem.Click += clickHandler; } menuItems.Add(menuItem); } groupedMenuItems[group.Key] = menuItems; } return groupedMenuItems; } // 获取按类别分组的菜单项(包含动态生成的插件节点) public Dictionary> GetCategorizedMenuItems(EventHandler clickHandler) { var categorizedMethods = new Dictionary>(); // 1. 处理原有Node方法 foreach (var method in _nodeMethods.Values.Where(m => !(m is DynamicMethod))) { var nodeAttr = method.GetCustomAttribute(); if (nodeAttr == null) continue; if (!categorizedMethods.ContainsKey(nodeAttr.Category)) { categorizedMethods[nodeAttr.Category] = new List(); } categorizedMethods[nodeAttr.Category].Add(method); } // 2. 处理动态插件方法 foreach (var pluginNode in _pluginNodeMethods.Values) { if (!categorizedMethods.ContainsKey(pluginNode.Category)) { categorizedMethods[pluginNode.Category] = new List(); } // 找到对应的动态MethodInfo var dynamicMethod = _nodeMethods.Values .OfType() .FirstOrDefault(m => m.Name == pluginNode.DisplayName); if (dynamicMethod != null) { categorizedMethods[pluginNode.Category].Add(dynamicMethod); } } // 生成菜单项 var categorizedMenuItems = new Dictionary>(); foreach (var category in categorizedMethods) { var menuItems = new List(); foreach (var method in category.Value) { string menuText; string toolTip; if (method is DynamicMethod dynamicMethod) { var pluginNode = _pluginNodeMethods.Values.FirstOrDefault(p => p.DisplayName == dynamicMethod.Name); menuText = pluginNode?.DisplayName ?? dynamicMethod.Name; toolTip = pluginNode?.Description ?? $"动态工具: {dynamicMethod.Name}"; } else { var nodeAttr = method.GetCustomAttribute(); menuText = nodeAttr?.Name ?? method.Name; toolTip = $"{nodeAttr?.Group} - {nodeAttr?.Description}"; } var menuItem = new ToolStripMenuItem { Text = menuText, Tag = menuText, ToolTipText = toolTip }; if (clickHandler != null) { menuItem.Click += clickHandler; } menuItems.Add(menuItem); } categorizedMenuItems[category.Key] = menuItems; } return categorizedMenuItems; } // 原有Node方法 [Node("开始", "控制", "Logic", "开始")] public virtual void 开始(FlowNode node) { node.Result = true; } [Node("结束", "控制", "Logic", "结束")] public virtual void 结束(FlowNode node) { node.Result = true; } [Node("分支", "控制", "Logic", "分支")] public virtual void 分支(FlowNode node) { node.Result = true; } [Node("多分支", "控制", "Logic", "多分支")] public virtual void 多分支(FlowNode node) { node.Result = true; } [Node("并行分支开始", "控制", "Logic", "并行分支开始")] public virtual void 并行分支开始(FlowNode node) { string ProcessName = node.Text; node.BranchIndex = "-1"; try { for (int i = 0; i < node.BranchNodes.Count; i++) { if (i == 0) node.BranchIndex = "0;"; else node.BranchIndex += $"{i.ToString()};"; } node.Result = true; } catch { node.Result = false; } } [Node("并行分支结束", "控制", "Logic", "并行分支结束")] public virtual void 并行分支结束(FlowNode node) { node.Result = true; } } public class FlowContext : IFlowContext { /// /// 运行标记 /// public bool bRuning = false; /// /// 运行完成 /// public bool bCompleted = true; /// /// 运行结果 /// public bool Result = false; /// /// 运行消息 /// public string Msg = string.Empty; /// /// 运行时间 /// public double RunTime = 0; /// /// 开始时间 /// public DateTime StartTime = DateTime.Now; public FlowContext() { InitializeMethods(); InitializeDelegates(); } // 统一的动态节点执行辅助方法(可选) private void RunNodeAsync(FlowNode node) { // 调用基类的ExecuteNode node.Result = ExecuteNode(node); if (node.Result) { Debug.WriteLine($"{node.Text} 运行完成"); } else { Msg += $"[{node.Text}] 运行失败"; Result = false; } } // 重写原有Node方法,添加业务逻辑 [Node("开始", "控制", "Logic", "开始")] public override void 开始(FlowNode node) { StartTime = DateTime.Now; RunTime = 0; Result = true; bRuning = true; bCompleted = false; Msg = string.Empty; node.Result = true; } [Node("结束", "控制", "Logic", "结束")] public override void 结束(FlowNode node) { bRuning = false; bCompleted = true; if (Result) Msg = "运行成功"; RunTime = (DateTime.Now - StartTime).TotalMilliseconds; node.Result = true; } [Node("分支", "控制", "Logic", "分支")] public override void 分支(FlowNode node) { string ProcessName = node.Text; node.BranchIndex = "-1"; node.Result = true; try { if (node.Break) { node.BranchIndex = "0"; node.Result = true; return; } node.BranchIndex = 0.ToString(); Debug.WriteLine($"{ProcessName},分支{node.BranchIndex}运行完成"); } catch (Exception ex) { node.Result = false; Result &= false; Msg = $"[{ProcessName}]运行发生意外,{ex.Message}"; } } [Node("多分支", "控制", "Logic", "多分支")] public override void 多分支(FlowNode node) { string ProcessName = node.Text; node.BranchIndex = "-1"; node.Result = true; try { if (node.Break) { node.BranchIndex = "0"; node.Result = true; return; } node.BranchIndex = 0.ToString(); Debug.WriteLine($"{ProcessName},分支{node.BranchIndex}运行完成"); } catch (Exception ex) { node.Result = false; Result &= false; Msg = $"[{ProcessName}]运行发生意外,{ex.Message}"; } } // 保留原有测试方法(可选,也可以移除,由动态生成替代) [Node("测试工具", "算法", "Basic", "测试工具")] public void 测试工具(FlowNode node) { RunNodeAsync(node); } } }