using System.Diagnostics;
|
using System.Reflection;
|
using System.Text.Json.Nodes;
|
using System.Threading;
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TreeView;
|
|
namespace LB_VisionFlowNode
|
{
|
public class IFlowContext
|
{
|
public readonly Dictionary<string, MethodInfo> _nodeMethods
|
= new Dictionary<string, MethodInfo>();
|
|
public readonly Dictionary<string, List<MethodInfo>> _groupedMethods
|
= new Dictionary<string, List<MethodInfo>>();
|
|
public readonly Dictionary<string, Func<FlowNode, bool>> _nodeDelegates
|
= new Dictionary<string, Func<FlowNode, bool>>();
|
|
public void InitializeMethods()
|
{
|
var methods = GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance);
|
|
foreach (var method in methods)
|
{
|
var nodeAttr = method.GetCustomAttribute<NodeAttribute>();
|
if (nodeAttr != null)
|
{
|
// 使用描述作为键值
|
_nodeMethods[nodeAttr.Description] = method;
|
|
// 按组分类
|
if (!_groupedMethods.ContainsKey(nodeAttr.Group))
|
{
|
_groupedMethods[nodeAttr.Group] = new List<MethodInfo>();
|
}
|
_groupedMethods[nodeAttr.Group].Add(method);
|
}
|
}
|
}
|
|
public void InitializeDelegates()
|
{
|
foreach (var kvp in _nodeMethods)
|
{
|
var method = kvp.Value;
|
var parameters = method.GetParameters();
|
|
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; };
|
}
|
}
|
}
|
|
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<string, MethodInfo> GetAvailableNodes()
|
{
|
return _nodeMethods.ToDictionary(
|
kvp => kvp.Key,
|
kvp => kvp.Value
|
);
|
}
|
|
// 获取按组分组的可用节点
|
public Dictionary<string, List<ToolStripMenuItem>> GetGroupedMenuItems(EventHandler clickHandler)
|
{
|
var groupedMenuItems = new Dictionary<string, List<ToolStripMenuItem>>();
|
|
foreach (var group in _groupedMethods)
|
{
|
var menuItems = new List<ToolStripMenuItem>();
|
|
foreach (var method in group.Value)
|
{
|
var nodeAttr = method.GetCustomAttribute<NodeAttribute>();
|
var menuItem = new ToolStripMenuItem
|
{
|
Text = nodeAttr.Name,
|
Tag = nodeAttr.Description, // 存储描述作为标识
|
ToolTipText = nodeAttr.Description
|
};
|
|
if (clickHandler != null)
|
{
|
menuItem.Click += clickHandler;
|
}
|
|
menuItems.Add(menuItem);
|
}
|
|
groupedMenuItems[group.Key] = menuItems;
|
}
|
|
return groupedMenuItems;
|
}
|
|
|
// 获取按类别分组的菜单项
|
public Dictionary<string, List<ToolStripMenuItem>> GetCategorizedMenuItems(EventHandler clickHandler)
|
{
|
var categorizedMethods = new Dictionary<string, List<MethodInfo>>();
|
|
foreach (var method in _nodeMethods.Values)
|
{
|
var nodeAttr = method.GetCustomAttribute<NodeAttribute>();
|
if (!categorizedMethods.ContainsKey(nodeAttr.Category))
|
{
|
categorizedMethods[nodeAttr.Category] = new List<MethodInfo>();
|
}
|
categorizedMethods[nodeAttr.Category].Add(method);
|
}
|
|
var categorizedMenuItems = new Dictionary<string, List<ToolStripMenuItem>>();
|
|
foreach (var category in categorizedMethods)
|
{
|
var menuItems = new List<ToolStripMenuItem>();
|
|
foreach (var method in category.Value)
|
{
|
var nodeAttr = method.GetCustomAttribute<NodeAttribute>();
|
var menuItem = new ToolStripMenuItem
|
{
|
Text = nodeAttr.Name,
|
Tag = nodeAttr.Description,
|
ToolTipText = $"{nodeAttr.Group} - {nodeAttr.Description}"
|
};
|
|
if (clickHandler != null)
|
{
|
menuItem.Click += clickHandler;
|
}
|
|
menuItems.Add(menuItem);
|
}
|
|
categorizedMenuItems[category.Key] = menuItems;
|
}
|
|
return categorizedMenuItems;
|
}
|
|
[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
|
{
|
/// <summary>
|
/// 运行标记
|
/// </summary>
|
public bool bRuning = false;
|
|
/// <summary>
|
/// 运行完成
|
/// </summary>
|
public bool bCompleted = true;
|
|
/// <summary>
|
/// 运行结果
|
/// </summary>
|
public bool Result = false;
|
|
/// <summary>
|
/// 运行消息
|
/// </summary>
|
public string Msg = string.Empty;
|
|
/// <summary>
|
/// 运行时间
|
/// </summary>
|
public double RunTime = 0;
|
|
/// <summary>
|
/// 开始时间
|
/// </summary>
|
public DateTime StartTime = DateTime.Now;
|
|
|
public FlowContext()
|
{
|
InitializeMethods();
|
InitializeDelegates();
|
}
|
|
/// <summary>
|
/// 非分支节点的统一调用方式
|
/// </summary>
|
private void RunNodeAsync(FlowNode node)
|
{
|
// 走默认分支
|
node.BranchIndex = "0";
|
string ProcessName = node.Text;
|
try
|
{
|
MessageBox.Show($"{ProcessName},运行完成");
|
}
|
catch (Exception ex)
|
{
|
node.Result = false;
|
Result &= false;
|
Msg += $"[{ProcessName}]运行发生意外,{ex.Message}";
|
}
|
}
|
#region 相机工具
|
|
[Node("相机取图", "相机", "Basic", "相机取图")]
|
public void 相机取图(FlowNode node) { RunNodeAsync(node); }
|
|
|
#endregion
|
#region 通讯工具
|
[Node("通讯测试", "通讯", "Basic", "通讯测试")]
|
public void 通讯测试(FlowNode node) { RunNodeAsync(node); }
|
|
//[Node("西门子S7", "通讯", "Basic", "西门子S7")]
|
//public void 西门子S7(FlowNode node) { RunNodeAsync(node); }
|
|
|
[Node("T306通讯", "通讯", "Basic", "T306通讯")]
|
public void T306通讯(FlowNode node) { RunNodeAsync(node); }
|
#endregion
|
|
#region Halcon2D算法
|
[Node("Halcon2D_模板匹配工具", "Halcon2D算法", "Basic", "Halcon2D_模板匹配工具")]
|
public void Halcon2D_模板匹配工具(FlowNode node) { RunNodeAsync(node); }
|
|
[Node("Halcon2D_多模板匹配工具", "Halcon2D算法", "Basic", "Halcon2D_多模板匹配工具")]
|
public void Halcon2D_多模板匹配工具(FlowNode node) { RunNodeAsync(node); }
|
|
[Node("Halcon2D_斑点工具", "Halcon2D算法", "Basic", "Halcon2D_斑点工具")]
|
public void Halcon2D_斑点工具(FlowNode node) { RunNodeAsync(node); }
|
|
[Node("Halcon2D_读码工具", "Halcon2D算法", "Basic", "Halcon2D_读码工具")]
|
public void Halcon2D_读码工具(FlowNode node) { RunNodeAsync(node); }
|
|
[Node("Halcon2D_找线工具", "Halcon2D算法", "Basic", "Halcon2D_找线工具")]
|
public void Halcon2D_找线工具(FlowNode node) { RunNodeAsync(node); }
|
#endregion
|
|
#region 分割模型
|
|
[Node("语义分割工具", "BigModel", "Basic", "语义分割工具")]
|
public void 语义分割工具(FlowNode node) { RunNodeAsync(node); }
|
|
#endregion
|
|
#region OpenCvSharp算法
|
[Node("OpenCvSharp_模板匹配工具", "OpenCvSharp算法", "Basic", "OpenCvSharp_模板匹配工具")]
|
public void OpenCvSharp_模板匹配工具(FlowNode node) { RunNodeAsync(node); }
|
|
[Node("OpenCvSharp_斑点工具", "OpenCvSharp算法", "Basic", "OpenCvSharp_斑点工具")]
|
public void OpenCvSharp_斑点工具(FlowNode node) { RunNodeAsync(node); }
|
|
[Node("OpenCvSharp_找线工具", "OpenCvSharp算法", "Basic", "OpenCvSharp_找线工具")]
|
public void OpenCvSharp_找线工具(FlowNode node) { RunNodeAsync(node); }
|
#endregion
|
|
#region 图像处理工具
|
[Node("单图像处理工具", "图像处理工具", "Basic", "单图像处理工具")]
|
public void 单图像处理工具(FlowNode node) { RunNodeAsync(node); }
|
|
[Node("点云转换工具", "图像处理工具", "Basic", "点云转换工具")]
|
public void 点云转换工具(FlowNode node) { RunNodeAsync(node); }
|
|
[Node("线线交点工具", "图像处理工具", "Basic", "线线交点工具")]
|
public void 线线交点工具(FlowNode node) { RunNodeAsync(node); }
|
#endregion
|
|
|
[Node("脚本", "工具", "Basic", "脚本")]
|
public void 脚本(FlowNode node) { RunNodeAsync(node); }
|
|
[Node("延时", "工具", "Basic", "延时")]
|
public void 延时(FlowNode node) { RunNodeAsync(node); }
|
|
[Node("创建固定跟随", "工具", "Basic", "创建固定跟随")]
|
public void 创建固定跟随(FlowNode node) { RunNodeAsync(node); }
|
|
[Node("开始", "控制", "Logic", "开始")]
|
public override void 开始(FlowNode node)
|
{
|
StartTime = DateTime.Now;
|
RunTime = 0;
|
|
Result = true;
|
bRuning = true;
|
bCompleted = false;
|
Msg = string.Empty;
|
}
|
|
[Node("结束", "控制", "Logic", "结束")]
|
public override void 结束(FlowNode node)
|
{
|
bRuning = false;
|
bCompleted = true;
|
|
if (Result)
|
Msg = "运行成功";
|
|
RunTime = (DateTime.Now - StartTime).TotalMilliseconds;
|
}
|
|
[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();
|
MessageBox.Show($"{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();
|
MessageBox.Show($"{ProcessName},分支{node.BranchIndex}运行完成");
|
}
|
catch (Exception ex)
|
{
|
node.Result = false;
|
Result &= false;
|
Msg = $"[{ProcessName}]运行发生意外,{ex.Message}";
|
}
|
}
|
|
[Node("测试工具", "算法", "Basic", "测试工具")]
|
public void 测试工具(FlowNode node) { RunNodeAsync(node); }
|
}
|
}
|