2024-08-06 16:09:46 +08:00
using Newtonsoft.Json ;
2024-09-18 16:45:41 +08:00
using Newtonsoft.Json.Linq ;
2024-09-12 20:32:54 +08:00
using Serein.Library.Api ;
2024-09-27 10:30:19 +08:00
using Serein.Library.Attributes ;
2024-09-15 12:15:32 +08:00
using Serein.Library.Entity ;
2024-09-12 20:32:54 +08:00
using Serein.Library.Enums ;
2024-09-15 22:07:10 +08:00
using Serein.Library.Ex ;
2024-09-27 10:30:19 +08:00
using Serein.Library.Utils ;
2024-09-16 19:53:36 +08:00
using Serein.NodeFlow.Tool.SereinExpression ;
2024-09-15 12:15:32 +08:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
2024-09-22 14:10:13 +08:00
using System.Linq.Expressions ;
2024-09-18 16:45:41 +08:00
using System.Net.Http.Headers ;
2024-09-27 10:30:19 +08:00
using System.Reflection ;
2024-09-15 12:15:32 +08:00
using System.Text ;
using System.Threading.Tasks ;
2024-09-21 10:06:44 +08:00
using System.Xml.Linq ;
2024-09-20 10:50:32 +08:00
using static Serein . Library . Utils . ChannelFlowInterrupt ;
2024-08-06 16:09:46 +08:00
2024-09-15 12:15:32 +08:00
namespace Serein.NodeFlow.Base
2024-08-06 16:09:46 +08:00
{
/// <summary>
/// 节点基类(数据):条件控件,动作控件,条件区域,动作区域
/// </summary>
2024-09-15 12:15:32 +08:00
public abstract partial class NodeModelBase : IDynamicFlowNode
2024-08-06 16:09:46 +08:00
{
2024-09-20 10:50:32 +08:00
#region 调 试 中 断
2024-09-21 10:06:44 +08:00
2024-09-20 10:50:32 +08:00
/// <summary>
/// 不再中断
/// </summary>
public void CancelInterrupt ( )
{
this . DebugSetting . InterruptClass = InterruptClass . None ;
2024-09-22 17:37:32 +08:00
DebugSetting . CancelInterruptCallback ? . Invoke ( ) ;
2024-09-20 10:50:32 +08:00
}
2024-09-22 17:37:32 +08:00
2024-09-20 10:50:32 +08:00
#endregion
2024-09-18 16:45:41 +08:00
#region 导 出 / 导 入 项 目 文 件 节 点 信 息
2024-09-17 14:20:27 +08:00
internal abstract Parameterdata [ ] GetParameterdatas ( ) ;
internal virtual NodeInfo ToInfo ( )
2024-09-15 12:15:32 +08:00
{
2024-09-17 14:20:27 +08:00
// if (MethodDetails == null) return null;
2024-08-06 16:09:46 +08:00
2024-09-15 12:15:32 +08:00
var trueNodes = SuccessorNodes [ ConnectionType . IsSucceed ] . Select ( item = > item . Guid ) ; // 真分支
var falseNodes = SuccessorNodes [ ConnectionType . IsFail ] . Select ( item = > item . Guid ) ; // 假分支
2024-09-17 14:20:27 +08:00
var errorNodes = SuccessorNodes [ ConnectionType . IsError ] . Select ( item = > item . Guid ) ; // 异常分支
var upstreamNodes = SuccessorNodes [ ConnectionType . Upstream ] . Select ( item = > item . Guid ) ; // 上游分支
2024-09-09 16:42:01 +08:00
2024-09-15 12:15:32 +08:00
// 生成参数列表
Parameterdata [ ] parameterData = GetParameterdatas ( ) ;
2024-08-06 16:09:46 +08:00
2024-09-15 12:15:32 +08:00
return new NodeInfo
{
Guid = Guid ,
MethodName = MethodDetails ? . MethodName ,
Label = DisplayName ? ? "" ,
Type = this . GetType ( ) . ToString ( ) ,
TrueNodes = trueNodes . ToArray ( ) ,
FalseNodes = falseNodes . ToArray ( ) ,
UpstreamNodes = upstreamNodes . ToArray ( ) ,
ParameterData = parameterData . ToArray ( ) ,
ErrorNodes = errorNodes . ToArray ( ) ,
2024-09-18 16:45:41 +08:00
2024-09-15 12:15:32 +08:00
} ;
}
2024-08-06 16:09:46 +08:00
2024-09-17 14:20:27 +08:00
internal virtual NodeModelBase LoadInfo ( NodeInfo nodeInfo )
{
2024-09-30 22:20:02 +08:00
this . Guid = nodeInfo . Guid ;
if ( this . MethodDetails is not null )
2024-09-17 14:20:27 +08:00
{
for ( int i = 0 ; i < nodeInfo . ParameterData . Length ; i + + )
{
Parameterdata ? pd = nodeInfo . ParameterData [ i ] ;
2024-09-30 22:20:02 +08:00
this . MethodDetails . ExplicitDatas [ i ] . IsExplicitData = pd . State ;
this . MethodDetails . ExplicitDatas [ i ] . DataValue = pd . Value ;
2024-09-17 14:20:27 +08:00
}
}
2024-09-30 22:20:02 +08:00
2024-09-17 14:20:27 +08:00
return this ;
}
2024-09-15 19:48:27 +08:00
2024-09-18 16:45:41 +08:00
#endregion
2024-09-15 19:48:27 +08:00
2024-09-20 10:50:32 +08:00
#region 节 点 方 法 的 执 行
2024-09-15 19:48:27 +08:00
/// <summary>
/// 开始执行
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
2024-09-20 10:50:32 +08:00
public async Task StartExecute ( IDynamicContext context )
2024-09-15 19:48:27 +08:00
{
2024-09-22 14:10:13 +08:00
Stack < NodeModelBase > stack = new Stack < NodeModelBase > ( ) ;
stack . Push ( this ) ;
2024-09-24 22:39:43 +08:00
var cts = context . Env . IOC . Get < CancellationTokenSource > ( FlowStarter . FlipFlopCtsName ) ;
2024-09-25 22:20:23 +08:00
while ( stack . Count > 0 ) // 循环中直到栈为空才会退出循环
2024-09-15 19:48:27 +08:00
{
2024-09-25 22:20:23 +08:00
if ( cts is not null )
{
if ( cts . IsCancellationRequested )
break ;
}
2024-09-22 17:37:32 +08:00
// 节点执行异常时跳过执行
2024-09-22 14:10:13 +08:00
// 从栈中弹出一个节点作为当前节点进行处理
var currentNode = stack . Pop ( ) ;
2024-09-15 19:48:27 +08:00
2024-09-27 10:30:19 +08:00
//// 设置方法执行的对象
//if (currentNode.MethodDetails?.ActingInstance is not null && currentNode.MethodDetails?.ActingInstanceType is not null)
//{
// currentNode.MethodDetails.ActingInstance = context.Env.IOC.GetOrRegisterInstantiate(currentNode.MethodDetails.ActingInstanceType);
//}
2024-09-21 10:06:44 +08:00
2024-09-22 14:10:13 +08:00
#region 执 行 相 关
2024-09-20 10:50:32 +08:00
2024-09-22 14:10:13 +08:00
// 首先执行上游分支
var upstreamNodes = currentNode . SuccessorNodes [ ConnectionType . Upstream ] ;
for ( int i = upstreamNodes . Count - 1 ; i > = 0 ; i - - )
{
2024-09-22 17:37:32 +08:00
// 筛选出启用的节点
if ( upstreamNodes [ i ] . DebugSetting . IsEnable )
2024-09-21 10:06:44 +08:00
{
2024-09-22 17:37:32 +08:00
if ( upstreamNodes [ i ] . DebugSetting . InterruptClass ! = InterruptClass . None ) // 执行触发前
{
var cancelType = await upstreamNodes [ i ] . DebugSetting . GetInterruptTask ( ) ;
2024-09-30 22:20:02 +08:00
await Console . Out . WriteLineAsync ( $"[{upstreamNodes[i]?.MethodDetails?.MethodName}]中断已{cancelType},开始执行后继分支" ) ;
2024-09-22 17:37:32 +08:00
}
2024-09-22 14:10:13 +08:00
upstreamNodes [ i ] . PreviousNode = currentNode ;
2024-09-22 17:37:32 +08:00
await upstreamNodes [ i ] . StartExecute ( context ) ; // 执行流程节点的上游分支
2024-09-20 10:50:32 +08:00
}
2024-09-21 10:06:44 +08:00
}
2024-09-15 19:48:27 +08:00
2024-09-21 10:06:44 +08:00
2024-09-22 17:37:32 +08:00
// 执行当前节点
object? newFlowData = await currentNode . ExecutingAsync ( context ) ;
2024-09-25 22:20:23 +08:00
if ( cts is null | | cts . IsCancellationRequested | | currentNode . NextOrientation = = ConnectionType . None )
2024-09-22 14:10:13 +08:00
{
// 不再执行
break ;
}
2024-09-22 17:37:32 +08:00
await RefreshFlowDataAndExpInterrupt ( context , currentNode , newFlowData ) ; // 执行当前节点后刷新数据
#endregion
2024-09-22 14:10:13 +08:00
2024-09-22 17:37:32 +08:00
#region 执 行 完 成
2024-09-22 14:10:13 +08:00
// 选择后继分支
var nextNodes = currentNode . SuccessorNodes [ currentNode . NextOrientation ] ;
// 将下一个节点集合中的所有节点逆序推入栈中
for ( int i = nextNodes . Count - 1 ; i > = 0 ; i - - )
{
2024-09-22 17:37:32 +08:00
// 筛选出启用的节点、未被中断的节点
if ( nextNodes [ i ] . DebugSetting . IsEnable /*&& nextNodes[i].DebugSetting.InterruptClass == InterruptClass.None*/ )
2024-09-22 14:10:13 +08:00
{
2024-09-22 17:37:32 +08:00
if ( nextNodes [ i ] . DebugSetting . InterruptClass ! = InterruptClass . None ) // 执行触发前
{
var cancelType = await nextNodes [ i ] . DebugSetting . GetInterruptTask ( ) ;
2024-09-30 22:20:02 +08:00
await Console . Out . WriteLineAsync ( $"[{nextNodes[i]?.MethodDetails?.MethodName}]中断已{cancelType},开始执行后继分支" ) ;
2024-09-22 17:37:32 +08:00
}
2024-09-22 14:10:13 +08:00
nextNodes [ i ] . PreviousNode = currentNode ;
stack . Push ( nextNodes [ i ] ) ;
}
}
#endregion
2024-09-22 17:37:32 +08:00
2024-09-22 14:10:13 +08:00
}
2024-09-20 10:50:32 +08:00
}
2024-09-15 19:48:27 +08:00
2024-09-22 17:37:32 +08:00
2024-09-09 16:42:01 +08:00
/// <summary>
/// 执行节点对应的方法
/// </summary>
/// <param name="context">流程上下文</param>
/// <returns>节点传回数据对象</returns>
2024-09-20 10:50:32 +08:00
public virtual async Task < object? > ExecutingAsync ( IDynamicContext context )
2024-08-06 16:09:46 +08:00
{
2024-09-20 10:50:32 +08:00
#region 调 试 中 断
2024-09-22 17:37:32 +08:00
if ( DebugSetting . InterruptClass ! = InterruptClass . None ) // 执行触发前
2024-09-20 10:50:32 +08:00
{
2024-09-22 17:37:32 +08:00
var cancelType = await this . DebugSetting . GetInterruptTask ( ) ;
//if(cancelType == CancelType.Discard)
//{
// this.NextOrientation = ConnectionType.None;
// return null;
//}
2024-09-30 22:20:02 +08:00
await Console . Out . WriteLineAsync ( $"[{this.MethodDetails?.MethodName}]中断已{cancelType},开始执行后继分支" ) ;
2024-09-20 10:50:32 +08:00
}
#endregion
2024-09-30 22:20:02 +08:00
MethodDetails ? md = MethodDetails ;
2024-09-30 02:45:49 +08:00
//var del = md.MethodDelegate.Clone();
2024-09-30 22:20:02 +08:00
if ( md is null )
{
throw new Exception ( $"节点{this.Guid}不存在方法信息, 请检查是否需要重写节点的ExecutingAsync" ) ;
}
2024-09-30 02:45:49 +08:00
if ( ! context . Env . TryGetDelegate ( md . MethodName , out var del ) )
{
2024-09-30 22:20:02 +08:00
throw new Exception ( $"节点{this.Guid}不存在对应委托" ) ;
2024-09-30 02:45:49 +08:00
}
2024-09-30 22:20:02 +08:00
md . ActingInstance ? ? = context . Env . IOC . Get ( md . ActingInstanceType ) ;
2024-09-18 16:45:41 +08:00
object instance = md . ActingInstance ;
var haveParameter = md . ExplicitDatas . Length > 0 ;
var haveResult = md . ReturnType ! = typeof ( void ) ;
2024-09-09 16:42:01 +08:00
try
2024-08-06 16:09:46 +08:00
{
2024-09-18 16:45:41 +08:00
// Action/Func([方法作用的实例],[可能的参数值],[可能的返回值])
2024-09-22 17:37:32 +08:00
object? [ ] ? parameters = GetParameters ( context , this , md ) ;
2024-09-18 16:45:41 +08:00
object? result = ( haveParameter , haveResult ) switch
2024-08-06 16:09:46 +08:00
{
2024-09-18 16:45:41 +08:00
( false , false ) = > Execution ( ( Action < object > ) del , instance ) , // 调用节点方法, 返回null
2024-09-21 10:06:44 +08:00
( true , false ) = > Execution ( ( Action < object , object? [ ] ? > ) del , instance , parameters ) , // 调用节点方法, 返回null
2024-09-18 16:45:41 +08:00
( false , true ) = > Execution ( ( Func < object , object? > ) del , instance ) , // 调用节点方法,返回方法传回类型
2024-09-21 10:06:44 +08:00
( true , true ) = > Execution ( ( Func < object , object? [ ] ? , object? > ) del , instance , parameters ) , // 调用节点方法,获取入参参数,返回方法忏悔类型
2024-09-18 16:45:41 +08:00
} ;
2024-09-21 10:06:44 +08:00
2024-09-15 22:07:10 +08:00
NextOrientation = ConnectionType . IsSucceed ;
2024-09-09 16:42:01 +08:00
return result ;
}
catch ( Exception ex )
{
2024-10-07 15:15:18 +08:00
await Console . Out . WriteLineAsync ( $"节点[{this.MethodDetails?.MethodName}]异常:" + ex . Message ) ;
2024-09-15 22:07:10 +08:00
NextOrientation = ConnectionType . IsError ;
2024-09-15 12:15:32 +08:00
RuningException = ex ;
2024-09-18 16:45:41 +08:00
return null ;
2024-08-06 16:09:46 +08:00
}
}
2024-09-18 16:45:41 +08:00
#region 节 点 转 换 的 委 托 类 型
public static object? Execution ( Action < object > del , object instance )
{
del ? . Invoke ( instance ) ;
return null ;
}
public static object? Execution ( Action < object , object? [ ] ? > del , object instance , object? [ ] ? parameters )
{
del ? . Invoke ( instance , parameters ) ;
return null ;
}
public static object? Execution ( Func < object , object? > del , object instance )
{
return del ? . Invoke ( instance ) ;
}
public static object? Execution ( Func < object , object? [ ] ? , object? > del , object instance , object? [ ] ? parameters )
{
return del ? . Invoke ( instance , parameters ) ;
2024-08-06 16:09:46 +08:00
}
2024-09-18 16:45:41 +08:00
#endregion
2024-08-06 16:09:46 +08:00
2024-09-09 16:42:01 +08:00
/// <summary>
/// 获取对应的参数数组
/// </summary>
2024-09-22 14:10:13 +08:00
public static object? [ ] ? GetParameters ( IDynamicContext context , NodeModelBase nodeModel , MethodDetails md )
2024-08-06 16:09:46 +08:00
{
// 用正确的大小初始化参数数组
2024-09-20 10:50:32 +08:00
if ( md . ExplicitDatas . Length = = 0 )
2024-08-06 16:09:46 +08:00
{
2024-09-21 10:06:44 +08:00
return null ; // md.ActingInstance
2024-08-06 16:09:46 +08:00
}
2024-09-20 10:50:32 +08:00
object? [ ] ? parameters = new object [ md . ExplicitDatas . Length ] ;
2024-09-22 14:10:13 +08:00
var flowData = nodeModel . PreviousNode ? . FlowData ; // 当前传递的数据
2024-09-18 16:45:41 +08:00
var previousDataType = flowData ? . GetType ( ) ;
2024-08-06 16:09:46 +08:00
2024-09-20 10:50:32 +08:00
for ( int i = 0 ; i < parameters . Length ; i + + )
2024-08-06 16:09:46 +08:00
{
2024-09-20 10:50:32 +08:00
object? inputParameter ; // 存放解析的临时参数
2024-09-18 16:45:41 +08:00
var ed = md . ExplicitDatas [ i ] ; // 方法入参描述
2024-09-20 10:50:32 +08:00
2024-09-27 10:30:19 +08:00
if ( ed . IsExplicitData ) // 判断是否使用显示的输入参数
2024-08-06 16:09:46 +08:00
{
2024-09-30 22:20:02 +08:00
if ( ed . DataValue . StartsWith ( "@get" , StringComparison . OrdinalIgnoreCase ) & & flowData is not null )
2024-09-18 23:03:35 +08:00
{
// 执行表达式从上一节点获取对象
2024-09-20 10:50:32 +08:00
inputParameter = SerinExpressionEvaluator . Evaluate ( ed . DataValue , flowData , out _ ) ;
2024-09-18 23:03:35 +08:00
}
2024-09-20 10:50:32 +08:00
else
2024-09-18 23:03:35 +08:00
{
// 使用输入的固定值
2024-09-20 10:50:32 +08:00
inputParameter = ed . DataValue ;
2024-09-18 23:03:35 +08:00
}
2024-08-06 16:09:46 +08:00
}
2024-09-18 16:45:41 +08:00
else
2024-08-06 16:09:46 +08:00
{
2024-09-18 16:45:41 +08:00
inputParameter = flowData ; // 使用上一节点的对象
2024-08-06 16:09:46 +08:00
}
2024-09-12 20:32:54 +08:00
2024-09-28 23:55:19 +08:00
// 存在转换器
if ( ed . Convertor is not null )
{
if ( Enum . TryParse ( ed . ExplicitType , ed . DataValue , out var resultEnum ) )
{
var value = ed . Convertor ( resultEnum ) ;
if ( value is not null )
{
parameters [ i ] = value ;
continue ;
}
else
{
throw new InvalidOperationException ( "转换器调用失败" ) ;
}
}
}
2024-09-27 10:30:19 +08:00
if ( ed . DataType ! = ed . ExplicitType ) // 获取枚举转换器中记录的枚举
{
if ( ed . ExplicitType . IsEnum & & Enum . TryParse ( ed . ExplicitType , ed . DataValue , out var resultEnum ) ) // 获取对应的枚举项
{
var type = EnumHelper . GetBoundValue ( ed . ExplicitType , resultEnum , attr = > attr . Value ) ;
if ( type is Type enumBindType & & enumBindType is not null )
{
var value = context . Env . IOC . Instantiate ( enumBindType ) ;
if ( value is not null )
{
parameters [ i ] = value ;
continue ;
}
}
}
}
2024-09-28 23:55:19 +08:00
2024-09-27 10:30:19 +08:00
2024-09-18 16:45:41 +08:00
try
2024-08-06 16:09:46 +08:00
{
2024-09-30 22:20:02 +08:00
string? valueStr = inputParameter ? . ToString ( ) ;
2024-09-18 16:45:41 +08:00
parameters [ i ] = ed . DataType switch
2024-09-12 20:32:54 +08:00
{
2024-09-18 16:45:41 +08:00
Type t when t = = typeof ( IDynamicContext ) = > context , // 上下文
2024-09-30 22:20:02 +08:00
Type t when t . IsEnum = > Enum . Parse ( ed . DataType , ed . DataValue ) , // 需要枚举
Type t when t = = typeof ( string ) = > inputParameter ? . ToString ( ) ,
Type t when t = = typeof ( char ) & & ! string . IsNullOrEmpty ( valueStr ) = > char . Parse ( valueStr ) ,
Type t when t = = typeof ( bool ) & & ! string . IsNullOrEmpty ( valueStr ) = > inputParameter is not null & & bool . Parse ( valueStr ) ,
Type t when t = = typeof ( float ) & & ! string . IsNullOrEmpty ( valueStr ) = > float . Parse ( valueStr ) ,
Type t when t = = typeof ( decimal ) & & ! string . IsNullOrEmpty ( valueStr ) = > decimal . Parse ( valueStr ) ,
Type t when t = = typeof ( double ) & & ! string . IsNullOrEmpty ( valueStr ) = > double . Parse ( valueStr ) ,
Type t when t = = typeof ( sbyte ) & & ! string . IsNullOrEmpty ( valueStr ) = > sbyte . Parse ( valueStr ) ,
Type t when t = = typeof ( byte ) & & ! string . IsNullOrEmpty ( valueStr ) = > byte . Parse ( valueStr ) ,
Type t when t = = typeof ( short ) & & ! string . IsNullOrEmpty ( valueStr ) = > short . Parse ( valueStr ) ,
Type t when t = = typeof ( ushort ) & & ! string . IsNullOrEmpty ( valueStr ) = > ushort . Parse ( valueStr ) ,
Type t when t = = typeof ( int ) & & ! string . IsNullOrEmpty ( valueStr ) = > int . Parse ( valueStr ) ,
Type t when t = = typeof ( uint ) & & ! string . IsNullOrEmpty ( valueStr ) = > uint . Parse ( valueStr ) ,
Type t when t = = typeof ( long ) & & ! string . IsNullOrEmpty ( valueStr ) = > long . Parse ( valueStr ) ,
Type t when t = = typeof ( ulong ) & & ! string . IsNullOrEmpty ( valueStr ) = > ulong . Parse ( valueStr ) ,
Type t when t = = typeof ( nint ) & & ! string . IsNullOrEmpty ( valueStr ) = > nint . Parse ( valueStr ) ,
Type t when t = = typeof ( nuint ) & & ! string . IsNullOrEmpty ( valueStr ) = > nuint . Parse ( valueStr ) ,
//Type t when t == typeof(DateTime) => string.IsNullOrEmpty(valueStr) ? 0 : DateTime.Parse(valueStr),
2024-09-18 16:45:41 +08:00
Type t when t = = typeof ( MethodDetails ) = > md , // 节点方法描述
2024-09-22 14:10:13 +08:00
Type t when t = = typeof ( NodeModelBase ) = > nodeModel , // 节点实体类
2024-09-20 10:50:32 +08:00
2024-09-18 16:45:41 +08:00
Type t when t . IsArray = > ( inputParameter as Array ) ? . Cast < object > ( ) . ToList ( ) ,
Type t when t . IsGenericType & & t . GetGenericTypeDefinition ( ) = = typeof ( List < > ) = > inputParameter ,
_ = > inputParameter ,
2024-09-30 22:20:02 +08:00
// Type t when Nullable.GetUnderlyingType(t) != null => inputParameter is null ? null : Convert.ChangeType(inputParameter, Nullable.GetUnderlyingType(t)),
2024-09-18 16:45:41 +08:00
} ;
2024-09-30 22:20:02 +08:00
2024-08-06 16:09:46 +08:00
}
2024-09-18 16:45:41 +08:00
catch ( Exception ex ) // 节点参数类型转换异常
2024-08-06 16:09:46 +08:00
{
2024-09-30 22:20:02 +08:00
parameters [ i ] = new object ( ) ;
2024-09-18 16:45:41 +08:00
Console . WriteLine ( ex ) ;
2024-08-06 16:09:46 +08:00
}
}
return parameters ;
}
2024-09-22 14:10:13 +08:00
/// <summary>
2024-09-24 22:39:43 +08:00
/// 更新节点数据,并检查监视表达式是否生效
2024-09-22 14:10:13 +08:00
/// </summary>
/// <param name="newData"></param>
2024-09-24 22:39:43 +08:00
public static async Task RefreshFlowDataAndExpInterrupt ( IDynamicContext context , NodeModelBase nodeModel , object? newData = null )
2024-09-22 14:10:13 +08:00
{
string guid = nodeModel . Guid ;
2024-09-24 22:39:43 +08:00
if ( newData is not null )
2024-09-22 14:10:13 +08:00
{
2024-09-24 22:39:43 +08:00
await MonitorObjExpInterrupt ( context , nodeModel , newData , 0 ) ; // 首先监视对象
await MonitorObjExpInterrupt ( context , nodeModel , newData , 1 ) ; // 然后监视节点
nodeModel . FlowData = newData ; // 替换数据
}
}
2024-09-30 22:20:02 +08:00
private static async Task MonitorObjExpInterrupt ( IDynamicContext context , NodeModelBase nodeModel , object? data , int monitorType )
2024-09-24 22:39:43 +08:00
{
MonitorObjectEventArgs . ObjSourceType sourceType ;
2024-09-30 22:20:02 +08:00
string? key ;
if ( monitorType = = 0 )
2024-09-22 14:10:13 +08:00
{
2024-09-30 22:20:02 +08:00
key = data ? . GetType ( ) ? . FullName ;
2024-09-24 22:39:43 +08:00
sourceType = MonitorObjectEventArgs . ObjSourceType . IOCObj ;
}
else
{
key = nodeModel . Guid ;
sourceType = MonitorObjectEventArgs . ObjSourceType . IOCObj ;
2024-09-22 14:10:13 +08:00
}
2024-09-30 22:20:02 +08:00
if ( string . IsNullOrEmpty ( key ) )
{
return ;
}
2024-09-24 22:39:43 +08:00
if ( context . Env . CheckObjMonitorState ( key , out List < string > exps ) ) // 如果新的数据处于查看状态, 通知UI进行更新? 交给运行环境判断?
{
context . Env . MonitorObjectNotification ( nodeModel . Guid , data , sourceType ) ; // 对象处于监视状态, 通知UI更新数据显示
if ( exps . Count > 0 )
{
// 表达式环境下判断是否需要执行中断
bool isExpInterrupt = false ;
string? exp = "" ;
// 判断执行监视表达式,直到为 true 时退出
for ( int i = 0 ; i < exps . Count & & ! isExpInterrupt ; i + + )
{
exp = exps [ i ] ;
2024-09-26 21:00:17 +08:00
if ( string . IsNullOrEmpty ( exp ) ) continue ;
2024-09-24 22:39:43 +08:00
isExpInterrupt = SereinConditionParser . To ( data , exp ) ;
}
if ( isExpInterrupt ) // 触发中断
{
InterruptClass interruptClass = InterruptClass . Branch ; // 分支中断
if ( context . Env . SetNodeInterrupt ( nodeModel . Guid , interruptClass ) )
{
2024-09-26 21:00:17 +08:00
context . Env . TriggerInterrupt ( nodeModel . Guid , exp , InterruptTriggerEventArgs . InterruptTriggerType . Exp ) ;
2024-09-24 22:39:43 +08:00
var cancelType = await nodeModel . DebugSetting . GetInterruptTask ( ) ;
await Console . Out . WriteLineAsync ( $"[{data}]中断已{cancelType},开始执行后继分支" ) ;
}
}
}
2024-09-22 14:10:13 +08:00
2024-09-24 22:39:43 +08:00
}
2024-09-22 14:10:13 +08:00
}
2024-09-24 22:39:43 +08:00
2024-09-22 14:10:13 +08:00
/// <summary>
/// 释放对象
/// </summary>
public void ReleaseFlowData ( )
{
if ( typeof ( IDisposable ) . IsAssignableFrom ( FlowData ? . GetType ( ) ) & & FlowData is IDisposable disposable )
{
disposable ? . Dispose ( ) ;
}
this . FlowData = null ;
}
/// <summary>
/// 获取节点数据
/// </summary>
/// <returns></returns>
public object? GetFlowData ( )
{
2024-09-22 17:37:32 +08:00
return this . FlowData ;
2024-09-22 14:10:13 +08:00
}
2024-09-20 10:50:32 +08:00
#endregion
2024-08-06 16:09:46 +08:00
}
}