mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-03 00:00:49 +08:00
尝试将节点流导出为c#代码文件
This commit is contained in:
@@ -10,7 +10,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser;
|
||||
|
||||
namespace Serein.NodeFlow.Env
|
||||
{
|
||||
@@ -25,11 +24,11 @@ namespace Serein.NodeFlow.Env
|
||||
private readonly UIContextOperation UIContextOperation;
|
||||
|
||||
public FlowControl(IFlowEnvironment flowEnvironment,
|
||||
IFlowEnvironmentEvent flowEnvironmentEvent,
|
||||
FlowLibraryService flowLibraryService,
|
||||
FlowOperationService flowOperationService,
|
||||
FlowModelService flowModelService,
|
||||
UIContextOperation UIContextOperation)
|
||||
IFlowEnvironmentEvent flowEnvironmentEvent,
|
||||
FlowLibraryService flowLibraryService,
|
||||
FlowOperationService flowOperationService,
|
||||
FlowModelService flowModelService,
|
||||
UIContextOperation UIContextOperation)
|
||||
{
|
||||
this.flowEnvironment = flowEnvironment;
|
||||
this.flowEnvironmentEvent = flowEnvironmentEvent;
|
||||
@@ -285,38 +284,24 @@ namespace Serein.NodeFlow.Env
|
||||
/// 调用流程接口,将返回 FlowResult.Value。如果需要 FlowResult 对象,请使用该方法的泛型版本。
|
||||
/// </summary>
|
||||
/// <param name="apiGuid">流程接口节点Guid</param>
|
||||
/// <param name="param">调用时入参参数</param>
|
||||
/// <param name="dict">调用时入参参数</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public async Task<object> ApiInvokeAsync(string apiGuid, object[] param)
|
||||
public async Task<object> InvokeAsync(string apiGuid, Dictionary<string, object> dict)
|
||||
{
|
||||
if (sereinIOC is null)
|
||||
{
|
||||
sereinIOC = flowEnvironment.IOC;
|
||||
}
|
||||
if (!flowModelService.TryGetNodeModel(apiGuid, out var nodeModel))
|
||||
{
|
||||
throw new ArgumentNullException($"不存在流程接口:{apiGuid}");
|
||||
}
|
||||
if (nodeModel is not SingleFlowCallNode flowCallNode)
|
||||
{
|
||||
throw new ArgumentNullException($"目标节点并非流程接口:{apiGuid}");
|
||||
}
|
||||
var context = contexts.Allocate();
|
||||
CancellationTokenSource cts = new CancellationTokenSource();
|
||||
var flowResult = await flowCallNode.StartFlowAsync(context, cts.Token);
|
||||
return flowResult.Value;
|
||||
var result = await InvokeAsync<object>(apiGuid, dict);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 调用流程接口,泛型类型为 FlowResult 时,将返回 FlowResult 对象。
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult"></typeparam>
|
||||
/// <param name="apiGuid">流程接口节点Guid</param>
|
||||
/// <param name="param">调用时入参参数</param>
|
||||
/// <param name="dict">调用时入参参数</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public async Task<TResult> ApiInvokeAsync<TResult>(string apiGuid, object[] param)
|
||||
public async Task<TResult> InvokeAsync<TResult>(string apiGuid, Dictionary<string, object> dict)
|
||||
{
|
||||
if (sereinIOC is null)
|
||||
{
|
||||
@@ -330,10 +315,25 @@ namespace Serein.NodeFlow.Env
|
||||
{
|
||||
throw new ArgumentNullException($"目标节点并非流程接口:{apiGuid}");
|
||||
}
|
||||
var context = contexts.Allocate();
|
||||
var pds = flowCallNode.MethodDetails.ParameterDetailss;
|
||||
if (dict.Keys.Count != pds.Length)
|
||||
{
|
||||
throw new ArgumentNullException($"参数数量不一致。传入参数数量:{dict.Keys.Count}。接口入参数量:{pds.Length}。");
|
||||
}
|
||||
|
||||
IDynamicContext context = contexts.Allocate();
|
||||
for (int index = 0; index < pds.Length; index++)
|
||||
{
|
||||
ParameterDetails pd = pds[index];
|
||||
if (dict.TryGetValue(pd.Name, out var value))
|
||||
{
|
||||
context.SetParamsTempData(flowCallNode.Guid, index, value); // 设置入参参数
|
||||
}
|
||||
}
|
||||
CancellationTokenSource cts = new CancellationTokenSource();
|
||||
var flowResult = await flowCallNode.StartFlowAsync(context, cts.Token);
|
||||
|
||||
cts?.Cancel();
|
||||
cts?.Dispose();
|
||||
if (flowResult.Value is TResult result)
|
||||
{
|
||||
return result;
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
using Serein.Library;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Serein.Library;
|
||||
using Serein.Library.Api;
|
||||
using Serein.Library.Utils;
|
||||
using Serein.NodeFlow.Model;
|
||||
using Serein.NodeFlow.Model.Operation;
|
||||
using Serein.NodeFlow.Services;
|
||||
using Serein.NodeFlow.Tool;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using static Serein.Library.Api.IFlowEnvironment;
|
||||
using IOperation = Serein.NodeFlow.Model.Operation.IOperation;
|
||||
|
||||
namespace Serein.NodeFlow.Env
|
||||
{
|
||||
@@ -107,11 +111,13 @@ namespace Serein.NodeFlow.Env
|
||||
/// 从节点信息创建节点,并返回状态指示是否创建成功
|
||||
/// </summary>
|
||||
/// <param name="nodeInfo"></param>
|
||||
/// <param name="nodeModel"></param>
|
||||
/// <returns></returns>
|
||||
private bool CreateNodeFromNodeInfo(NodeInfo nodeInfo)
|
||||
private bool CreateNodeFromNodeInfo(NodeInfo nodeInfo, out IFlowNode? nodeModel)
|
||||
{
|
||||
if (!EnumHelper.TryConvertEnum<NodeControlType>(nodeInfo.Type, out var controlType))
|
||||
{
|
||||
nodeModel = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -146,37 +152,22 @@ namespace Serein.NodeFlow.Env
|
||||
}
|
||||
else
|
||||
{
|
||||
if (string.IsNullOrEmpty(nodeInfo.MethodName)) return false;
|
||||
if (string.IsNullOrEmpty(nodeInfo.MethodName))
|
||||
{
|
||||
nodeModel = null;
|
||||
return false;
|
||||
}
|
||||
// 加载方法节点
|
||||
flowLibraryManagement.TryGetMethodDetails(nodeInfo.AssemblyName, nodeInfo.MethodName, out methodDetails); // 加载项目时尝试获取方法信息
|
||||
}
|
||||
#endregion
|
||||
|
||||
var nodeModel = FlowNodeExtension.CreateNode(flowEnvironment, controlType, methodDetails); // 加载项目时创建节点
|
||||
nodeModel = FlowNodeExtension.CreateNode(flowEnvironment, controlType, methodDetails); // 加载项目时创建节点
|
||||
if (nodeModel is null)
|
||||
{
|
||||
nodeInfo.Guid = string.Empty;
|
||||
return false;
|
||||
}
|
||||
if (TryGetCanvasModel(nodeInfo.CanvasGuid, out var canvasModel))
|
||||
{
|
||||
|
||||
// 节点与画布互相绑定
|
||||
// 需要在UI线程上进行添加,否则会报 “不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改”异常
|
||||
nodeModel.CanvasDetails = canvasModel;
|
||||
UIContextOperation?.Invoke(() => canvasModel.Nodes.Add(nodeModel));
|
||||
|
||||
nodeModel.LoadInfo(nodeInfo); // 创建节点model
|
||||
TryAddNode(nodeModel); // 加载项目时将节点加载到环境中
|
||||
}
|
||||
else
|
||||
{
|
||||
SereinEnv.WriteLine(InfoType.ERROR, $"加载节点[{nodeInfo.Guid}]时发生异常,画布[{nodeInfo.CanvasGuid}]不存在");
|
||||
return false;
|
||||
}
|
||||
|
||||
UIContextOperation?.Invoke(() =>
|
||||
flowEnvironmentEvent.OnNodeCreated(new NodeCreateEventArgs(nodeInfo.CanvasGuid, nodeModel, nodeInfo.Position))); // 添加到UI上
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -355,7 +346,10 @@ namespace Serein.NodeFlow.Env
|
||||
}*/
|
||||
canvasModel.StartNode = newStartNodeModel;
|
||||
//newStartNode.IsStart = true;
|
||||
UIContextOperation?.Invoke(() => flowEnvironmentEvent.OnStartNodeChanged(new StartNodeChangeEventArgs(canvasGuid, oldNodeGuid, newStartNodeModel.Guid)));
|
||||
_ = TriggerEvent(() =>
|
||||
flowEnvironmentEvent.OnStartNodeChanged(
|
||||
new StartNodeChangeEventArgs(canvasGuid, oldNodeGuid, newStartNodeModel.Guid)
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -395,6 +389,46 @@ namespace Serein.NodeFlow.Env
|
||||
#region 从NodeInfo创建NodeModel
|
||||
// 流程接口节点最后才创建
|
||||
|
||||
async Task AddNodeAsync(NodeInfo nodeInfo, IFlowNode nodeModel)
|
||||
{
|
||||
if (!TryGetCanvasModel(nodeInfo.CanvasGuid, out var canvasModel))
|
||||
{
|
||||
SereinEnv.WriteLine(InfoType.ERROR, $"加载节点[{nodeInfo.Guid}]时发生异常,画布[{nodeInfo.CanvasGuid}]不存在");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 节点与画布互相绑定
|
||||
// 需要在UI线程上进行添加,否则会报 “不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改”异常
|
||||
nodeModel.CanvasDetails = canvasModel;
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var nodes = canvasModel.Nodes.ToList();
|
||||
nodes.Add(nodeModel);
|
||||
canvasModel.Nodes = nodes;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
}
|
||||
}); // 添加到画布节点集合中
|
||||
nodeModel.LoadInfo(nodeInfo); // 创建节点model
|
||||
nodeModel.Guid ??= Guid.NewGuid().ToString();
|
||||
flowModelService.AddNodeModel(nodeModel);
|
||||
|
||||
await TriggerEvent(() =>
|
||||
flowEnvironmentEvent.OnNodeCreated(
|
||||
new NodeCreateEventArgs(nodeInfo.CanvasGuid, nodeModel, nodeInfo.Position)
|
||||
)
|
||||
); // 创建节点事件
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
List<NodeInfo> flowCallNodeInfos = [];
|
||||
foreach (NodeInfo? nodeInfo in nodeInfos)
|
||||
{
|
||||
@@ -404,10 +438,13 @@ namespace Serein.NodeFlow.Env
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!CreateNodeFromNodeInfo(nodeInfo))
|
||||
if (CreateNodeFromNodeInfo(nodeInfo, out var nodeModel) && nodeModel is not null)
|
||||
{
|
||||
await AddNodeAsync(nodeInfo, nodeModel);
|
||||
}
|
||||
else
|
||||
{
|
||||
SereinEnv.WriteLine(InfoType.WARN, $"节点创建失败。{Environment.NewLine}{nodeInfo}");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -415,10 +452,13 @@ namespace Serein.NodeFlow.Env
|
||||
// 创建流程接口节点
|
||||
foreach (NodeInfo? nodeInfo in flowCallNodeInfos)
|
||||
{
|
||||
if (!CreateNodeFromNodeInfo(nodeInfo))
|
||||
if (CreateNodeFromNodeInfo(nodeInfo, out var nodeModel) && nodeModel is not null)
|
||||
{
|
||||
await AddNodeAsync(nodeInfo, nodeModel);
|
||||
}
|
||||
else
|
||||
{
|
||||
SereinEnv.WriteLine(InfoType.WARN, $"节点创建失败。{Environment.NewLine}{nodeInfo}");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
@@ -444,8 +484,10 @@ namespace Serein.NodeFlow.Env
|
||||
var result = nodeContainer.PlaceNode(nodeModel);
|
||||
if (result)
|
||||
{
|
||||
UIContextOperation?.Invoke(() => flowEnvironmentEvent.OnNodePlace(
|
||||
new NodePlaceEventArgs(nodeInfo.CanvasGuid, nodeModel.Guid, containerNode.Guid)));
|
||||
await TriggerEvent(() =>
|
||||
flowEnvironmentEvent.OnNodePlace(
|
||||
new NodePlaceEventArgs(nodeInfo.CanvasGuid, nodeModel.Guid, containerNode.Guid)
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -484,30 +526,9 @@ namespace Serein.NodeFlow.Env
|
||||
|
||||
ConnectInvokeNode(canvasGuid, fromNodeModel.Guid, toNodeModel.Guid, JunctionType.NextStep, JunctionType.Execute, item.connectionType);
|
||||
|
||||
//var isSuccessful = ConnectInvokeOfNode(canvasGuid, fromNodeModel, toNodeModel, item.connectionType); // 加载时确定节点间的连接关系
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//List<(ConnectionInvokeType connectionType, string[] guids)> allToNodes = [(ConnectionInvokeType.IsSucceed,nodeInfo.TrueNodes),
|
||||
// (ConnectionInvokeType.IsFail, nodeInfo.FalseNodes),
|
||||
// (ConnectionInvokeType.IsError, nodeInfo.ErrorNodes),
|
||||
// (ConnectionInvokeType.Upstream, nodeInfo.UpstreamNodes)];
|
||||
|
||||
//List<(ConnectionInvokeType, NodeModelBase[])> fromNodes = allToNodes.Where(info => info.guids.Length > 0)
|
||||
// .Select(info => (info.connectionType,
|
||||
// info.guids.Where(guid => NodeModels.ContainsKey(guid)).Select(guid => NodeModels[guid])
|
||||
// .ToArray()))
|
||||
// .ToList();
|
||||
// 遍历每种类型的节点分支(四种)
|
||||
//foreach ((ConnectionInvokeType connectionType, NodeModelBase[] toNodes) item in nodeInfo)
|
||||
//{
|
||||
// // 遍历当前类型分支的节点(确认连接关系)
|
||||
// foreach (var toNode in item.toNodes)
|
||||
// {
|
||||
// _ = ConnectInvokeOfNode(fromNode, toNode, item.connectionType); // 加载时确定节点间的连接关系
|
||||
// }
|
||||
//}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -526,20 +547,13 @@ namespace Serein.NodeFlow.Env
|
||||
if (!string.IsNullOrEmpty(pd.ArgDataSourceNodeGuid)
|
||||
&& TryGetNodeModel(pd.ArgDataSourceNodeGuid, out var fromNode))
|
||||
{
|
||||
|
||||
ConnectArgSourceNode(canvasGuid, fromNode.Guid, toNode.Guid, JunctionType.ReturnData, JunctionType.ArgData, pd.ArgDataSourceType, pd.Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
UIContextOperation?.Invoke(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnProjectLoaded(new ProjectLoadedEventArgs());
|
||||
});
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -561,8 +575,27 @@ namespace Serein.NodeFlow.Env
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
private async Task TriggerEvent(Action action)
|
||||
{
|
||||
if(UIContextOperation is null)
|
||||
{
|
||||
action?.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
await UIContextOperation.InvokeAsync(() =>
|
||||
{
|
||||
action?.Invoke();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -51,8 +51,7 @@ namespace Serein.NodeFlow.Env
|
||||
public FlowEnvironment()
|
||||
{
|
||||
ISereinIOC ioc = new SereinIOC();
|
||||
ioc.Reset()
|
||||
.Register<ISereinIOC>(()=> ioc) // 注册IOC
|
||||
ioc.Register<ISereinIOC>(()=> ioc) // 注册IOC
|
||||
.Register<IFlowEnvironment>(() => this)
|
||||
.Register<IFlowEnvironmentEvent, FlowEnvironmentEvent>()
|
||||
.Register<IFlowEdit, FlowEdit>()
|
||||
@@ -205,11 +204,20 @@ namespace Serein.NodeFlow.Env
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void LoadProject(FlowEnvInfo flowEnvInfo, string filePath)
|
||||
public void LoadProject(string filePath)
|
||||
{
|
||||
if (flowEnvInfo is null) return;
|
||||
//if (flowEnvInfo is null) return;
|
||||
SetProjectLoadingFlag(false);
|
||||
currentFlowEnvironment.LoadProject(flowEnvInfo, filePath);
|
||||
currentFlowEnvironment.LoadProject(filePath);
|
||||
SetProjectLoadingFlag(true);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task LoadProjetAsync(string filePath)
|
||||
{
|
||||
//if (flowEnvInfo is null) return;
|
||||
SetProjectLoadingFlag(false);
|
||||
await currentFlowEnvironment.LoadProjetAsync(filePath);
|
||||
SetProjectLoadingFlag(true);
|
||||
}
|
||||
|
||||
@@ -307,11 +315,7 @@ namespace Serein.NodeFlow.Env
|
||||
/// <inheritdoc/>
|
||||
public void SetUIContextOperation(UIContextOperation uiContextOperation)
|
||||
{
|
||||
if(uiContextOperation is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
IOC.Register<UIContextOperation>(() => uiContextOperation).Build();
|
||||
|
||||
currentFlowEnvironment.SetUIContextOperation(uiContextOperation);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Serein.Library;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Newtonsoft.Json;
|
||||
using Serein.Library;
|
||||
using Serein.Library.Api;
|
||||
using Serein.Library.FlowNode;
|
||||
using Serein.Library.Utils;
|
||||
@@ -15,6 +17,8 @@ using System.Reactive;
|
||||
using System.Reflection;
|
||||
using System.Security.AccessControl;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using static Serein.Library.Api.IFlowEnvironment;
|
||||
|
||||
namespace Serein.NodeFlow.Env
|
||||
@@ -288,12 +292,75 @@ namespace Serein.NodeFlow.Env
|
||||
/// <summary>
|
||||
/// 加载项目文件
|
||||
/// </summary>
|
||||
/// <param name="flowEnvInfo">环境信息</param>
|
||||
/// <param name="filePath"></param>
|
||||
public void LoadProject(FlowEnvInfo flowEnvInfo, string filePath)
|
||||
public void LoadProject(string filePath)
|
||||
{
|
||||
string content = System.IO.File.ReadAllText(filePath); // 读取整个文件内容
|
||||
var FlowProjectData = JsonConvert.DeserializeObject<SereinProjectData>(content);
|
||||
var FileDataPath = System.IO.Path.GetDirectoryName(filePath)!; // filePath;//
|
||||
|
||||
|
||||
|
||||
this.ProjectFileLocation = filePath;
|
||||
var projectData = flowEnvInfo.Project;
|
||||
|
||||
var projectData = FlowProjectData;
|
||||
// 加载项目配置文件
|
||||
var dllPaths = projectData.Librarys.Select(it => it.FilePath).ToList();
|
||||
List<MethodDetails> methodDetailss = [];
|
||||
|
||||
// 遍历依赖项中的特性注解,生成方法详情
|
||||
foreach (var dllPath in dllPaths)
|
||||
{
|
||||
string cleanedRelativePath = dllPath.TrimStart('.', '\\');
|
||||
var tmpPath = Path.Combine(FileDataPath, cleanedRelativePath);
|
||||
var dllFilePath = Path.GetFullPath(tmpPath);
|
||||
LoadLibrary(dllFilePath); // 加载项目文件时加载对应的程序集
|
||||
}
|
||||
|
||||
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
// 加载画布
|
||||
try
|
||||
{
|
||||
foreach (var canvasInfo in projectData.Canvass)
|
||||
{
|
||||
await LoadCanvasAsync(canvasInfo);
|
||||
}
|
||||
var nodeInfos = projectData.Nodes.ToList();
|
||||
await FlowEdit.LoadNodeInfosAsync(nodeInfos); // 加载节点信息
|
||||
// 加载画布
|
||||
foreach (var canvasInfo in projectData.Canvass)
|
||||
{
|
||||
FlowEdit.SetStartNode(canvasInfo.Guid, canvasInfo.StartNode); // 设置起始节点
|
||||
}
|
||||
|
||||
Event.OnProjectLoaded(new ProjectLoadedEventArgs());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
//
|
||||
//await SetStartNodeAsync("", projectData.StartNode); // 设置起始节点
|
||||
});
|
||||
}
|
||||
|
||||
public async Task LoadProjetAsync(string filePath)
|
||||
{
|
||||
string content = await System.IO.File.ReadAllTextAsync(filePath); // 读取整个文件内容
|
||||
var FlowProjectData = JsonConvert.DeserializeObject<SereinProjectData>(content);
|
||||
var FileDataPath = System.IO.Path.GetDirectoryName(filePath)!; // filePath;//
|
||||
if(FlowProjectData is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.ProjectFileLocation = filePath;
|
||||
var projectData = FlowProjectData;
|
||||
|
||||
// 加载项目配置文件
|
||||
var dllPaths = projectData.Librarys.Select(it => it.FilePath).ToList();
|
||||
List<MethodDetails> methodDetailss = [];
|
||||
@@ -309,23 +376,18 @@ namespace Serein.NodeFlow.Env
|
||||
|
||||
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
// 加载画布
|
||||
foreach (var canvasInfo in projectData.Canvass)
|
||||
{
|
||||
// 加载画布
|
||||
foreach (var canvasInfo in projectData.Canvass)
|
||||
{
|
||||
LoadCanvas(canvasInfo);
|
||||
}
|
||||
await FlowEdit.LoadNodeInfosAsync(projectData.Nodes.ToList()); // 加载节点信息
|
||||
|
||||
// 加载画布
|
||||
foreach (var canvasInfo in projectData.Canvass)
|
||||
{
|
||||
FlowEdit.SetStartNode(canvasInfo.Guid, canvasInfo.StartNode); // 设置起始节点
|
||||
}
|
||||
//await SetStartNodeAsync("", projectData.StartNode); // 设置起始节点
|
||||
});
|
||||
|
||||
await LoadCanvasAsync(canvasInfo);
|
||||
}
|
||||
await FlowEdit.LoadNodeInfosAsync(projectData.Nodes.ToList()); // 加载节点信息
|
||||
// 加载画布
|
||||
foreach (var canvasInfo in projectData.Canvass)
|
||||
{
|
||||
FlowEdit.SetStartNode(canvasInfo.Guid, canvasInfo.StartNode); // 设置起始节点
|
||||
}
|
||||
Event.OnProjectLoaded(new ProjectLoadedEventArgs());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -532,15 +594,24 @@ namespace Serein.NodeFlow.Env
|
||||
private int _addCanvasCount = 0;
|
||||
|
||||
|
||||
private FlowCanvasDetails LoadCanvas(FlowCanvasDetailsInfo info)
|
||||
private async Task<FlowCanvasDetails> LoadCanvasAsync(FlowCanvasDetailsInfo info)
|
||||
{
|
||||
var model = new FlowCanvasDetails(this);
|
||||
model.LoadInfo(info);
|
||||
flowModelService.AddCanvasModel(model);
|
||||
UIContextOperation?.Invoke(() =>
|
||||
|
||||
if(UIContextOperation is null)
|
||||
{
|
||||
Event.OnCanvasCreated(new CanvasCreateEventArgs(model));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
await UIContextOperation.InvokeAsync(() =>
|
||||
{
|
||||
Event.OnCanvasCreated(new CanvasCreateEventArgs(model));
|
||||
});
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
@@ -585,12 +656,12 @@ namespace Serein.NodeFlow.Env
|
||||
/// <param name="uiContextOperation"></param>
|
||||
public void SetUIContextOperation(UIContextOperation uiContextOperation)
|
||||
{
|
||||
if (uiContextOperation is not null)
|
||||
if (uiContextOperation is null)
|
||||
{
|
||||
this.UIContextOperation = uiContextOperation;
|
||||
//PersistennceInstance[typeof(UIContextOperation)] = uiContextOperation; // 缓存封装好的UI线程上下文
|
||||
return;
|
||||
}
|
||||
|
||||
this.UIContextOperation = uiContextOperation;
|
||||
IOC.Register<UIContextOperation>(() => uiContextOperation).Build();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using Serein.NodeFlow.Model;
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace Serein.NodeFlow
|
||||
{
|
||||
@@ -128,6 +129,32 @@ namespace Serein.NodeFlow
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加代码
|
||||
/// </summary>
|
||||
/// <param name="sb">字符串构建器</param>
|
||||
/// <param name="retractCount">缩进次数(4个空格)</param>
|
||||
/// <param name="code">要添加的代码</param>
|
||||
/// <returns>字符串构建器本身</returns>
|
||||
public static StringBuilder AddCode(this StringBuilder sb,
|
||||
int retractCount = 0,
|
||||
string code = null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(code))
|
||||
{
|
||||
var retract = new string(' ', retractCount * 4);
|
||||
sb.AppendLine(retract + code);
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///// <summary>
|
||||
///// 从节点类型枚举中转为对应的 Model 类型
|
||||
///// </summary>
|
||||
@@ -165,4 +192,6 @@ namespace Serein.NodeFlow
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace Serein.NodeFlow.Model
|
||||
}
|
||||
object[] args = await this.GetParametersAsync(context, token);
|
||||
var result = await dd.InvokeAsync(instance, args);
|
||||
var flowReslt = new FlowResult(this, context, result);
|
||||
var flowReslt = new FlowResult(this.Guid, context, result);
|
||||
return flowReslt;
|
||||
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace Serein.NodeFlow.Model
|
||||
{
|
||||
if (token.IsCancellationRequested)
|
||||
{
|
||||
return new FlowResult(this, context);
|
||||
return new FlowResult(this.Guid, context);
|
||||
}
|
||||
// 接收上一节点参数or自定义参数内容
|
||||
object? parameter;
|
||||
@@ -128,15 +128,15 @@ namespace Serein.NodeFlow.Model
|
||||
if (hasNode)
|
||||
{
|
||||
context.NextOrientation = ConnectionInvokeType.IsError;
|
||||
return new FlowResult(this, context);
|
||||
return new FlowResult(this.Guid, context);
|
||||
}
|
||||
if (hasNode)
|
||||
{
|
||||
return new FlowResult(this, context);
|
||||
return new FlowResult(this.Guid, context);
|
||||
}
|
||||
if (pd.ArgDataSourceType == ConnectionArgSourceType.GetOtherNodeData)
|
||||
{
|
||||
result = context.GetFlowData(argSourceNode).Value; // 使用自定义节点的参数
|
||||
result = context.GetFlowData(argSourceNode.Guid).Value; // 使用自定义节点的参数
|
||||
}
|
||||
else if (pd.ArgDataSourceType == ConnectionArgSourceType.GetOtherNodeDataOfInvoke)
|
||||
{
|
||||
@@ -148,7 +148,7 @@ namespace Serein.NodeFlow.Model
|
||||
}
|
||||
else
|
||||
{
|
||||
result = context.TransmissionData(this).Value; // 条件节点透传上一节点的数据
|
||||
result = context.TransmissionData(this.Guid).Value; // 条件节点透传上一节点的数据
|
||||
}
|
||||
parameter = result; // 使用上一节点的参数
|
||||
|
||||
@@ -184,7 +184,7 @@ namespace Serein.NodeFlow.Model
|
||||
|
||||
SereinEnv.WriteLine(InfoType.INFO, $"{result} {Expression} -> " + context.NextOrientation);
|
||||
//return result;
|
||||
return new FlowResult(this, context, judgmentResult);
|
||||
return new FlowResult(this.Guid, context, judgmentResult);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace Serein.NodeFlow.Model
|
||||
|
||||
public override async Task<FlowResult> ExecutingAsync(IDynamicContext context, CancellationToken token)
|
||||
{
|
||||
if(token.IsCancellationRequested) return new FlowResult(this, context);
|
||||
if(token.IsCancellationRequested) return new FlowResult(this.Guid, context);
|
||||
|
||||
object? parameter = null;// context.TransmissionData(this); // 表达式节点使用上一节点数据
|
||||
var pd = MethodDetails.ParameterDetailss[0];
|
||||
@@ -103,12 +103,12 @@ namespace Serein.NodeFlow.Model
|
||||
if (hasNode)
|
||||
{
|
||||
context.NextOrientation = ConnectionInvokeType.IsError;
|
||||
return new FlowResult(this, context);
|
||||
return new FlowResult(this.Guid, context);
|
||||
}
|
||||
if (pd.ArgDataSourceType == ConnectionArgSourceType.GetOtherNodeData)
|
||||
{
|
||||
// 使用自定义节点的参数
|
||||
parameter = context.GetFlowData(argSourceNode).Value;
|
||||
parameter = context.GetFlowData(argSourceNode.Guid).Value;
|
||||
}
|
||||
else if (pd.ArgDataSourceType == ConnectionArgSourceType.GetOtherNodeDataOfInvoke)
|
||||
{
|
||||
@@ -122,7 +122,7 @@ namespace Serein.NodeFlow.Model
|
||||
else
|
||||
{
|
||||
// 条件节点透传上一节点的数据
|
||||
parameter = context.TransmissionData(this);
|
||||
parameter = context.TransmissionData(this.Guid);
|
||||
}
|
||||
|
||||
try
|
||||
@@ -139,13 +139,13 @@ namespace Serein.NodeFlow.Model
|
||||
}
|
||||
|
||||
context.NextOrientation = ConnectionInvokeType.IsSucceed;
|
||||
return new FlowResult(this,context, result);
|
||||
return new FlowResult(this.Guid, context, result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
context.NextOrientation = ConnectionInvokeType.IsError;
|
||||
context.ExceptionOfRuning = ex;
|
||||
return new FlowResult(this, context);
|
||||
return new FlowResult(this.Guid, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace Serein.NodeFlow.Model
|
||||
throw new FlipflopException(MethodDetails.MethodName + "触发器超时触发。Guid" + Guid);
|
||||
}
|
||||
object result = dynamicFlipflopContext.Value;
|
||||
var flowReslt = new FlowResult(this, context, result);
|
||||
var flowReslt = new FlowResult(this.Guid, context, result);
|
||||
return flowReslt;
|
||||
}
|
||||
|
||||
|
||||
@@ -208,6 +208,14 @@ namespace Serein.NodeFlow.Model
|
||||
{
|
||||
TargetNodeGuid = targetNode.Guid;
|
||||
this.targetNode = targetNode;
|
||||
|
||||
if(this.IsShareParam == false)
|
||||
{
|
||||
foreach (var item in nodeInfo.ParameterData)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -258,7 +266,7 @@ namespace Serein.NodeFlow.Model
|
||||
// 此处代码与SereinFlow.Library.FlowNode.ParameterDetails
|
||||
// ToMethodArgData()方法中判断流程接口节点分支逻辑耦合
|
||||
// 不要轻易修改
|
||||
context.AddOrUpdate(targetNode, flowData);
|
||||
context.AddOrUpdate(targetNode.Guid, flowData);
|
||||
foreach (ConnectionInvokeType ctType in NodeStaticConfig.ConnectionTypes)
|
||||
{
|
||||
if (this.SuccessorNodes[ctType] == null) continue;
|
||||
@@ -267,7 +275,7 @@ namespace Serein.NodeFlow.Model
|
||||
if (node.DebugSetting.IsEnable)
|
||||
{
|
||||
|
||||
context.SetPreviousNode(node, this);
|
||||
context.SetPreviousNode(node.Guid, this.Guid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,18 +110,18 @@ namespace Serein.NodeFlow.Model
|
||||
/// <returns></returns>
|
||||
public override async Task<FlowResult> ExecutingAsync(IDynamicContext context, CancellationToken token)
|
||||
{
|
||||
if (token.IsCancellationRequested) return new FlowResult(this, context);
|
||||
if (token.IsCancellationRequested) return new FlowResult(this.Guid, context);
|
||||
if (string.IsNullOrEmpty(KeyName))
|
||||
{
|
||||
context.NextOrientation = ConnectionInvokeType.IsError;
|
||||
SereinEnv.WriteLine(InfoType.ERROR, $"全局数据的KeyName不能为空[{this.Guid}]");
|
||||
return new FlowResult(this, context);
|
||||
return new FlowResult(this.Guid, context);
|
||||
}
|
||||
if (DataNode is null)
|
||||
{
|
||||
context.NextOrientation = ConnectionInvokeType.IsError;
|
||||
SereinEnv.WriteLine(InfoType.ERROR, $"全局数据节点没有设置数据来源[{this.Guid}]");
|
||||
return new FlowResult(this, context);
|
||||
return new FlowResult(this.Guid, context);
|
||||
}
|
||||
|
||||
try
|
||||
@@ -135,7 +135,7 @@ namespace Serein.NodeFlow.Model
|
||||
{
|
||||
context.NextOrientation = ConnectionInvokeType.IsError;
|
||||
context.ExceptionOfRuning = ex;
|
||||
return new FlowResult(this, context);
|
||||
return new FlowResult(this.Guid, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -136,6 +136,8 @@ namespace Serein.NodeFlow.Model
|
||||
this.MethodDetails.ParameterDetailss[i].Name = nodeInfo.ParameterData[i].ArgName;
|
||||
}
|
||||
|
||||
ReloadScript();// 加载时重新解析
|
||||
IsScriptChanged = false; // 重置脚本改变标志
|
||||
|
||||
}
|
||||
|
||||
@@ -165,6 +167,8 @@ namespace Serein.NodeFlow.Model
|
||||
var p = new SereinScriptParser(sb.ToString());
|
||||
//var p = new SereinScriptParser(Script);
|
||||
mainNode = p.Parse(); // 开始解析
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -192,9 +196,9 @@ namespace Serein.NodeFlow.Model
|
||||
/// <returns></returns>
|
||||
public async Task<FlowResult> ExecutingAsync(NodeModelBase flowCallNode, IDynamicContext context, CancellationToken token)
|
||||
{
|
||||
if (token.IsCancellationRequested) return new FlowResult(this, context);
|
||||
if (token.IsCancellationRequested) return new FlowResult(this.Guid, context);
|
||||
var @params = await flowCallNode.GetParametersAsync(context, token);
|
||||
if (token.IsCancellationRequested) return new FlowResult(this, context);
|
||||
if (token.IsCancellationRequested) return new FlowResult(this.Guid, context);
|
||||
|
||||
//context.AddOrUpdate($"{context.Guid}_{this.Guid}_Params", @params[0]); // 后面再改
|
||||
|
||||
@@ -204,7 +208,8 @@ namespace Serein.NodeFlow.Model
|
||||
if (IsScriptChanged)
|
||||
{
|
||||
ReloadScript();// 每次都重新解析
|
||||
IsScriptChanged = false;
|
||||
IsScriptChanged = false;
|
||||
context.Env.WriteLine(InfoType.INFO, $"[{Guid}]脚本解析完成");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,7 +238,7 @@ namespace Serein.NodeFlow.Model
|
||||
|
||||
var result = await ScriptInterpreter.InterpretAsync(scriptContext, mainNode); // 从入口节点执行
|
||||
envEvent.FlowRunComplete -= onFlowStop;
|
||||
return new FlowResult(this, context, result);
|
||||
return new FlowResult(this.Guid, context, result);
|
||||
}
|
||||
|
||||
#region 挂载的方法
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Serein.NodeFlow.Model
|
||||
|
||||
public override async Task<FlowResult> ExecutingAsync(IDynamicContext context, CancellationToken token)
|
||||
{
|
||||
if (token.IsCancellationRequested) return new FlowResult(this,context);
|
||||
if (token.IsCancellationRequested) return new FlowResult(this.Guid, context);
|
||||
if(Adapter is null)
|
||||
{
|
||||
|
||||
@@ -34,13 +34,13 @@ namespace Serein.NodeFlow.Model
|
||||
}
|
||||
else
|
||||
{
|
||||
var p = context.GetPreviousNode(this);
|
||||
var p = context.GetPreviousNode(this.Guid);
|
||||
var data = context.GetFlowData(p).Value;
|
||||
var iflowContorl = Adapter.GetFlowControl();
|
||||
iflowContorl.OnExecuting(data);
|
||||
}
|
||||
|
||||
return new FlowResult(this, context);
|
||||
return new FlowResult(this.Guid, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Execute()
|
||||
public override async Task<bool> ExecuteAsync()
|
||||
{
|
||||
if (!ValidationParameter()) return false;
|
||||
if (!flowModelService.TryGetCanvasModel(CanvasGuid, out FlowCanvas) // 不存在画布
|
||||
@@ -132,12 +132,12 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
// flowTaskManagement?.TerminateGlobalFlipflopRuning(flipflopNode); // 假设被连接的是全局触发器,尝试移除
|
||||
//}
|
||||
|
||||
var state = (JunctionOfConnectionType, ChangeType) switch
|
||||
var state = (JunctionOfConnectionType, ChangeType) switch
|
||||
{
|
||||
(JunctionOfConnectionType.Invoke, NodeConnectChangeEventArgs.ConnectChangeType.Create) => CreateInvokeConnection(), // 创建节点之间的调用关系
|
||||
(JunctionOfConnectionType.Invoke, NodeConnectChangeEventArgs.ConnectChangeType.Remove) => RemoveInvokeConnection(), // 移除节点之间的调用关系
|
||||
(JunctionOfConnectionType.Arg, NodeConnectChangeEventArgs.ConnectChangeType.Create) => CreateArgConnection(), // 创建节点之间的参数传递关系
|
||||
(JunctionOfConnectionType.Arg, NodeConnectChangeEventArgs.ConnectChangeType.Remove) => RemoveArgConnection(), // 移除节点之间的参数传递关系
|
||||
(JunctionOfConnectionType.Invoke, NodeConnectChangeEventArgs.ConnectChangeType.Create) => await CreateInvokeConnection(), // 创建节点之间的调用关系
|
||||
(JunctionOfConnectionType.Invoke, NodeConnectChangeEventArgs.ConnectChangeType.Remove) => await RemoveInvokeConnection(), // 移除节点之间的调用关系
|
||||
(JunctionOfConnectionType.Arg, NodeConnectChangeEventArgs.ConnectChangeType.Create) => await CreateArgConnection(), // 创建节点之间的参数传递关系
|
||||
(JunctionOfConnectionType.Arg, NodeConnectChangeEventArgs.ConnectChangeType.Remove) => await RemoveArgConnection(), // 移除节点之间的参数传递关系
|
||||
_ => false
|
||||
};
|
||||
return state;
|
||||
@@ -151,7 +151,7 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
/// <summary>
|
||||
/// 创建方法调用关系
|
||||
/// </summary>
|
||||
private bool CreateInvokeConnection()
|
||||
private async Task<bool> CreateInvokeConnection()
|
||||
{
|
||||
IFlowNode fromNode = FromNode ;
|
||||
IFlowNode toNode = ToNode;
|
||||
@@ -224,15 +224,20 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
}
|
||||
fromNode.SuccessorNodes[invokeType].Add(toNode); // 添加到起始节点新类别的子分支
|
||||
toNode.PreviousNodes[invokeType].Add(fromNode); // 添加到目标节点新类别的父分支
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(
|
||||
new NodeConnectChangeEventArgs(
|
||||
FlowCanvas.Guid,
|
||||
fromNode.Guid, // 从哪个节点开始
|
||||
toNode.Guid, // 连接到那个节点
|
||||
JunctionOfConnectionType.Invoke,
|
||||
invokeType, // 连接线的样式类型
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Create // 是创建连接还是删除连接
|
||||
));
|
||||
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(
|
||||
new NodeConnectChangeEventArgs(
|
||||
FlowCanvas.Guid,
|
||||
fromNode.Guid, // 从哪个节点开始
|
||||
toNode.Guid, // 连接到那个节点
|
||||
JunctionOfConnectionType.Invoke,
|
||||
invokeType, // 连接线的样式类型
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Create // 是创建连接还是删除连接
|
||||
));
|
||||
});
|
||||
|
||||
// Invoke
|
||||
// GetResult
|
||||
return true;
|
||||
@@ -248,19 +253,22 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
/// <summary>
|
||||
/// 移除方法调用关系
|
||||
/// </summary>
|
||||
private bool RemoveInvokeConnection()
|
||||
private async Task<bool> RemoveInvokeConnection()
|
||||
{
|
||||
FromNode.SuccessorNodes[ConnectionInvokeType].Remove(ToNode);
|
||||
ToNode.PreviousNodes[ConnectionInvokeType].Remove(FromNode);
|
||||
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(
|
||||
new NodeConnectChangeEventArgs(
|
||||
FlowCanvas.Guid,
|
||||
FromNode.Guid,
|
||||
ToNode.Guid,
|
||||
JunctionOfConnectionType.Invoke,
|
||||
ConnectionInvokeType,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Remove));
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(
|
||||
new NodeConnectChangeEventArgs(
|
||||
FlowCanvas.Guid,
|
||||
FromNode.Guid,
|
||||
ToNode.Guid,
|
||||
JunctionOfConnectionType.Invoke,
|
||||
ConnectionInvokeType,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Remove));
|
||||
});
|
||||
|
||||
|
||||
/* if (string.IsNullOrEmpty(ToNode.MethodDetails.ParameterDetailss[ArgIndex].ArgDataSourceNodeGuid))
|
||||
@@ -289,7 +297,7 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
/// 创建参数连接关系
|
||||
/// </summary>
|
||||
/// <exception cref="Exception"></exception>
|
||||
private bool CreateArgConnection()
|
||||
private async Task<bool> CreateArgConnection()
|
||||
{
|
||||
IFlowNode fromNodeControl = ToNode;
|
||||
IFlowNode toNodeControl = ToNode;
|
||||
@@ -304,43 +312,27 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
if (FromNode.Guid == toNodeArgSourceGuid
|
||||
&& toNodeArgSourceType == ConnectionArgSourceType)
|
||||
{
|
||||
SereinEnv.WriteLine(InfoType.INFO, $"节点之间已建立过连接关系,此次操作将不会执行" +
|
||||
SereinEnv.WriteLine(InfoType.INFO, $"节点之间已建立过连接关系" +
|
||||
$"起始节点:{FromNode.Guid}" +
|
||||
$"目标节点:{ToNode.Guid}" +
|
||||
$"参数索引:{ArgIndex}" +
|
||||
$"参数类型:{ConnectionArgSourceType}");
|
||||
/*flowEnvironmentEvent.OnNodeConnectChanged(
|
||||
new NodeConnectChangeEventArgs(
|
||||
FlowCanvas.Guid,
|
||||
FromNode.Guid, // 从哪个节点开始
|
||||
ToNode.Guid, // 连接到那个节点
|
||||
ArgIndex, // 连接线的样式类型
|
||||
JunctionOfConnectionType.Arg,
|
||||
ConnectionArgSourceType,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Create // 是创建连接还是删除连接
|
||||
)); // 通知UI */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(toNodeArgSourceGuid)) // 更改关系获取
|
||||
{
|
||||
ToNode.MethodDetails.ParameterDetailss[ArgIndex].ArgDataSourceNodeGuid = null;
|
||||
ToNode.MethodDetails.ParameterDetailss[ArgIndex].ArgDataSourceType = ConnectionArgSourceType.GetPreviousNodeData; // 恢复默认值
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(
|
||||
new NodeConnectChangeEventArgs(
|
||||
FlowCanvas.Guid,
|
||||
FromNode.Guid,
|
||||
ToNode.Guid,
|
||||
ArgIndex,
|
||||
JunctionOfConnectionType.Arg,
|
||||
ConnectionArgSourceType.GetPreviousNodeData,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Remove));
|
||||
}
|
||||
|
||||
ToNode.MethodDetails.ParameterDetailss[ArgIndex].ArgDataSourceNodeGuid = FromNode.Guid; // 设置
|
||||
ToNode.MethodDetails.ParameterDetailss[ArgIndex].ArgDataSourceType = ConnectionArgSourceType;
|
||||
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(
|
||||
new NodeConnectChangeEventArgs(
|
||||
FlowCanvas.Guid,
|
||||
FromNode.Guid, // 从哪个节点开始
|
||||
ToNode.Guid, // 连接到那个节点
|
||||
ArgIndex, // 连接线的样式类型
|
||||
JunctionOfConnectionType.Arg,
|
||||
ConnectionArgSourceType,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Remove // 是创建连接还是删除连接
|
||||
)); // 通知UI
|
||||
});
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(
|
||||
new NodeConnectChangeEventArgs(
|
||||
FlowCanvas.Guid,
|
||||
FromNode.Guid, // 从哪个节点开始
|
||||
@@ -350,6 +342,47 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
ConnectionArgSourceType,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Create // 是创建连接还是删除连接
|
||||
)); // 通知UI
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(toNodeArgSourceGuid)) // 更改关系获取
|
||||
{
|
||||
ToNode.MethodDetails.ParameterDetailss[ArgIndex].ArgDataSourceNodeGuid = null;
|
||||
ToNode.MethodDetails.ParameterDetailss[ArgIndex].ArgDataSourceType = ConnectionArgSourceType.GetPreviousNodeData; // 恢复默认值
|
||||
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(
|
||||
new NodeConnectChangeEventArgs(
|
||||
FlowCanvas.Guid,
|
||||
FromNode.Guid,
|
||||
ToNode.Guid,
|
||||
ArgIndex,
|
||||
JunctionOfConnectionType.Arg,
|
||||
ConnectionArgSourceType.GetPreviousNodeData,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Remove));
|
||||
});
|
||||
}
|
||||
|
||||
ToNode.MethodDetails.ParameterDetailss[ArgIndex].ArgDataSourceNodeGuid = FromNode.Guid; // 设置
|
||||
ToNode.MethodDetails.ParameterDetailss[ArgIndex].ArgDataSourceType = ConnectionArgSourceType;
|
||||
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(
|
||||
new NodeConnectChangeEventArgs(
|
||||
FlowCanvas.Guid,
|
||||
FromNode.Guid, // 从哪个节点开始
|
||||
ToNode.Guid, // 连接到那个节点
|
||||
ArgIndex, // 连接线的样式类型
|
||||
JunctionOfConnectionType.Arg,
|
||||
ConnectionArgSourceType,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Create // 是创建连接还是删除连接
|
||||
)); // 通知UI
|
||||
});
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
@@ -360,14 +393,15 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
/// <param name="fromNodeControl"></param>
|
||||
/// <param name="toNodeControl"></param>
|
||||
/// <param name="index"></param>
|
||||
private bool RemoveArgConnection()
|
||||
private async Task<bool> RemoveArgConnection()
|
||||
{
|
||||
ToNode.MethodDetails.ParameterDetailss[ArgIndex].ArgDataSourceNodeGuid = null;
|
||||
ToNode.MethodDetails.ParameterDetailss[ArgIndex].ArgDataSourceType = ConnectionArgSourceType.GetPreviousNodeData; // 恢复默认值
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(
|
||||
new NodeConnectChangeEventArgs(
|
||||
FlowCanvas.Guid,
|
||||
FromNode.Guid,
|
||||
@@ -376,7 +410,8 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
JunctionOfConnectionType.Arg,
|
||||
ConnectionArgSourceType.GetPreviousNodeData,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Remove));
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,30 +52,31 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
}
|
||||
|
||||
|
||||
public override bool Execute()
|
||||
public override Task<bool> ExecuteAsync()
|
||||
{
|
||||
if (!ValidationParameter()) return false;
|
||||
|
||||
if (!ValidationParameter()) return Task.FromResult(false);
|
||||
|
||||
if (IsAdd)
|
||||
{
|
||||
if (nodeModel.MethodDetails.AddParamsArg(ParamIndex))
|
||||
{
|
||||
return true;
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nodeModel.MethodDetails.RemoveParamsArg(ParamIndex))
|
||||
{
|
||||
return true;
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
using Serein.Library.Api;
|
||||
using Microsoft.VisualBasic.FileIO;
|
||||
using Serein.Library.Api;
|
||||
using Serein.Library.Utils;
|
||||
using Serein.NodeFlow.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Mime;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -72,12 +75,16 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Execute()
|
||||
public override async Task<bool> ExecuteAsync()
|
||||
{
|
||||
if (!ValidationParameter()) return false;
|
||||
|
||||
ContainerNode.PlaceNode(Node);
|
||||
flowEnvironmentEvent.OnNodePlace(new NodePlaceEventArgs(CanvasGuid, NodeGuid, ContainerNodeGuid)); // 通知UI更改节点放置位置
|
||||
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnNodePlace(new NodePlaceEventArgs(CanvasGuid, NodeGuid, ContainerNodeGuid)); // 通知UI更改节点放置位置
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,12 +61,15 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Execute()
|
||||
public override async Task<bool> ExecuteAsync()
|
||||
{
|
||||
if (!ValidationParameter()) return false;
|
||||
|
||||
ContainerNode.TakeOutNode(Node);
|
||||
flowEnvironmentEvent.OnNodeTakeOut(new NodeTakeOutEventArgs(CanvasGuid, NodeGuid)); // 重新放置在画布上
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnNodeTakeOut(new NodeTakeOutEventArgs(CanvasGuid, NodeGuid)); // 重新放置在画布上
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Execute()
|
||||
public override async Task<bool> ExecuteAsync()
|
||||
{
|
||||
if(!ValidationParameter()) return false;
|
||||
|
||||
@@ -38,7 +38,11 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
cavasnModel.LoadInfo(CanvasInfo);
|
||||
flowModelService.AddCanvasModel(cavasnModel);
|
||||
this.flowCanvasDetails = cavasnModel; ;
|
||||
flowEnvironmentEvent.OnCanvasCreated(new CanvasCreateEventArgs(cavasnModel));
|
||||
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnCanvasCreated(new CanvasCreateEventArgs(cavasnModel));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Execute()
|
||||
public override async Task<bool> ExecuteAsync()
|
||||
{
|
||||
if (!ValidationParameter()) return false; // 执行时验证
|
||||
|
||||
@@ -101,7 +101,11 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
|
||||
flowModelService.AddNodeModel(nodeModel);
|
||||
this.flowNode = nodeModel;
|
||||
flowEnvironmentEvent.OnNodeCreated(new NodeCreateEventArgs(flowCanvasDetails.Guid, nodeModel, Position));
|
||||
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnNodeCreated(new NodeCreateEventArgs(flowCanvasDetails.Guid, nodeModel, Position));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Serein.Library;
|
||||
using Serein.Library.Api;
|
||||
using Serein.Library.Utils;
|
||||
using Serein.NodeFlow.Services;
|
||||
using Serein.NodeFlow.Tool;
|
||||
using System;
|
||||
@@ -25,7 +26,7 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
/// <summary>
|
||||
/// 执行操作
|
||||
/// </summary>
|
||||
bool Execute();
|
||||
Task<bool> ExecuteAsync();
|
||||
/// <summary>
|
||||
/// 撤销操作
|
||||
/// </summary>
|
||||
@@ -46,6 +47,12 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
[AutoInjection]
|
||||
protected FlowModelService flowModelService;
|
||||
|
||||
/// <summary>
|
||||
/// 节点管理服务
|
||||
/// </summary>
|
||||
[AutoInjection]
|
||||
protected UIContextOperation uiContextOperation;
|
||||
|
||||
/// <summary>
|
||||
/// 流程依赖服务
|
||||
/// </summary>
|
||||
@@ -75,7 +82,7 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
/// <summary>
|
||||
/// 执行
|
||||
/// </summary>
|
||||
public abstract bool Execute();
|
||||
public abstract Task<bool> ExecuteAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 撤销
|
||||
@@ -96,6 +103,23 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
public abstract void ToInfo();
|
||||
|
||||
|
||||
protected async Task TriggerEvent(Action action)
|
||||
{
|
||||
/* if (OperatingSystem.IsWindows())
|
||||
{
|
||||
}*/
|
||||
if (uiContextOperation is null)
|
||||
{
|
||||
action?.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
await uiContextOperation.InvokeAsync(() =>
|
||||
{
|
||||
action?.Invoke();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Execute()
|
||||
public override async Task<bool> ExecuteAsync()
|
||||
{
|
||||
if (!ValidationParameter()) return false;
|
||||
|
||||
@@ -46,7 +46,11 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
|
||||
flowModelService.RemoveCanvasModel(flowCanvasDetails);
|
||||
flowCanvasDetailsInfo = flowCanvasDetails.ToInfo();
|
||||
flowEnvironmentEvent.OnCanvasRemoved(new CanvasRemoveEventArgs(flowCanvasDetails.Guid));
|
||||
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnCanvasRemoved(new CanvasRemoveEventArgs(flowCanvasDetails.Guid));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Execute()
|
||||
public override async Task<bool> ExecuteAsync()
|
||||
{
|
||||
if (!ValidationParameter()) return false;
|
||||
|
||||
@@ -74,8 +74,10 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
connectionType, // 对应的连接关系
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Remove); // 移除连线
|
||||
EventArgs.Add(e); // 缓存事件参数
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(e);
|
||||
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +104,10 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
connectionType, // 对应的连接关系
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Remove); // 移除连线
|
||||
EventArgs.Add(e); // 缓存事件参数
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(e);
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,7 +141,10 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
connectionType, // 对应的连接关系
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Remove); // 移除连线
|
||||
EventArgs.Add(e); // 缓存事件参数
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(e);
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnNodeConnectChanged(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,12 +161,16 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
{
|
||||
// 存在UI上下文操作,当前运行环境极有可能运行在有UI线程的平台上
|
||||
// 为了避免直接修改 ObservableCollection 集合导致异常产生,故而使用UI线程上下文操作运行
|
||||
flowEnvironment.UIContextOperation?.Invoke(() =>
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowCanvasDetails?.Nodes.Remove(flowNode);
|
||||
});
|
||||
}
|
||||
flowEnvironmentEvent.OnNodeRemoved(new NodeRemoveEventArgs(CanvasGuid, NodeGuid));
|
||||
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnNodeRemoved(new NodeRemoveEventArgs(CanvasGuid, NodeGuid));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,9 +46,9 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
/// <summary>
|
||||
/// 成为首项
|
||||
/// </summary>
|
||||
public override bool Execute()
|
||||
public override Task<bool> ExecuteAsync()
|
||||
{
|
||||
if(!ValidationParameter()) return false;
|
||||
if(!ValidationParameter()) return Task.FromResult(false);
|
||||
|
||||
if (FromNode.SuccessorNodes.TryGetValue(ConnectionType, out var nodes))
|
||||
{
|
||||
@@ -60,7 +60,7 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
nodes.Insert(0, ToNode);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public override bool Execute()
|
||||
public override async Task<bool> ExecuteAsync()
|
||||
{
|
||||
if (!ValidationParameter()) return false;
|
||||
|
||||
@@ -45,7 +45,11 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
}
|
||||
|
||||
CanvasModel.StartNode = NewStartNodeModel;
|
||||
flowEnvironmentEvent.OnStartNodeChanged(new StartNodeChangeEventArgs(CanvasModel.Guid, OldStartNodeModel?.Guid, NewStartNodeModel.Guid));
|
||||
|
||||
await TriggerEvent(() =>
|
||||
{
|
||||
flowEnvironmentEvent.OnStartNodeChanged(new StartNodeChangeEventArgs(CanvasModel.Guid, OldStartNodeModel?.Guid, NewStartNodeModel.Guid));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,10 @@
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.6" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Serein.Library.MyGenerator\Serein.Library.NodeGenerator.csproj" OutputItemType="Analyzer" />
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Serein.NodeFlow.Services
|
||||
{
|
||||
@@ -113,5 +114,53 @@ namespace Serein.NodeFlow.Services
|
||||
return flowCanvasDetails.Nodes.Count > 0;
|
||||
}
|
||||
|
||||
|
||||
public void ToCsharpCoreFile()
|
||||
{
|
||||
// TODO: 实现将流程模型转换为C# Core文件的逻辑
|
||||
// 遍历每个画布
|
||||
int canvas_index = 0;
|
||||
|
||||
HashSet<Type> assemblyFlowClasss = new HashSet<Type>(); // 用于创建依赖注入项
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
foreach (var canvas in FlowCanvass.Values)
|
||||
{
|
||||
int flowTemplateId = canvas_index++;
|
||||
string flowTemplateClassName = $"FlowTemplate{flowTemplateId}";
|
||||
|
||||
HashSet<Type> flowClasss = new HashSet<Type>();
|
||||
|
||||
// 收集程序集信息
|
||||
foreach (var node in canvas.Nodes)
|
||||
{
|
||||
var instanceType = node.MethodDetails.ActingInstanceType;
|
||||
if(instanceType is not null)
|
||||
{
|
||||
flowClasss.Add(instanceType);
|
||||
assemblyFlowClasss.Add(instanceType);
|
||||
}
|
||||
}
|
||||
|
||||
// 生成方法信息
|
||||
foreach (var node in canvas.Nodes)
|
||||
{
|
||||
var instanceType = node.MethodDetails.ActingInstanceType;
|
||||
var returnType = node.MethodDetails.ReturnType;
|
||||
var methodName = node.MethodDetails.MethodAnotherName;
|
||||
|
||||
|
||||
|
||||
var instanceTypeFullName = instanceType.FullName;
|
||||
var returnTypeFullName = returnType == typeof(void) ? "void" : returnType.FullName;
|
||||
|
||||
string methodContext = $"private {returnTypeFullName} NodeMethod_{methodName}({nameof(IDynamicContext)} context)";
|
||||
SereinEnv.WriteLine(InfoType.INFO, methodContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,12 +50,12 @@ namespace Serein.NodeFlow.Services
|
||||
/// <summary>
|
||||
/// 重做
|
||||
/// </summary>
|
||||
public void Redo()
|
||||
public async Task Redo()
|
||||
{
|
||||
if (redoStack.Count > 0)
|
||||
{
|
||||
var command = redoStack.Pop();
|
||||
var state = command.Execute();
|
||||
var state = await command.ExecuteAsync();
|
||||
if (state)
|
||||
{
|
||||
undoStack.Push(command); // 将重做的命令推入撤销栈
|
||||
@@ -64,10 +64,10 @@ namespace Serein.NodeFlow.Services
|
||||
}
|
||||
|
||||
|
||||
internal void Execute(IOperation operation)
|
||||
internal async Task Execute(IOperation operation)
|
||||
{
|
||||
sereinIOC.InjectDependenciesProperty(operation); // 注入所需要的依赖
|
||||
var state = operation.Execute();
|
||||
var state = await operation.ExecuteAsync();
|
||||
if (state)
|
||||
{
|
||||
// 执行后,推入撤销栈,并清空重做栈
|
||||
|
||||
@@ -273,14 +273,11 @@ namespace Serein.NodeFlow.Services
|
||||
var pool = WorkOptions.FlowContextPool;
|
||||
var context = pool.Allocate();
|
||||
var token = WorkOptions.CancellationTokenSource.Token;
|
||||
await startNode.StartFlowAsync(context, token); // 开始运行时从选定节点开始运行
|
||||
var result = await startNode.StartFlowAsync(context, token); // 开始运行时从选定节点开始运行
|
||||
context.Reset();
|
||||
pool.Free(context);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 尝试添加全局触发器
|
||||
/// </summary>
|
||||
@@ -295,6 +292,7 @@ namespace Serein.NodeFlow.Services
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 尝试移除全局触发器
|
||||
/// </summary>
|
||||
@@ -344,7 +342,7 @@ namespace Serein.NodeFlow.Services
|
||||
{
|
||||
var context = pool.Allocate(); // 启动全局触发器时新建上下文
|
||||
var newFlowData = await singleFlipFlopNode.ExecutingAsync(context, singleToken); // 获取触发器等待Task
|
||||
context.AddOrUpdate(singleFlipFlopNode, newFlowData);
|
||||
context.AddOrUpdate(singleFlipFlopNode.Guid, newFlowData);
|
||||
if (context.NextOrientation == ConnectionInvokeType.None)
|
||||
{
|
||||
continue;
|
||||
@@ -388,7 +386,7 @@ namespace Serein.NodeFlow.Services
|
||||
{
|
||||
continue;
|
||||
}
|
||||
context.SetPreviousNode(nextNodes[i], singleFlipFlopNode); // 设置调用关系
|
||||
context.SetPreviousNode(nextNodes[i].Guid, singleFlipFlopNode.Guid); // 设置调用关系
|
||||
|
||||
if (nextNodes[i].DebugSetting.IsInterrupt) // 执行触发前检查终端
|
||||
{
|
||||
@@ -407,7 +405,7 @@ namespace Serein.NodeFlow.Services
|
||||
continue;
|
||||
}
|
||||
|
||||
context.SetPreviousNode(nextNodes[i], singleFlipFlopNode);
|
||||
context.SetPreviousNode(nextNodes[i].Guid, singleFlipFlopNode.Guid);
|
||||
if (nextNodes[i].DebugSetting.IsInterrupt) // 执行触发前
|
||||
{
|
||||
await nextNodes[i].DebugSetting.GetInterruptTask.Invoke();
|
||||
|
||||
Reference in New Issue
Block a user