mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-22 00:56:34 +08:00
优化了流程的进行
This commit is contained in:
@@ -1,10 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
using Serein.Library.Api;
|
||||
using Serein.Library.Api;
|
||||
using Serein.Library.Entity;
|
||||
using Serein.Library.Enums;
|
||||
using Serein.NodeFlow.Model;
|
||||
using Serein.NodeFlow.Tool.SerinExpression;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Serein.NodeFlow.Base
|
||||
{
|
||||
@@ -65,12 +61,14 @@ namespace Serein.NodeFlow.Base
|
||||
/// <summary>
|
||||
/// 不同分支的子节点
|
||||
/// </summary>
|
||||
public Dictionary<ConnectionType,List<NodeModelBase>> SuccessorNodes { get; }
|
||||
public Dictionary<ConnectionType,List<NodeModelBase>> SuccessorNodes { get; }
|
||||
|
||||
public ConnectionType NextOrientation { get; set; } = ConnectionType.None;
|
||||
|
||||
/// <summary>
|
||||
/// 当前执行状态(进入真分支还是假分支,异常分支在异常中确定)
|
||||
/// </summary>
|
||||
public FlowStateType FlowState { get; set; } = FlowStateType.None;
|
||||
// public FlowStateType FlowState { get; set; } = FlowStateType.Cancel;
|
||||
|
||||
/// <summary>
|
||||
/// 运行时的异常信息(仅在 FlowState 为 Error 时存在对应值)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Serein.Library.Api;
|
||||
using Serein.Library.Entity;
|
||||
using Serein.Library.Enums;
|
||||
using Serein.Library.Ex;
|
||||
using Serein.NodeFlow.Tool.SerinExpression;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -92,14 +93,13 @@ namespace Serein.NodeFlow.Base
|
||||
currentNode.FlowData = currentNode.Execute(context);
|
||||
}
|
||||
|
||||
ConnectionType connection = currentNode.FlowState switch
|
||||
if(currentNode.NextOrientation == ConnectionType.None)
|
||||
{
|
||||
FlowStateType.Succeed => ConnectionType.IsSucceed,
|
||||
FlowStateType.Fail => ConnectionType.IsFail,
|
||||
FlowStateType.Error => ConnectionType.IsError,
|
||||
_ => throw new Exception("非预期的枚举值")
|
||||
};
|
||||
var nextNodes = currentNode.SuccessorNodes[connection];
|
||||
// 不再执行
|
||||
break;
|
||||
}
|
||||
|
||||
var nextNodes = currentNode.SuccessorNodes[currentNode.NextOrientation];
|
||||
|
||||
// 将下一个节点集合中的所有节点逆序推入栈中
|
||||
for (int i = nextNodes.Count - 1; i >= 0; i--)
|
||||
@@ -148,12 +148,12 @@ namespace Serein.NodeFlow.Base
|
||||
result = func?.Invoke(md.ActingInstance, parameters);
|
||||
}
|
||||
}
|
||||
FlowState = FlowStateType.Succeed;
|
||||
NextOrientation = ConnectionType.IsSucceed;
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
FlowState = FlowStateType.Error;
|
||||
NextOrientation = ConnectionType.IsError;
|
||||
RuningException = ex;
|
||||
}
|
||||
|
||||
@@ -184,23 +184,16 @@ namespace Serein.NodeFlow.Base
|
||||
object?[]? parameters = GetParameters(context, MethodDetails);
|
||||
flipflopContext = await ((Func<object, object[], Task<IFlipflopContext>>)md.MethodDelegate).Invoke(MethodDetails.ActingInstance, parameters);
|
||||
}
|
||||
|
||||
if (flipflopContext != null)
|
||||
if (flipflopContext == null)
|
||||
{
|
||||
FlowState = flipflopContext.State;
|
||||
if (flipflopContext.State == FlowStateType.Succeed)
|
||||
{
|
||||
result = flipflopContext.Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
throw new FlipflopException("没有返回上下文");
|
||||
}
|
||||
NextOrientation = flipflopContext.State.ToContentType();
|
||||
result = flipflopContext.Data;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
FlowState = FlowStateType.Error;
|
||||
NextOrientation = ConnectionType.IsError;
|
||||
RuningException = ex;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ using Serein.NodeFlow.Base;
|
||||
using Serein.NodeFlow.Model;
|
||||
using Serein.NodeFlow.Tool;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Mime;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Xml.Linq;
|
||||
@@ -618,6 +619,18 @@ namespace Serein.NodeFlow
|
||||
Path = assembly.Location,
|
||||
};
|
||||
}
|
||||
|
||||
public static ConnectionType ToContentType(this FlipflopStateType flowStateType)
|
||||
{
|
||||
return flowStateType switch
|
||||
{
|
||||
FlipflopStateType.Succeed => ConnectionType.IsSucceed,
|
||||
FlipflopStateType.Fail => ConnectionType.IsFail,
|
||||
FlipflopStateType.Error => ConnectionType.IsError,
|
||||
FlipflopStateType.Cancel => ConnectionType.None,
|
||||
_ => throw new NotImplementedException("未定义的流程状态")
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -159,11 +159,14 @@ namespace Serein.NodeFlow
|
||||
|
||||
IFlipflopContext flipflopContext = await func.Invoke(md.ActingInstance, parameters);
|
||||
|
||||
if (flipflopContext.State == FlowStateType.Succeed)
|
||||
ConnectionType connection = flipflopContext.State.ToContentType();
|
||||
|
||||
if (connection != ConnectionType.None)
|
||||
{
|
||||
singleFlipFlopNode.FlowState = FlowStateType.Succeed;
|
||||
singleFlipFlopNode.NextOrientation = connection;
|
||||
singleFlipFlopNode.FlowData = flipflopContext.Data;
|
||||
var tasks = singleFlipFlopNode.SuccessorNodes[ConnectionType.IsSucceed].Select(nextNode =>
|
||||
|
||||
var tasks = singleFlipFlopNode.SuccessorNodes[connection].Select(nextNode =>
|
||||
{
|
||||
var context = new DynamicContext(SereinIoc,flowEnvironment);
|
||||
nextNode.PreviousNode = singleFlipFlopNode;
|
||||
|
||||
@@ -26,50 +26,38 @@ namespace Serein.NodeFlow.Model
|
||||
/// <returns></returns>
|
||||
public override object? Execute(IDynamicContext context)
|
||||
{
|
||||
// bool allTrue = ConditionNodes.All(condition => Judge(context,condition.MethodDetails));
|
||||
// bool IsAllTrue = true; // 初始化为 true
|
||||
FlowState = FlowStateType.Succeed;
|
||||
// NextOrientation = ConnectionType.IsSucceed;
|
||||
|
||||
// 条件区域中遍历每个条件节点
|
||||
foreach (SingleConditionNode? node in ConditionNodes)
|
||||
{
|
||||
var state = Judge(context, node);
|
||||
if (state == FlowStateType.Fail || FlowStateType.Fail == FlowStateType.Error)
|
||||
NextOrientation = state; // 每次判读完成后,设置区域后继方向为判断结果
|
||||
if (state != ConnectionType.IsSucceed)
|
||||
{
|
||||
FlowState = state;
|
||||
break;// 一旦发现条件为假,立即退出循环
|
||||
// 如果条件不通过,立刻推出循环
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return PreviousNode?.FlowData;
|
||||
//if (IsAllTrue)
|
||||
//{
|
||||
// foreach (var nextNode in TrueBranchNextNodes)
|
||||
// {
|
||||
// nextNode.ExecuteStack(context);
|
||||
// }
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// foreach (var nextNode in FalseBranchNextNodes)
|
||||
// {
|
||||
// nextNode.ExecuteStack(context);
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private FlowStateType Judge(IDynamicContext context, SingleConditionNode node)
|
||||
private ConnectionType Judge(IDynamicContext context, SingleConditionNode node)
|
||||
{
|
||||
try
|
||||
{
|
||||
node.Execute(context);
|
||||
return node.FlowState;
|
||||
return node.NextOrientation;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
return FlowStateType.Error;
|
||||
NextOrientation = ConnectionType.IsError;
|
||||
RuningException = ex;
|
||||
return ConnectionType.IsError;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,15 +43,15 @@ namespace Serein.NodeFlow.Model
|
||||
try
|
||||
{
|
||||
var isPass = SerinConditionParser.To(result, Expression);
|
||||
FlowState = isPass ? FlowStateType.Succeed : FlowStateType.Fail;
|
||||
NextOrientation = isPass ? ConnectionType.IsSucceed : ConnectionType.IsFail;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
FlowState = FlowStateType.Error;
|
||||
NextOrientation = ConnectionType.IsError;
|
||||
RuningException = ex;
|
||||
}
|
||||
|
||||
Console.WriteLine($"{result} {Expression} -> " + FlowState);
|
||||
Console.WriteLine($"{result} {Expression} -> " + NextOrientation);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using Serein.Library.Entity;
|
||||
using Serein.Library.Enums;
|
||||
using Serein.NodeFlow.Base;
|
||||
using Serein.NodeFlow.Tool.SerinExpression;
|
||||
using System.Text;
|
||||
|
||||
namespace Serein.NodeFlow.Model
|
||||
{
|
||||
@@ -21,16 +22,27 @@ namespace Serein.NodeFlow.Model
|
||||
{
|
||||
var data = PreviousNode?.FlowData;
|
||||
|
||||
var newData = SerinExpressionEvaluator.Evaluate(Expression, data, out bool isChange);
|
||||
try
|
||||
{
|
||||
var newData = SerinExpressionEvaluator.Evaluate(Expression, data, out bool isChange);
|
||||
Console.WriteLine(newData);
|
||||
object? result = null;
|
||||
if (isChange)
|
||||
{
|
||||
result = newData;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = PreviousNode?.FlowData;
|
||||
}
|
||||
|
||||
FlowState = FlowStateType.Succeed;
|
||||
Console.WriteLine(newData);
|
||||
if (isChange)
|
||||
{
|
||||
return newData;
|
||||
NextOrientation = ConnectionType.IsSucceed;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
NextOrientation = ConnectionType.IsError;
|
||||
RuningException = ex;
|
||||
return PreviousNode?.FlowData;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Serein.Library.Api;
|
||||
using Serein.Library.Entity;
|
||||
using Serein.Library.Ex;
|
||||
using Serein.NodeFlow.Base;
|
||||
|
||||
namespace Serein.NodeFlow.Model
|
||||
@@ -7,9 +8,11 @@ namespace Serein.NodeFlow.Model
|
||||
|
||||
public class SingleFlipflopNode : NodeModelBase
|
||||
{
|
||||
public override object Execute(IDynamicContext context)
|
||||
public override object? Execute(IDynamicContext context)
|
||||
{
|
||||
throw new NotImplementedException("无法以非await/async的形式调用触发器");
|
||||
NextOrientation = Library.Enums.ConnectionType.IsError;
|
||||
RuningException = new FlipflopException ("无法以非await/async的形式调用触发器");
|
||||
return null;
|
||||
}
|
||||
|
||||
public override Parameterdata[] GetParameterdatas()
|
||||
|
||||
@@ -67,6 +67,10 @@ public static class MethodDetailsHelperTmp
|
||||
|
||||
var methodName = method.Name;
|
||||
var attribute = method.GetCustomAttribute<NodeActionAttribute>();
|
||||
if(attribute is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var explicitDataOfParameters = GetExplicitDataOfParameters(method.GetParameters());
|
||||
// 生成委托
|
||||
var methodDelegate = GenerateMethodDelegate(type, // 方法所在的对象类型
|
||||
@@ -74,6 +78,16 @@ public static class MethodDetailsHelperTmp
|
||||
method.GetParameters(),// 方法参数
|
||||
method.ReturnType);// 返回值
|
||||
|
||||
Type returnType;
|
||||
if (attribute?.MethodDynamicType == Library.Enums.NodeType.Flipflop)
|
||||
{
|
||||
// 触发器节点
|
||||
returnType = attribute.ReturnType;
|
||||
}
|
||||
else
|
||||
{
|
||||
returnType = method.ReturnType;
|
||||
}
|
||||
|
||||
var dllTypeName = $"{assemblyName}.{type.Name}";
|
||||
// object instance = Activator.CreateInstance(type);
|
||||
@@ -89,7 +103,7 @@ public static class MethodDetailsHelperTmp
|
||||
MethodLockName = attribute.LockName,
|
||||
MethodTips = attribute.MethodTips,
|
||||
ExplicitDatas = explicitDataOfParameters,
|
||||
ReturnType = method.ReturnType,
|
||||
ReturnType = returnType,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user