流程返回值改为FlowResult,记录节点信息、上下文信息,为以后的流程调用回溯做准备

This commit is contained in:
fengjiayi
2025-03-21 18:26:01 +08:00
parent 9941f24c5d
commit f99aff3c2c
30 changed files with 916 additions and 752 deletions

View File

@@ -36,7 +36,7 @@ namespace Serein.NodeFlow.Model
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override async Task<object?> ExecutingAsync(IDynamicContext context, CancellationToken token)
public override async Task<FlowResult> ExecutingAsync(IDynamicContext context, CancellationToken token)
{
try
{
@@ -45,7 +45,7 @@ namespace Serein.NodeFlow.Model
{
if (token.IsCancellationRequested)
{
return null;
return new FlowResult(this, context);
}
var state = await node.ExecutingAsync(context, token);
if (context.NextOrientation != ConnectionInvokeType.IsSucceed)
@@ -56,7 +56,8 @@ namespace Serein.NodeFlow.Model
}
//var previousNode = context.GetPreviousNode()
return context.TransmissionData(this); // 条件区域透传上一节点的数据
var result = context.TransmissionData(this); // 条件区域透传上一节点的数据
return new FlowResult(this,context, result);
}
catch (Exception ex)
{

View File

@@ -110,9 +110,12 @@ namespace Serein.NodeFlow.Model
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override async Task<object?> ExecutingAsync(IDynamicContext context, CancellationToken token)
public override async Task<FlowResult> ExecutingAsync(IDynamicContext context, CancellationToken token)
{
if (token.IsCancellationRequested) return null;
if (token.IsCancellationRequested)
{
return new FlowResult(this, context);
}
// 接收上一节点参数or自定义参数内容
object? parameter;
object? result = null;
@@ -121,17 +124,31 @@ namespace Serein.NodeFlow.Model
{
// 使用自动取参
var pd = MethodDetails.ParameterDetailss[INDEX_EXPRESSION];
var hasNode = context.Env.TryGetNodeModel(pd.ArgDataSourceNodeGuid, out var argSourceNode);
if (hasNode)
{
context.NextOrientation = ConnectionInvokeType.IsError;
return new FlowResult(this, context);
}
if (hasNode)
{
return new FlowResult(this, context);
}
if (pd.ArgDataSourceType == ConnectionArgSourceType.GetOtherNodeData)
{
result = context.GetFlowData(pd.ArgDataSourceNodeGuid); // 使用自定义节点的参数
result = context.GetFlowData(argSourceNode).Value; // 使用自定义节点的参数
}
else if (pd.ArgDataSourceType == ConnectionArgSourceType.GetOtherNodeDataOfInvoke)
{
result = await Env.InvokeNodeAsync(context, pd.ArgDataSourceNodeGuid); // 立刻调用目标节点,然后使用其返回值
CancellationTokenSource cts = new CancellationTokenSource();
var nodeResult = await argSourceNode.ExecutingAsync(context, cts.Token);
result = nodeResult.Value;
cts?.Cancel();
cts?.Dispose();
}
else
{
result = context.TransmissionData(this); // 条件节点透传上一节点的数据
result = context.TransmissionData(this).Value; // 条件节点透传上一节点的数据
}
parameter = result; // 使用上一节点的参数
@@ -167,7 +184,7 @@ namespace Serein.NodeFlow.Model
SereinEnv.WriteLine(InfoType.INFO, $"{result} {Expression} -> " + context.NextOrientation);
//return result;
return judgmentResult;
return new FlowResult(this, context, judgmentResult);
}

View File

@@ -92,22 +92,32 @@ namespace Serein.NodeFlow.Model
}
public override async Task<object?> ExecutingAsync(IDynamicContext context, CancellationToken token)
public override async Task<FlowResult> ExecutingAsync(IDynamicContext context, CancellationToken token)
{
if(token.IsCancellationRequested) return null;
if(token.IsCancellationRequested) return new FlowResult(this, context);
object? parameter = null;// context.TransmissionData(this); // 表达式节点使用上一节点数据
var pd = MethodDetails.ParameterDetailss[0];
var hasNode = context.Env.TryGetNodeModel(pd.ArgDataSourceNodeGuid, out var argSourceNode);
if (hasNode)
{
context.NextOrientation = ConnectionInvokeType.IsError;
return new FlowResult(this, context);
}
if (pd.ArgDataSourceType == ConnectionArgSourceType.GetOtherNodeData)
{
// 使用自定义节点的参数
parameter = context.GetFlowData(pd.ArgDataSourceNodeGuid);
parameter = context.GetFlowData(argSourceNode).Value;
}
else if (pd.ArgDataSourceType == ConnectionArgSourceType.GetOtherNodeDataOfInvoke)
{
// 立刻调用目标节点,然后使用其返回值
parameter = await Env.InvokeNodeAsync(context, pd.ArgDataSourceNodeGuid);
var cts = new CancellationTokenSource();
var result = await argSourceNode.ExecutingAsync(context, cts.Token);
cts?.Cancel();
cts?.Dispose();
parameter = result.Value;
}
else
{
@@ -129,13 +139,13 @@ namespace Serein.NodeFlow.Model
}
context.NextOrientation = ConnectionInvokeType.IsSucceed;
return result;
return new FlowResult(this,context, result);
}
catch (Exception ex)
{
context.NextOrientation = ConnectionInvokeType.IsError;
context.ExceptionOfRuning = ex;
return parameter;
return new FlowResult(this, context);
}
}

View File

@@ -22,7 +22,7 @@ namespace Serein.NodeFlow.Model
/// <param name="context"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public override async Task<object?> ExecutingAsync(IDynamicContext context, CancellationToken token)
public override async Task<FlowResult> ExecutingAsync(IDynamicContext context, CancellationToken token)
{
#region
if (DebugSetting.IsInterrupt) // 执行触发前
@@ -40,8 +40,13 @@ namespace Serein.NodeFlow.Model
}
var instance = context.Env.IOC.Get(md.ActingInstanceType);
if (instance is null)
{
Env.IOC.Register(md.ActingInstanceType).Build();
instance = Env.IOC.Get(md.ActingInstanceType);
}
await dd.InvokeAsync(instance, [context]);
var args = await GetParametersAsync(context, token);
var args = await this.GetParametersAsync(context, token);
// 因为这里会返回不确定的泛型 IFlipflopContext<TRsult>
// 而我们只需要获取到 State 和 Value返回的数据
// 所以使用 dynamic 类型接收
@@ -58,7 +63,9 @@ namespace Serein.NodeFlow.Model
{
throw new FlipflopException(base.MethodDetails.MethodName + "触发器超时触发。Guid" + base.Guid);
}
return dynamicFlipflopContext.Value;
object result = dynamicFlipflopContext.Value;
var flowReslt = new FlowResult(this, context, result);
return flowReslt;
}
}

