using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.Xml.Linq;
using TeamAAS.FlowEditor.Execution;
using TeamAAS.FlowEditor.Plugins;
namespace TeamAAS.FlowEditor.Models
{
[Serializable]
///
/// 流程图模型 - 管理节点和连线的集合
///
public class FlowGraph : TeamAAS.BindableBase
{
///
/// 本流程绑定的执行结果注册表(主页面运行流程 = ResultRegistry.Main,编辑/调试流程 = ResultRegistry.Debug)。
/// 运行态/编辑态各自独立,互不干扰;监控模式挂接运行态流程时自动指向主面对象。
///
[Newtonsoft.Json.JsonIgnore]
[field: NonSerialized]
public ResultRegistry Registry { get; set; } = ResultRegistry.Debug;
public string GraphId { get; set; } = System.Guid.NewGuid().ToString("N");
public string GraphName
{
get => _graphName;
set => SetProperty(ref _graphName, value);
}
private string _graphName = "新流程";
public ObservableCollection Nodes { get; set; } = new ObservableCollection();
public ObservableCollection Connections { get; set; } = new ObservableCollection();
///
/// 添加节点
///
public void AddNode(FlowNode node)
{
Nodes.Add(node);
}
///
/// 删除节点及其关联连线
///
public void RemoveNode(string nodeId)
{
// 删除关联连线
var connectionsToRemove = new List();
foreach (var conn in Connections)
{
if (conn.SourceNodeId == nodeId || conn.TargetNodeId == nodeId)
connectionsToRemove.Add(conn);
}
foreach (var conn in connectionsToRemove)
Connections.Remove(conn);
// 删除节点 + 清理 ResultRegistry 中的执行结果
for (int i = Nodes.Count - 1; i >= 0; i--)
{
if (Nodes[i].NodeId == nodeId)
{
Registry?.RemoveNodeResult(GraphId, Nodes[i].NodeName);
Nodes.RemoveAt(i);
break;
}
}
}
///
/// 检查连线是否合法(不自连、非End下游、不重复、不成环)— 只检查不添加
///
public bool CanConnect(FlowConnection connection)
{
// 不允许自连接
if (connection.SourceNodeId == connection.TargetNodeId)
return false;
// 结束节点不允许添加下游连线
var sourceNode = GetNode(connection.SourceNodeId);
if (sourceNode != null && sourceNode.Category == NodeCategory.End)
return false;
// 检查重复 — 同一对节点之间不允许连线(双向检查,防止反向连接)
foreach (var conn in Connections)
{
if ((conn.SourceNodeId == connection.SourceNodeId && conn.TargetNodeId == connection.TargetNodeId) ||
(conn.SourceNodeId == connection.TargetNodeId && conn.TargetNodeId == connection.SourceNodeId))
return false;
}
// 检查是否形成环(多级链路:A→B→C 后不允许 C→A)
if (WouldCreateCycle(connection.SourceNodeId, connection.TargetNodeId))
return false;
return true;
}
///
/// 添加连线(自动检查重复和环)
///
public bool TryAddConnection(FlowConnection connection)
{
if (!CanConnect(connection))
return false;
Connections.Add(connection);
return true;
}
///
/// 删除连线
///
public void RemoveConnection(string connectionId)
{
for (int i = Connections.Count - 1; i >= 0; i--)
{
if (Connections[i].ConnectionId == connectionId)
{
Connections.RemoveAt(i);
break;
}
}
}
///
/// 检查添加连线后是否形成环
///
private bool WouldCreateCycle(string sourceId, string targetId)
{
// 如果 target 能到达 source,则形成环
return CanReach(targetId, sourceId, new HashSet());
}
private bool CanReach(string fromId, string toId, HashSet visited)
{
if (fromId == toId) return true;
if (visited.Contains(fromId)) return false;
visited.Add(fromId);
foreach (var conn in Connections)
{
if (conn.SourceNodeId == fromId)
{
if (CanReach(conn.TargetNodeId, toId, visited))
return true;
}
}
return false;
}
///
/// 获取节点
///
public FlowNode GetNode(string nodeId)
{
foreach (var node in Nodes)
{
if (node.NodeId == nodeId) return node;
}
return null;
}
}
}