C3031
2026-01-30 065674f3eea53cd84244dbb7ba1a994f86dde1ab
LB_VisionFlowNode/IFlowContext.cs
@@ -1,6 +1,7 @@
using LB_VisionProcesses;
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text.Json.Nodes;
@@ -20,7 +21,7 @@
        public string Group { get; set; }
        public string Description { get; set; }
    }
    public abstract class IFlowContext
    public class IFlowContext
    {
        public readonly Dictionary<string, MethodInfo> _nodeMethods
            = new Dictionary<string, MethodInfo>();
@@ -31,33 +32,10 @@
        public readonly Dictionary<string, Func<FlowNode, bool>> _nodeDelegates
            = new Dictionary<string, Func<FlowNode, bool>>();
        // 自动生成的插件节点方法信息
        public readonly Dictionary<string, PluginNodeMethodInfo> _pluginNodeMethods
            = new Dictionary<string, PluginNodeMethodInfo>();
        // 动态方法的包装(用于模拟MethodInfo)
        private readonly Dictionary<string, DynamicMethodWrapper> _dynamicMethodWrappers
            = new Dictionary<string, DynamicMethodWrapper>();
        // 是否已自动生成插件节点
        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<FlowNode, bool> 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<NodeAttribute>();
@@ -74,269 +52,28 @@
                    _groupedMethods[nodeAttr.Group].Add(method);
                }
            }
            // 2. 自动为IProcess工具生成动态节点方法
            GeneratePluginNodeMethods();
        }
        /// <summary>
        /// 自动为IProcess工具生成节点方法(核心方法)
        /// </summary>
        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<FlowNode, bool> 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<MethodInfo>();
                    }
                    _groupedMethods[group].Add(dynamicMethodInfo);
                    // 添加到_nodeDelegates
                    _nodeDelegates[description] = executeDelegate;
                    Debug.WriteLine($"自动生成插件节点: {toolName} (分类: {category}, 组: {group})");
                }
                _pluginNodesGenerated = true;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"自动生成插件节点方法失败: {ex.Message}");
            }
        }
        /// <summary>
        /// 使用Reflection.Emit生成动态MethodInfo,模拟Node特性方法
        /// </summary>
        /// <param name="toolName">工具名称</param>
        /// <param name="group">组名</param>
        /// <param name="description">描述</param>
        /// <returns>动态生成的MethodInfo</returns>
        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;
        }
        /// <summary>
        /// 根据工具名称推断分类(完善逻辑)
        /// </summary>
        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 "插件工具";
        }
        /// <summary>
        /// 根据分类确定组名
        /// </summary>
        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))
                {
                    // 带FlowNode参数的方法
                    var action = (Action<FlowNode>)Delegate.CreateDelegate(typeof(Action<FlowNode>), this, method);
                    _nodeDelegates[kvp.Key] = (node) => { action(node); return node.Result; };
                }
            }
            // 2. 确保动态方法的委托已添加(GeneratePluginNodeMethods中已处理)
        }
        public virtual bool ExecuteNode(FlowNode node)
@@ -344,7 +81,7 @@
            if (string.IsNullOrEmpty(node.Description))
                return false;
            // 优先检查动态委托
            // 使用委托缓存,避免反射开销
            if (_nodeDelegates.TryGetValue(node.Description, out var nodeDelegate))
            {
                try
@@ -358,7 +95,6 @@
                }
            }
            // 兼容原有逻辑
            return false;
        }
@@ -370,7 +106,7 @@
            );
        }
        // 获取按组分组的可用节点(包含动态生成的插件节点)
        // 获取按组分组的可用节点
        public Dictionary<string, List<ToolStripMenuItem>> GetGroupedMenuItems(EventHandler clickHandler)
        {
            var groupedMenuItems = new Dictionary<string, List<ToolStripMenuItem>>();
@@ -381,30 +117,12 @@
                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<NodeAttribute>();
                        menuText = nodeAttr?.Name ?? method.Name;
                        toolTip = nodeAttr?.Description ?? method.Name;
                    }
                    var nodeAttr = method.GetCustomAttribute<NodeAttribute>();
                    var menuItem = new ToolStripMenuItem
                    {
                        Text = menuText,
                        Tag = menuText, // 存储描述作为标识
                        ToolTipText = toolTip
                        Text = nodeAttr.Name,
                        Tag = nodeAttr.Description, // 存储描述作为标识
                        ToolTipText = nodeAttr.Description
                    };
                    if (clickHandler != null)
