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;
}
}
}