| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- 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
- {
- /// <summary>
- /// 给「组合模块输入参数 SourceValue」用的公式树数据源。
- /// 查外层主流程中组合模块节点的前置节点结果(而不是子流程内部节点)。
- /// 依赖 <see cref="PluginLoader.ParentGroupModel"/> 判断上下文。
- /// </summary>
- [Serializable]
- public class InputSourceDataProvider : IFormulaTreeProvider
- {
- /// <summary>
- /// 生成公式树节点列表:
- /// 1) 全局变量(Gloab)
- /// 2) 主流程中组合模块节点的所有前置节点输出结果
- /// </summary>
- public List<FormulaTreeNode> GetFormulaTree(PropertyItem propertyItem)
- {
- var nodes = new List<FormulaTreeNode>();
- 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;
- }
- /// <summary>
- /// 反向 BFS 追溯指定节点的所有前置节点名称(通过连接线追溯到起点)。
- /// </summary>
- private static HashSet<string> GetPredecessorNodeNames(string graphId, string nodeId)
- {
- var result = new HashSet<string>();
- var graph = FindGraphById(graphId);
- if (graph == null) return result;
- var predecessorIds = new HashSet<string>();
- var queue = new Queue<string>();
- 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;
- }
- /// <summary>
- /// 按 GraphId 查找 FlowGraph:先查顶层 FlowTabs,找不到再递归所有组合模块 SubGraph。
- /// </summary>
- 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;
- }
- /// <summary>
- /// 在图中递归查找所有 SubGraph(支持任意嵌套组合模块)。
- /// </summary>
- 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;
- }
- }
- }
|