View File

@@ -115,33 +115,34 @@ namespace Serein.NodeFlow.Model
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override async Task<object?> ExecutingAsync(IDynamicContext context, CancellationToken token)
public override async Task<FlowResult> ExecutingAsync(IDynamicContext context, CancellationToken token)
{
if (token.IsCancellationRequested) return null;
if (token.IsCancellationRequested) return new FlowResult(this, context);
if (string.IsNullOrEmpty(KeyName))
{
context.NextOrientation = ConnectionInvokeType.IsError;
SereinEnv.WriteLine(InfoType.ERROR, $"全局数据的KeyName不能为空[{this.Guid}]");
return null;
return new FlowResult(this, context);
}
if (DataNode is null)
{
context.NextOrientation = ConnectionInvokeType.IsError;
SereinEnv.WriteLine(InfoType.ERROR, $"全局数据节点没有设置数据来源[{this.Guid}]");
return null;
return new FlowResult(this, context);
}
try
{
var result = await context.Env.InvokeNodeAsync(context, DataNode.Guid);
SereinEnv.AddOrUpdateFlowGlobalData(KeyName, result);
var result = await DataNode.ExecutingAsync(context, token);
SereinEnv.AddOrUpdateFlowGlobalData(KeyName, result.Value);
return result;
}
catch (Exception ex)
{
context.NextOrientation = ConnectionInvokeType.IsError;
context.ExceptionOfRuning = ex;
return null;
return new FlowResult(this, context);
}
}

View File

@@ -165,12 +165,11 @@ namespace Serein.NodeFlow.Model
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override async Task<object?> ExecutingAsync(IDynamicContext context, CancellationToken token)
public override async Task<FlowResult> ExecutingAsync(IDynamicContext context, CancellationToken token)
{
if(token.IsCancellationRequested) return null;
var @params = await GetParametersAsync(context, token);
if(token.IsCancellationRequested) return null;
if (token.IsCancellationRequested) return new FlowResult(this, context);
var @params = await this.GetParametersAsync(context, token);
if(token.IsCancellationRequested) return new FlowResult(this, context);
//context.AddOrUpdate($"{context.Guid}_{this.Guid}_Params", @params[0]); // 后面再改
ReloadScript();// 每次都重新解析
@@ -199,9 +198,9 @@ namespace Serein.NodeFlow.Model
if (token.IsCancellationRequested) return null;
var result = await ScriptInterpreter.InterpretAsync(scriptContext, mainNode); // 从入口节点执行
envEvent.OnFlowRunComplete -= onFlowStop;
envEvent.OnFlowRunComplete -= onFlowStop;
return new FlowResult(this, context, result);
//SereinEnv.WriteLine(InfoType.INFO, "FlowContext Guid : " + context.Guid);
return result;
}

View File

@@ -15,14 +15,14 @@ namespace Serein.NodeFlow.Model
{
}
public override async Task<object?> ExecutingAsync(IDynamicContext context, CancellationToken token)
public override async Task<FlowResult> ExecutingAsync(IDynamicContext context, CancellationToken token)
{
if (token.IsCancellationRequested) return null;
if (token.IsCancellationRequested) return new FlowResult(this,context);
if(Adapter is null)
{
var result = await base.ExecutingAsync(context, token);
if (result is IEmbeddedContent adapter)
if (result.Value is IEmbeddedContent adapter)
{
this.Adapter = adapter;
context.NextOrientation = ConnectionInvokeType.IsSucceed;
@@ -35,12 +35,12 @@ namespace Serein.NodeFlow.Model
else
{
var p = context.GetPreviousNode(this);
var data = context.GetFlowData(p.Guid);
var data = context.GetFlowData(p).Value;
var iflowContorl = Adapter.GetFlowControl();
iflowContorl.OnExecuting(data);
}
return null;
return new FlowResult(this, context);
}
}
}