using HandyControl.Tools.Extension;
using PropertyGridLib.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using TeamAAS.Communication;
using TeamAAS.FlowEditor.Execution;
using TeamAAS.FlowEditor.Models;
using TeamAAS.FlowEngine;
namespace TeamAAS.FlowEngine.FormulaData
{
///
/// 给「组合模块输入参数 SourceValue」用的公式树数据源。
/// 查外层主流程中组合模块节点的前置节点结果(而不是子流程内部节点)。
/// 依赖 判断上下文。
///
[Serializable]
public class InputSourceDataProvider : IFormulaTreeProvider
{
///
/// 生成公式树节点列表:
/// 1) 全局变量(Gloab)
/// 2) 主流程中组合模块节点的所有前置节点输出结果
///
public List GetFormulaTree(PropertyItem propertyItem)
{
var nodes = new List();
try
{
var select = PluginLoader.Instance.ParentGroupModel;
if (select == null) return nodes;
var flowId = select.FlowId;
var findName = select.NodeName;
// 使用选中节点所属流程绑定的注册表(编辑态=Debug,监控态挂接运行图=Main)
var registry = PluginLoader.Instance.SelectFlow?.Registry ?? ResultRegistry.Debug;
registry.GetFlowResults(flowId, out var flowResults);
flowResults.DeleteIfExistsKey(findName);
if (propertyItem.Value == null)
propertyItem.Value = new object();
var targetType = propertyItem.Value.GetType();
var formulaType = propertyItem.PropertyType;
nodes.AddRange(flowResults.Select(kvp =>
new FormulaTreeNode
{
Header = kvp.Key,
Children = kvp.Value
.Where(p => targetType == null || targetType == typeof(object)
|| (p.Value != null && (p.Value.GetType() == targetType || p.Value.GetType() == formulaType)))
.Select(p =>
new FormulaTreeNode
{
Header = p.Key,
Formula = $"&{{{kvp.Key}.{p.Key}}}"
}).ToList()
}).ToList());
// 全局变量
try
{
registry.RefreshGlobalVariables();
var gloabNode = new FormulaTreeNode
{
Header = "Gloab",
Children = GlobalVariableManager.Instance.Variables
.Where(v => !string.IsNullOrWhiteSpace(v.Name))
.Select(v => new FormulaTreeNode
{
Header = v.Name,
Formula = $"&{{Gloab.{v.Name}}}"
}).ToList()
};
if (gloabNode.Children.Count > 0)
nodes.Insert(0, gloabNode);
}
catch { }
}
catch { }
return nodes;
}
///
/// 反向 BFS 追溯指定节点的所有前置节点名称(通过连接线追溯到起点)。
///
private static HashSet GetPredecessorNodeNames(string graphId, string nodeId)
{
var result = new HashSet();
var graph = FindGraphById(graphId);
if (graph == null) return result;
var predecessorIds = new HashSet();
var queue = new Queue();
foreach (var conn in graph.Connections)
{
if (conn.TargetNodeId == nodeId) queue.Enqueue(conn.SourceNodeId);
}
while (queue.Count > 0)
{
var cur = queue.Dequeue();
if (predecessorIds.Add(cur))
{
foreach (var conn in graph.Connections)
{
if (conn.TargetNodeId == cur) queue.Enqueue(conn.SourceNodeId);
}
}
}
foreach (var node in graph.Nodes)
{
if (predecessorIds.Contains(node.NodeId))
result.Add(node.NodeName);
}
return result;
}
///
/// 按 GraphId 查找 FlowGraph:先查顶层 FlowTabs,找不到再递归所有组合模块 SubGraph。
///
private static FlowGraph FindGraphById(string graphId)
{
var flowTabs = PluginLoader.Instance.FlowTabs;
if (flowTabs != null)
{
var tab = flowTabs.FirstOrDefault(t => t.Graph != null && t.Graph.GraphId == graphId);
if (tab?.Graph != null) return tab.Graph;
foreach (var t in flowTabs)
{
if (t?.Graph == null) continue;
var found = FindSubGraphById(t.Graph, graphId);
if (found != null) return found;
}
}
return null;
}
///
/// 在图中递归查找所有 SubGraph(支持任意嵌套组合模块)。
///
private static FlowGraph FindSubGraphById(FlowGraph parent, string graphId)
{
foreach (var node in parent.Nodes)
{
var model = node.PluginModel?.GetModel;
if (model == null) continue;
var graphProp = model.GetType().GetProperty("SubGraph");
if (graphProp?.GetValue(model) is FlowGraph sub)
{
if (sub.GraphId == graphId) return sub;
var nested = FindSubGraphById(sub, graphId);
if (nested != null) return nested;
}
}
return null;
}
}
}