using Newtonsoft.Json; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace LB_VisionFlowNode { [Serializable] public class FlowNode { // 用于标识节点的唯一ID [JsonProperty] public string Id { get; set; } = Guid.NewGuid().ToString(); [JsonProperty] public bool Result { get; set; } = true; [JsonProperty] public bool Break { get; set; } = false; [JsonProperty] public NodeType NodeType { get; set; } = NodeType.Normal; [JsonProperty] public string Text { get; set; } = "名称"; [JsonProperty] public string Description { get; set; } = "描述"; [JsonProperty] public string NextNodeId { get; set; } [JsonIgnore] public FlowNode NextNode { get; set; } = null; #region 分支流程相关 /// /// 多分支和并行节点的分支节点集合【Key: 分支名称, Value: 所链接的分支节点名称】 /// public ConcurrentDictionary BranchNodes { get; set; } = new ConcurrentDictionary(); [JsonProperty] public string BranchIndex { get; set; } = "0"; // 分支条件(可选) public Func BranchCondition { get; set; } // 超时设置(用于并行执行) public int TimeoutMilliseconds { get; set; } = 60000; #endregion public int X { get; set; } = 0; public int Y { get; set; } = 0; public int Width { get; set; } = 100; public int Height { get; set; } = 40; public Point LeftPoint { get { return new Point(X - Width / 2, Y); } } public Point RightPoint { get { return new Point(X + Width / 2, Y); } } public Point BtmPoint { get { return new Point(X, Y + Height / 2); } } public Point TopPoint { get { return new Point(X, Y - Height / 2); } } public Rectangle GetBounds() { return new Rectangle(X - Width / 2, Y - Height / 2, Width, Height); } public Color GetColor() { if (Break) return Color.Gray; return Result ? Color.LightGreen : Color.MediumVioletRed; } public List GetConnectionPoints() { List points = new List() { }; switch (NodeType) { case NodeType.Begin: points.Add(BtmPoint); break; case NodeType.End: points.Add(TopPoint); break; case NodeType.Switch: points.Add(TopPoint); points.Add(LeftPoint); points.Add(RightPoint); break; case NodeType.MultiBranch: case NodeType.Parallel: points.Add(TopPoint); int branchCount = BranchNodes.Count; if (branchCount == 0) break; int spacing = Width / (branchCount + 1); for (int i = 1; i <= branchCount; i++) points.Add(new Point(X - Width / 2 + i * spacing, Y + Height / 2)); break; case NodeType.Join: case NodeType.Normal: points.Add(TopPoint); points.Add(BtmPoint); break; default: break; } return points; } public Point GetBranchPoints(int index) { List points = new List() { }; switch (NodeType) { case NodeType.Begin: points.Add(BtmPoint); break; case NodeType.End: break; case NodeType.Switch: points.Add(LeftPoint); points.Add(RightPoint); break; case NodeType.MultiBranch: case NodeType.Parallel: int branchCount = BranchNodes.Count; if (branchCount == 0) break; int spacing = Width / (branchCount + 1); for (int i = 1; i <= branchCount; i++) points.Add(new Point(X - Width / 2 + i * spacing, Y + Height / 2)); break; case NodeType.Join: case NodeType.Normal: points.Add(BtmPoint); break; default: break; } if (index >= 0 && index < points.Count) return points[index]; else return new Point(-1, -1); } public List GetBranchPoints() { List points = new List() { }; switch (NodeType) { case NodeType.Begin: points.Add(BtmPoint); break; case NodeType.End: break; case NodeType.Switch: points.Add(LeftPoint); points.Add(RightPoint); break; case NodeType.MultiBranch: case NodeType.Parallel: int branchCount = BranchNodes.Count; if (branchCount == 0) break; int spacing = Width / (branchCount + 1); for (int i = 1; i <= branchCount; i++) points.Add(new Point(X - Width / 2 + i * spacing, Y + Height / 2)); break; case NodeType.Join: case NodeType.Normal: points.Add(BtmPoint); break; default: break; } return points; } public FlowNode() { } public FlowNode(NodeType nodeType, Point location, string text, string description, int width = 100, int height = 40) { NodeType = nodeType; X = location.X; Y = location.Y; Width = width; Height = height; Text = text; Description = description; } public static Point[] GetDiamondPoints(Rectangle bounds) { int centerX = bounds.X + bounds.Width / 2; int centerY = bounds.Y + bounds.Height / 2; return new Point[]{ new Point(centerX, bounds.Y), new Point(bounds.Right, centerY) , new Point(centerX, bounds.Bottom), new Point(bounds.X, centerY)}; } } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public class NodeAttribute : Attribute { public string Name { get; } public string Category { get; } public string Group { get; } public string Description { get; } public NodeAttribute(string name, string category, string group, string description) { Name = name; Category = category; Group = group; Description = description; } } }