Files
serein-flow/NodeFlow/Model/Nodes/SingleFlipflopNode.cs
fengjiayi 1bccccc835 1. 重新设计了 JSON门户类的实现
2. Script脚本添加了原始字符串的实现
3. 修复了Script中无法对  \" 双引号转义的问题
4. 新增了对于集合嵌套取值的支持(目前仅是集合取值)
5. 重新设计了FlowWorkManagement任务启动的逻辑,修复了触发器无法正常运行的问题
6. 在ScriptBaseFunc中新增了 json() 本地函数,支持将字符串转为IJsonToken进行取值。
7. EmitHelper对于集合取值时,反射获取“get_item”委托时存在看你多个MethodInfo,现在可以传入子项类型,帮助匹配目标重载方法
2025-07-31 23:59:31 +08:00

96 lines
3.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Serein.Library.Api;
using Serein.Library;
using Serein.Library.Utils;
using System;
namespace Serein.NodeFlow.Model.Nodes
{
[FlowDataProperty(ValuePath = NodeValuePath.Node, IsNodeImp = true)]
public partial class SingleFlipflopNode
{
/// <summary>
/// <para>是否等待后继节点(仅对于全局触发器)</para>
/// <para>如果为 true则在触发器获取结果后等待后继节点执行完成才会调用触发器</para>
/// <para>如果为 false则触发器获取到结果后将使用 _ = Task.Run(...) 再次调用触发器</para>
/// </summary>
private bool _isWaitSuccessorNodes = true;
}
/// <summary>
/// 触发器节点
/// </summary>
public partial class SingleFlipflopNode : NodeModelBase
{
/// <summary>
/// 构造一个新的单触发器节点实例。
/// </summary>
/// <param name="environment"></param>
public SingleFlipflopNode(IFlowEnvironment environment) : base(environment)
{
}
/// <summary>
/// 执行触发器进行等待触发
/// </summary>
/// <param name="context"></param>
/// <param name="token"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public override async Task<FlowResult> ExecutingAsync(IFlowContext context, CancellationToken token)
{
if (token.IsCancellationRequested)
{
return FlowResult.Fail(Guid, context, "流程操作已取消");
}
#region
if (DebugSetting.IsInterrupt) // 执行触发前
{
SereinEnv.WriteLine(InfoType.INFO, $"[{MethodDetails.MethodName}]进入中断");
await DebugSetting.GetInterruptTask.Invoke();
SereinEnv.WriteLine(InfoType.INFO, $"[{MethodDetails.MethodName}]中断已取消,开始执行后继分支");
}
#endregion
MethodDetails md = MethodDetails;
if (!context.Env.TryGetDelegateDetails(md.AssemblyName, md.MethodName, out var dd)) // 流程运行到某个节点
{
context.Exit();
context.ExceptionOfRuning = new FlipflopException($"无法获取到委托 {md.MethodName} 的详细信息。请检查流程配置。");
return FlowResult.Fail(Guid, context, "不存在对应委托");
}
var ioc = Env.FlowControl.IOC;
var instance = ioc.Get(md.ActingInstanceType);
if (instance is null)
{
ioc.Register(md.ActingInstanceType).Build();
instance = ioc.Get(md.ActingInstanceType);
}
var args = MethodDetails.ParameterDetailss.Length == 0 ? [] : await this.GetParametersAsync(context, token);
// 因为这里会返回不确定的泛型 IFlipflopContext<TRsult>
// 而我们只需要获取到 State 和 Value返回的数据
// 所以使用 dynamic 类型接收
dynamic flipflopContext = await dd.InvokeAsync(instance, args);
FlipflopStateType flipflopStateType = flipflopContext.State;
context.NextOrientation = flipflopStateType.ToContentType();
if (flipflopContext.Type == TriggerDescription.Overtime)
{
throw new FlipflopException(MethodDetails.MethodName + "触发器超时触发。Guid" + Guid);
}
object result = flipflopContext.Value;
var flowReslt = FlowResult.OK(this.Guid, context, result);
return flowReslt;
}
}
}