@@ -421,17 +139,15 @@
            return groupedMenuItems;
        }
        // 获取按类别分组的菜单项(包含动态生成的插件节点)
        // 获取按类别分组的菜单项
        public Dictionary<string, List<ToolStripMenuItem>> GetCategorizedMenuItems(EventHandler clickHandler)
        {
            var categorizedMethods = new Dictionary<string, List<MethodInfo>>();
            // 1. 处理原有Node方法
            foreach (var method in _nodeMethods.Values.Where(m => !(m is DynamicMethod)))
            foreach (var method in _nodeMethods.Values)
            {
                var nodeAttr = method.GetCustomAttribute<NodeAttribute>();
                if (nodeAttr == null) continue;
                if (!categorizedMethods.ContainsKey(nodeAttr.Category))
                {
                    categorizedMethods[nodeAttr.Category] = new List<MethodInfo>();
@@ -439,54 +155,20 @@
                categorizedMethods[nodeAttr.Category].Add(method);
            }
            // 2. 处理动态插件方法
            foreach (var pluginNode in _pluginNodeMethods.Values)
            {
                if (!categorizedMethods.ContainsKey(pluginNode.Category))
                {
                    categorizedMethods[pluginNode.Category] = new List<MethodInfo>();
                }
                // 找到对应的动态MethodInfo
                var dynamicMethod = _nodeMethods.Values
                    .OfType<DynamicMethod>()
                    .FirstOrDefault(m => m.Name == pluginNode.DisplayName);
                if (dynamicMethod != null)
                {
                    categorizedMethods[pluginNode.Category].Add(dynamicMethod);
                }
            }
            // 生成菜单项
            var categorizedMenuItems = new Dictionary<string, List<ToolStripMenuItem>>();
            foreach (var category in categorizedMethods)
            {
                var menuItems = new List<ToolStripMenuItem>();
                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<NodeAttribute>();
                        menuText = nodeAttr?.Name ?? method.Name;
                        toolTip = $"{nodeAttr?.Group} - {nodeAttr?.Description}";
                    }
                    var nodeAttr = method.GetCustomAttribute<NodeAttribute>();
                    var menuItem = new ToolStripMenuItem
                    {
                        Text = menuText,
                        Tag = menuText,
                        ToolTipText = toolTip
                        Text = nodeAttr.Name,
                        Tag = nodeAttr.Description,
                        ToolTipText = $"{nodeAttr.Group} - {nodeAttr.Description}"
                    };
                    if (clickHandler != null)
@@ -503,7 +185,6 @@
            return categorizedMenuItems;
        }
        // 原有Node方法
        [Node("开始", "控制", "Logic", "开始")]
        public virtual void 开始(FlowNode node) { node.Result = true; }
@@ -538,7 +219,6 @@
        [Node("并行分支结束", "控制", "Logic", "并行分支结束")]
        public virtual void 并行分支结束(FlowNode node) { node.Result = true; }
    }
    public class FlowContext : IFlowContext
    {
        /// <summary>
@@ -573,9 +253,11 @@
        public FlowContext()
        {
            //GenerateFixedNodeMethods();
            InitializeMethods();
            InitializeDelegates();
        }
        // 统一的动态节点执行辅助方法(可选)
        private void RunNodeAsync(FlowNode node)
@@ -592,6 +274,20 @@
                Result = false;
            }
        }
        #region 注册工具事件
        [Node("相机取图", "取像工具", "Basic", "相机取图")]
        public void 相机取图(FlowNode node) { RunNodeAsync(node); }
        [Node("Halcon2D斑点工具", "Haclon2D工具", "Basic", "Halcon2D斑点工具")]
        public void Halcon2D斑点工具(FlowNode node) { RunNodeAsync(node); }
        [Node("通讯模块", "通讯模块工具", "Basic", "通讯模块")]
        public void 通讯模块(FlowNode node) { RunNodeAsync(node); }
        #endregion
        // 重写原有Node方法,添加业务逻辑
        [Node("开始", "控制", "Logic", "开始")]
@@ -672,9 +368,6 @@
            }
        }
        // 保留原有测试方法(可选,也可以移除,由动态生成替代)
        [Node("测试工具", "算法", "Basic", "测试工具")]
        public void 测试工具(FlowNode node) { RunNodeAsync(node); }
    }
}