mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-04-04 23:36:35 +08:00
修改了logwindows输出,避免高频输出时卡死。修改了流程运行上下文,使节点具备终止分支运行的能力。
This commit is contained in:
@@ -94,6 +94,36 @@ namespace Serein.NodeFlow.Base
|
||||
|
||||
#region 节点方法的执行
|
||||
|
||||
/// <summary>
|
||||
/// 是否应该退出执行
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="flowCts"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsBradk(IDynamicContext context, CancellationTokenSource? flowCts)
|
||||
{
|
||||
// 上下文不再执行
|
||||
if(context.RunState == RunState.Completion)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 不存在全局触发器时,流程运行状态被设置为完成,退出执行,用于打断无限循环分支。
|
||||
if (flowCts is null && context.Env.FlowState == RunState.Completion)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// 如果存在全局触发器,且触发器的执行任务已经被取消时,退出执行。
|
||||
if (flowCts is not null)
|
||||
{
|
||||
if (flowCts.IsCancellationRequested)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 开始执行
|
||||
/// </summary>
|
||||
@@ -107,24 +137,18 @@ namespace Serein.NodeFlow.Base
|
||||
bool hasFlipflow = flowCts != null;
|
||||
while (stack.Count > 0) // 循环中直到栈为空才会退出循环
|
||||
{
|
||||
if (hasFlipflow && flowCts is not null)
|
||||
{
|
||||
if (flowCts.IsCancellationRequested)
|
||||
break;
|
||||
}
|
||||
await Task.Delay(0);
|
||||
// 从栈中弹出一个节点作为当前节点进行处理
|
||||
var currentNode = stack.Pop();
|
||||
|
||||
#region 执行相关
|
||||
|
||||
// 筛选出上游分支
|
||||
var upstreamNodes = currentNode.SuccessorNodes[ConnectionType.Upstream].Where(
|
||||
node => node.DebugSetting.IsEnable
|
||||
).ToArray();
|
||||
// 执行上游分支
|
||||
foreach (var upstreamNode in upstreamNodes)
|
||||
var upstreamNodes = currentNode.SuccessorNodes[ConnectionType.Upstream].ToArray();
|
||||
for (int index = 0; index < upstreamNodes.Length; index++)
|
||||
{
|
||||
if (upstreamNode.DebugSetting.IsEnable)
|
||||
NodeModelBase? upstreamNode = upstreamNodes[index];
|
||||
if (upstreamNode is not null && upstreamNode.DebugSetting.IsEnable)
|
||||
{
|
||||
if (upstreamNode.DebugSetting.InterruptClass != InterruptClass.None) // 执行触发前
|
||||
{
|
||||
@@ -142,14 +166,11 @@ namespace Serein.NodeFlow.Base
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsBradk(context, flowCts)) break; // 退出执行
|
||||
// 上游分支执行完成,才执行当前节点
|
||||
object? newFlowData = await currentNode.ExecutingAsync(context);
|
||||
if (hasFlipflow && (flowCts is null || flowCts.IsCancellationRequested || currentNode.NextOrientation == ConnectionType.None))
|
||||
{
|
||||
// 不再执行
|
||||
break;
|
||||
}
|
||||
if (IsBradk(context, flowCts)) break; // 退出执行
|
||||
|
||||
await RefreshFlowDataAndExpInterrupt(context, currentNode, newFlowData); // 执行当前节点后刷新数据
|
||||
#endregion
|
||||
|
||||
@@ -169,6 +190,7 @@ namespace Serein.NodeFlow.Base
|
||||
stack.Push(nextNodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
@@ -342,7 +364,10 @@ namespace Serein.NodeFlow.Base
|
||||
/// <summary>
|
||||
/// 更新节点数据,并检查监视表达式是否生效
|
||||
/// </summary>
|
||||
/// <param name="newData"></param>
|
||||
/// <param name="context">上下文</param>
|
||||
/// <param name="nodeModel">节点Moel</param>
|
||||
/// <param name="newData">新的数据</param>
|
||||
/// <returns></returns>
|
||||
public static async Task RefreshFlowDataAndExpInterrupt(IDynamicContext context, NodeModelBase nodeModel, object? newData = null)
|
||||
{
|
||||
string guid = nodeModel.Guid;
|
||||
@@ -351,6 +376,7 @@ namespace Serein.NodeFlow.Base
|
||||
await MonitorObjExpInterrupt(context, nodeModel, newData, 0); // 首先监视对象
|
||||
await MonitorObjExpInterrupt(context, nodeModel, newData, 1); // 然后监视节点
|
||||
nodeModel.FlowData = newData; // 替换数据
|
||||
context.AddOrUpdate(guid, nodeModel); // 上下文中更新数据
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -150,6 +150,14 @@ namespace Serein.NodeFlow
|
||||
#endregion
|
||||
|
||||
#region 属性
|
||||
/// <summary>
|
||||
/// 如果没有全局触发器,且没有循环分支,流程执行完成后自动为 Completion 。
|
||||
/// </summary>
|
||||
public RunState FlowState { get; set; } = RunState.NoStart;
|
||||
/// <summary>
|
||||
/// 如果全局触发器还在运行,则为 Running 。
|
||||
/// </summary>
|
||||
public RunState FlipFlopState { get; set; } = RunState.NoStart;
|
||||
|
||||
/// <summary>
|
||||
/// 环境名称
|
||||
@@ -166,8 +174,18 @@ namespace Serein.NodeFlow
|
||||
/// </summary>
|
||||
public ChannelFlowInterrupt ChannelFlowInterrupt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para>单例模式IOC容器,内部维护了一个实例字典,默认使用类型的FullName作为Key,如果以“接口-实现类”的方式注册,那么将使用接口类型的FullName作为Key。</para>
|
||||
/// <para>当某个类型注册绑定成功后,将不会因为其它地方尝试注册相同类型的行为导致类型被重新创建。</para>
|
||||
/// </summary>
|
||||
public ISereinIOC IOC { get => this; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 描述所有DLL中NodeAction特性的方法的原始副本
|
||||
/// </summary>
|
||||
public Dictionary<NodeLibrary, List<MethodDetails>> MethodDetailss { get; } = [];
|
||||
|
||||
#endregion
|
||||
|
||||
#region 私有变量
|
||||
@@ -185,10 +203,7 @@ namespace Serein.NodeFlow
|
||||
/// </summary>
|
||||
public List<NodeLibrary> NodeLibrarys { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 描述所有DLL中NodeAction特性的方法的原始副本
|
||||
/// </summary>
|
||||
public Dictionary<NodeLibrary, List<MethodDetails>> MethodDetailss { get; } = [];
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 环境加载的节点集合
|
||||
@@ -283,7 +298,7 @@ namespace Serein.NodeFlow
|
||||
|
||||
await flowStarter.RunAsync(this, nodes, AutoRegisterTypes, initMethods, loadMethods, exitMethods);
|
||||
|
||||
if (flowStarter?.FlipFlopState == RunState.NoStart)
|
||||
if (this.FlipFlopState == RunState.Completion)
|
||||
{
|
||||
this.Exit(); // 未运行触发器时,才会调用结束方法
|
||||
}
|
||||
@@ -296,7 +311,7 @@ namespace Serein.NodeFlow
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (flowStarter.FlowState == RunState.Running || flowStarter.FlipFlopState == RunState.Running)
|
||||
if (this.FlowState == RunState.Running || this.FlipFlopState == RunState.Running)
|
||||
{
|
||||
NodeModelBase? nodeModel = GuidToModel(startNodeGuid);
|
||||
if (nodeModel is null || nodeModel is SingleFlipflopNode)
|
||||
@@ -580,7 +595,7 @@ namespace Serein.NodeFlow
|
||||
/// </summary>
|
||||
/// <param name="nodeGuid"></param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public void RemoteNode(string nodeGuid)
|
||||
public void RemoveNode(string nodeGuid)
|
||||
{
|
||||
var remoteNode = GuidToModel(nodeGuid);
|
||||
if (remoteNode is null) return;
|
||||
@@ -653,7 +668,7 @@ namespace Serein.NodeFlow
|
||||
/// <param name="toNodeGuid">目标节点Guid</param>
|
||||
/// <param name="connectionType">连接关系</param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public void RemoteConnect(string fromNodeGuid, string toNodeGuid, ConnectionType connectionType)
|
||||
public void RemoveConnect(string fromNodeGuid, string toNodeGuid, ConnectionType connectionType)
|
||||
{
|
||||
// 获取起始节点与目标节点
|
||||
var fromNode = GuidToModel(fromNodeGuid);
|
||||
@@ -853,7 +868,7 @@ namespace Serein.NodeFlow
|
||||
if (nodeModel is null) return;
|
||||
if (flowStarter is not null && nodeModel is SingleFlipflopNode flipflopNode) // 子节点为触发器
|
||||
{
|
||||
if (flowStarter.FlowState != RunState.Completion
|
||||
if (this.FlowState != RunState.Completion
|
||||
&& flipflopNode.NotExitPreviousNode()) // 正在运行,且该触发器没有上游节点
|
||||
{
|
||||
_ = flowStarter.RunGlobalFlipflopAsync(this, flipflopNode);// 被父节点移除连接关系的子节点若为触发器,且无上级节点,则当前流程正在运行,则加载到运行环境中
|
||||
|
||||
@@ -17,48 +17,28 @@ using static Serein.Library.Utils.ChannelFlowInterrupt;
|
||||
namespace Serein.NodeFlow
|
||||
{
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 流程启动器
|
||||
/// </summary>
|
||||
/// <param name="serviceContainer"></param>
|
||||
/// <param name="methodDetails"></param>
|
||||
public class FlowStarter
|
||||
{
|
||||
/// <summary>
|
||||
/// 全局触发器CTS
|
||||
/// </summary>
|
||||
public const string FlipFlopCtsName = "<>.FlowFlipFlopCts";
|
||||
/// <summary>
|
||||
/// 流程运行CTS
|
||||
/// </summary>
|
||||
public const string FlowRungCtsName = "<>.FlowRungCtsName";
|
||||
|
||||
public FlowStarter()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 流程运行状态
|
||||
/// </summary>
|
||||
public enum RunState
|
||||
{
|
||||
/// <summary>
|
||||
/// 等待开始
|
||||
/// </summary>
|
||||
NoStart,
|
||||
/// <summary>
|
||||
/// 正在运行
|
||||
/// </summary>
|
||||
Running,
|
||||
/// <summary>
|
||||
/// 运行完成
|
||||
/// </summary>
|
||||
Completion,
|
||||
}
|
||||
/// <summary>
|
||||
/// 起点流程运行状态
|
||||
/// </summary>
|
||||
public RunState FlowState { get; private set; } = RunState.NoStart;
|
||||
/// <summary>
|
||||
/// 全局触发器运行状态
|
||||
/// </summary>
|
||||
public RunState FlipFlopState { get; private set; } = RunState.NoStart;
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 控制触发器
|
||||
@@ -115,11 +95,11 @@ namespace Serein.NodeFlow
|
||||
List<MethodDetails> loadingMethods,
|
||||
List<MethodDetails> exitMethods)
|
||||
{
|
||||
|
||||
FlowState = RunState.Running; // 开始运行
|
||||
|
||||
env.FlowState = RunState.Running; // 开始运行
|
||||
NodeModelBase? startNode = nodes.FirstOrDefault(node => node.IsStart);
|
||||
if (startNode is null) {
|
||||
FlowState = RunState.Completion; // 不存在起点,退出流程
|
||||
env.FlowState = RunState.Completion; // 不存在起点,退出流程
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -281,8 +261,8 @@ namespace Serein.NodeFlow
|
||||
_flipFlopCts?.Cancel();
|
||||
_flipFlopCts?.Dispose();
|
||||
}
|
||||
FlowState = RunState.Completion;
|
||||
FlipFlopState = RunState.Completion;
|
||||
env.FlowState = RunState.Completion;
|
||||
env.FlipFlopState = RunState.Completion;
|
||||
|
||||
};
|
||||
#endregion
|
||||
@@ -294,7 +274,7 @@ namespace Serein.NodeFlow
|
||||
|
||||
if (flipflopNodes.Count > 0)
|
||||
{
|
||||
FlipFlopState = RunState.Running;
|
||||
env.FlipFlopState = RunState.Running;
|
||||
// 如果存在需要启动的触发器,则开始启动
|
||||
_flipFlopCts = new CancellationTokenSource();
|
||||
env.IOC.CustomRegisterInstance(FlipFlopCtsName, _flipFlopCts,false);
|
||||
@@ -308,7 +288,7 @@ namespace Serein.NodeFlow
|
||||
}
|
||||
await startNode.StartFlowAsync(Context); // 开始运行时从起始节点开始运行
|
||||
// 等待结束
|
||||
if(FlipFlopState == RunState.Running && _flipFlopCts is not null)
|
||||
if(env.FlipFlopState == RunState.Running && _flipFlopCts is not null)
|
||||
{
|
||||
while (!_flipFlopCts.IsCancellationRequested)
|
||||
{
|
||||
@@ -322,7 +302,7 @@ namespace Serein.NodeFlow
|
||||
}
|
||||
finally
|
||||
{
|
||||
FlowState = RunState.Completion;
|
||||
env.FlowState = RunState.Completion;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Serein.NodeFlow.Model
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Task.FromResult( PreviousNode?.GetFlowData());
|
||||
return Task.FromResult(PreviousNode?.GetFlowData()); // 条件区域透传上一节点的数据
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -32,35 +32,33 @@ namespace Serein.NodeFlow.Model
|
||||
public override Task<object?> ExecutingAsync(IDynamicContext context)
|
||||
{
|
||||
// 接收上一节点参数or自定义参数内容
|
||||
object? result;
|
||||
if (IsCustomData)
|
||||
object? parameter;
|
||||
object? result = PreviousNode?.GetFlowData(); // 条件节点透传上一节点的数据
|
||||
if (IsCustomData) // 是否使用自定义参数
|
||||
{
|
||||
result = CustomData;
|
||||
// 表达式获取上一节点数据
|
||||
var getObjExp = CustomData?.ToString();
|
||||
if (!string.IsNullOrEmpty(getObjExp) && getObjExp.Length >= 4 && getObjExp[..4].Equals("@get", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
parameter = result;
|
||||
if (parameter is not null)
|
||||
{
|
||||
parameter = SerinExpressionEvaluator.Evaluate(getObjExp, parameter, out _);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
parameter = CustomData;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = PreviousNode?.GetFlowData();
|
||||
parameter = result;
|
||||
}
|
||||
try
|
||||
{
|
||||
var getObjExp = CustomData?.ToString();
|
||||
|
||||
if (IsCustomData && !string.IsNullOrEmpty(getObjExp) && getObjExp.Length >= 4)
|
||||
{
|
||||
|
||||
var ExpOpOption = getObjExp[..4];
|
||||
if(ExpOpOption.ToLower() == "@get")
|
||||
{
|
||||
result = PreviousNode?.GetFlowData();
|
||||
if (result is not null)
|
||||
{
|
||||
result = SerinExpressionEvaluator.Evaluate(getObjExp, result, out _);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
var isPass = SereinConditionParser.To(result, Expression);
|
||||
|
||||
var isPass = SereinConditionParser.To(parameter, Expression);
|
||||
NextOrientation = isPass ? ConnectionType.IsSucceed : ConnectionType.IsFail;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Serein.NodeFlow.Model
|
||||
//public override async Task<object?> Executing(IDynamicContext context)
|
||||
public override Task<object?> ExecutingAsync(IDynamicContext context)
|
||||
{
|
||||
var data = PreviousNode?.GetFlowData();
|
||||
var data = PreviousNode?.GetFlowData(); // 表达式节点使用上一节点数据
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -1,189 +0,0 @@
|
||||
using Serein.Library.Api;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.NodeFlow
|
||||
{
|
||||
/* /// <summary>
|
||||
/// 输出文件
|
||||
/// </summary>
|
||||
public class SereinOutputFileData
|
||||
{
|
||||
/// <summary>
|
||||
/// 基础
|
||||
/// </summary>
|
||||
|
||||
public Basic basic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 依赖的DLL
|
||||
/// </summary>
|
||||
|
||||
public Library[] library { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起始节点GUID
|
||||
/// </summary>
|
||||
|
||||
public string startNode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 节点信息集合
|
||||
/// </summary>
|
||||
|
||||
public NodeInfo[] nodes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 区域集合
|
||||
/// </summary>
|
||||
|
||||
public Region[] regions { get; set; }
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 基础
|
||||
/// </summary>
|
||||
public class Basic
|
||||
{
|
||||
/// <summary>
|
||||
/// 画布
|
||||
/// </summary>
|
||||
|
||||
public FlowCanvas canvas { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 版本
|
||||
/// </summary>
|
||||
|
||||
public string versions { get; set; }
|
||||
|
||||
// 预览位置
|
||||
|
||||
// 缩放比例
|
||||
}
|
||||
/// <summary>
|
||||
/// 画布
|
||||
/// </summary>
|
||||
public class FlowCanvas
|
||||
{
|
||||
/// <summary>
|
||||
/// 宽度
|
||||
/// </summary>
|
||||
public float width { get; set; }
|
||||
/// <summary>
|
||||
/// 高度
|
||||
/// </summary>
|
||||
public float lenght { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DLL
|
||||
/// </summary>
|
||||
public class Library
|
||||
{
|
||||
/// <summary>
|
||||
/// DLL名称
|
||||
/// </summary>
|
||||
|
||||
public string name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 路径
|
||||
/// </summary>
|
||||
|
||||
public string path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提示
|
||||
/// </summary>
|
||||
|
||||
public string tips { get; set; }
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 节点
|
||||
/// </summary>
|
||||
public class NodeInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// GUID
|
||||
/// </summary>
|
||||
|
||||
public string guid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
|
||||
public string name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 显示标签
|
||||
/// </summary>
|
||||
|
||||
public string label { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型
|
||||
/// </summary>
|
||||
|
||||
public string type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 于画布中的位置
|
||||
/// </summary>
|
||||
|
||||
public Position position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 真分支节点GUID
|
||||
/// </summary>
|
||||
|
||||
public string[] trueNodes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 假分支节点
|
||||
/// </summary>
|
||||
|
||||
public string[] falseNodes { get; set; }
|
||||
public string[] upstreamNodes { get; set; }
|
||||
|
||||
|
||||
|
||||
public Parameterdata[] parameterData { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class Parameterdata
|
||||
{
|
||||
public bool state { get; set; }
|
||||
public string value { get; set; }
|
||||
public string expression { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 节点于画布中的位置
|
||||
/// </summary>
|
||||
public class Position
|
||||
{
|
||||
public float x { get; set; }
|
||||
public float y { get; set; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 区域
|
||||
/// </summary>
|
||||
public class Region
|
||||
{
|
||||
public string guid { get; set; }
|
||||
public NodeInfo[] childNodes { get; set; }
|
||||
|
||||
}*/
|
||||
}
|
||||
@@ -530,13 +530,9 @@ namespace Serein.NodeFlow.Tool.SereinExpression
|
||||
{
|
||||
">" => ValueTypeConditionResolver<T>.Operator.GreaterThan,
|
||||
"<" => ValueTypeConditionResolver<T>.Operator.LessThan,
|
||||
"=" => ValueTypeConditionResolver<T>.Operator.Equal,
|
||||
"==" => ValueTypeConditionResolver<T>.Operator.Equal,
|
||||
">=" => ValueTypeConditionResolver<T>.Operator.GreaterThanOrEqual,
|
||||
"≥" => ValueTypeConditionResolver<T>.Operator.GreaterThanOrEqual,
|
||||
"<=" => ValueTypeConditionResolver<T>.Operator.LessThanOrEqual,
|
||||
"≤" => ValueTypeConditionResolver<T>.Operator.LessThanOrEqual,
|
||||
"equals" => ValueTypeConditionResolver<T>.Operator.Equal,
|
||||
">=" or "≥" => ValueTypeConditionResolver<T>.Operator.GreaterThanOrEqual,
|
||||
"<=" or "≤" => ValueTypeConditionResolver<T>.Operator.LessThanOrEqual,
|
||||
"in" => ValueTypeConditionResolver<T>.Operator.InRange,
|
||||
"!in" => ValueTypeConditionResolver<T>.Operator.OutOfRange,
|
||||
_ => throw new ArgumentException($"Invalid operator {operatorStr} for value type.")
|
||||
@@ -553,10 +549,7 @@ namespace Serein.NodeFlow.Tool.SereinExpression
|
||||
{
|
||||
return operatorStr switch
|
||||
{
|
||||
"is" => BoolConditionResolver.Operator.Is,
|
||||
"==" => BoolConditionResolver.Operator.Is,
|
||||
"equals" => BoolConditionResolver.Operator.Is,
|
||||
//"isFalse" => BoolConditionNode.Operator.IsFalse,
|
||||
"is" or "==" or "equals" => BoolConditionResolver.Operator.Is,
|
||||
_ => throw new ArgumentException($"Invalid operator {operatorStr} for bool type.")
|
||||
};
|
||||
}
|
||||
@@ -569,21 +562,16 @@ namespace Serein.NodeFlow.Tool.SereinExpression
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
private static StringConditionResolver.Operator ParseStringOperator(string operatorStr)
|
||||
{
|
||||
return operatorStr switch
|
||||
return operatorStr.ToLower() switch
|
||||
{
|
||||
"c" => StringConditionResolver.Operator.Contains,
|
||||
"nc" => StringConditionResolver.Operator.DoesNotContain,
|
||||
"sw" => StringConditionResolver.Operator.StartsWith,
|
||||
"ew" => StringConditionResolver.Operator.EndsWith,
|
||||
"c" or "contains" => StringConditionResolver.Operator.Contains,
|
||||
"nc" or "doesnotcontain" => StringConditionResolver.Operator.DoesNotContain,
|
||||
"sw" or "startswith" => StringConditionResolver.Operator.StartsWith,
|
||||
"ew" or "endswith" => StringConditionResolver.Operator.EndsWith,
|
||||
|
||||
"==" or "equals" => StringConditionResolver.Operator.Equal,
|
||||
"!=" or "notequals" => StringConditionResolver.Operator.NotEqual,
|
||||
|
||||
"contains" => StringConditionResolver.Operator.Contains,
|
||||
"doesNotContain" => StringConditionResolver.Operator.DoesNotContain,
|
||||
"equals" => StringConditionResolver.Operator.Equal,
|
||||
"==" => StringConditionResolver.Operator.Equal,
|
||||
"notEquals" => StringConditionResolver.Operator.NotEqual,
|
||||
"!=" => StringConditionResolver.Operator.NotEqual,
|
||||
"startsWith" => StringConditionResolver.Operator.StartsWith,
|
||||
"endsWith" => StringConditionResolver.Operator.EndsWith,
|
||||
_ => throw new ArgumentException($"Invalid operator {operatorStr} for string type.")
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user