diff --git a/Library/Api/IFlowControl.cs b/Library/Api/IFlowControl.cs
index 65494fa..86510a8 100644
--- a/Library/Api/IFlowControl.cs
+++ b/Library/Api/IFlowControl.cs
@@ -40,6 +40,13 @@ namespace Serein.Library.Api
///
///
Task StartFlowAsync(string startNodeGuid);
+
+ ///
+ /// 从选定的节点开始运行
+ ///
+ ///
+ ///
+ Task StartFlowAsync(string startNodeGuid);
///
/// 结束运行
diff --git a/Library/Api/IFlowEnvironment.cs b/Library/Api/IFlowEnvironment.cs
index 12e946a..af907c8 100644
--- a/Library/Api/IFlowEnvironment.cs
+++ b/Library/Api/IFlowEnvironment.cs
@@ -1,10 +1,5 @@
-
-
-using Serein.Library.FlowNode;
-using Serein.Library.Utils;
+using Serein.Library.Utils;
using System;
-using System.Collections.Generic;
-using System.Threading;
using System.Threading.Tasks;
namespace Serein.Library.Api
diff --git a/Library/FlowNode/Env/CallNode.cs b/Library/FlowNode/Env/CallNode.cs
new file mode 100644
index 0000000..cb214dc
--- /dev/null
+++ b/Library/FlowNode/Env/CallNode.cs
@@ -0,0 +1,332 @@
+using Serein.Library.Api;
+using Serein.Library.Utils;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Serein.Library
+{
+ ///
+ /// 调用节点,代表一个流程中的调用点,可以是一个Action或一个异步函数。
+ ///
+
+ public class CallNode
+ {
+
+ private Func taskFunc;
+ private Action action;
+
+ ///
+ /// 创建一个新的调用节点,使用指定的节点Guid。
+ ///
+ ///
+ public CallNode(string nodeGuid)
+ {
+ Guid = nodeGuid;
+ Init();
+ }
+
+ ///
+ /// 创建一个新的调用节点,使用指定的节点Guid和Action。
+ ///
+ ///
+ ///
+ public CallNode(string nodeGuid, Action action)
+ {
+ Guid = nodeGuid;
+ this.action = action;
+ Init();
+ }
+
+ ///
+ /// 创建一个新的调用节点,使用指定的节点Guid和异步函数。
+ ///
+ ///
+ ///
+ public CallNode(string nodeGuid, Func func)
+ {
+ Guid = nodeGuid;
+ this.taskFunc = func;
+ Init();
+ }
+
+ ///
+ /// 初始化调用节点,设置默认的子节点和后继节点字典。
+ ///
+ private void Init()
+ {
+ //PreviousNodes = new Dictionary>();
+ SuccessorNodes = new Dictionary>();
+ foreach (ConnectionInvokeType ctType in NodeStaticConfig.ConnectionTypes)
+ {
+ //PreviousNodes[ctType] = new List();
+ SuccessorNodes[ctType] = new List();
+ }
+ }
+
+
+ private enum ActionType
+ {
+ Action,
+ Task,
+ }
+ private ActionType actionType = ActionType.Action;
+
+ ///
+ /// 设置调用节点的Action,表示该节点执行一个同步操作。
+ ///
+ ///
+ public void SetAction(Action action)
+ {
+ this.action = action;
+ actionType = ActionType.Action;
+ }
+
+ ///
+ /// 设置调用节点的异步函数,表示该节点执行一个异步操作。
+ ///
+ ///
+ public void SetAction(Func taskFunc)
+ {
+ this.taskFunc = taskFunc;
+ actionType = ActionType.Task;
+ }
+
+
+ ///
+ /// 对应的节点
+ ///
+ public string Guid { get; }
+
+#if false
+
+ ///
+ /// 不同分支的父节点(流程调用)
+ ///
+ public Dictionary> PreviousNodes { get; private set; }
+
+#endif
+ ///
+ /// 不同分支的子节点(流程调用)
+ ///
+ public Dictionary> SuccessorNodes { get; private set; }
+
+ ///
+ /// 子节点数组,分为四个分支:上游、成功、失败、错误,每个分支最多支持16个子节点。
+ ///
+ public CallNode[][] ChildNodes { get; private set; } = new CallNode[][]
+ {
+ new CallNode[MaxChildNodeCount],
+ new CallNode[MaxChildNodeCount],
+ new CallNode[MaxChildNodeCount],
+ new CallNode[MaxChildNodeCount]
+ };
+ private const int MaxChildNodeCount = 16; // 每个分支最多支持16个子节点
+
+
+ ///
+ /// 获取指定类型的子节点数量。
+ ///
+ ///
+ ///
+ public int GetCount(ConnectionInvokeType type)
+ {
+ if (type == ConnectionInvokeType.Upstream) return UpstreamNodeCount;
+ if (type == ConnectionInvokeType.IsSucceed) return IsSuccessorNodeCount;
+ if (type == ConnectionInvokeType.IsFail) return IsFailNodeCount;
+ if (type == ConnectionInvokeType.IsError) return IsErrorNodeCount;
+ return 0;
+ }
+
+ ///
+ /// 获取当前节点的子节点数量。
+ ///
+ public int UpstreamNodeCount { get; private set; } = 0;
+
+ ///
+ /// 获取当前节点的成功后继子节点数量。
+ ///
+ public int IsSuccessorNodeCount { get; private set; } = 0;
+ ///
+ /// 获取当前节点的失败后继子节点数量。
+ ///
+ public int IsFailNodeCount { get; private set; } = 0;
+ ///
+ /// 获取当前节点的错误后继子节点数量。
+ ///
+ public int IsErrorNodeCount { get; private set; } = 0;
+
+ ///
+ /// 添加一个上游子节点到当前节点。
+ ///
+ ///
+ ///
+ public CallNode AddChildNodeUpstream(CallNode callNode)
+ {
+ var connectionInvokeType = ConnectionInvokeType.Upstream;
+ ChildNodes[(int)connectionInvokeType][UpstreamNodeCount++] = callNode;
+ SuccessorNodes[connectionInvokeType].Add(callNode);
+ return this;
+ }
+
+ ///
+ /// 添加一个成功后继子节点到当前节点。
+ ///
+ ///
+ ///
+ public CallNode AddChildNodeSucceed(CallNode callNode)
+ {
+ ChildNodes[0][UpstreamNodeCount++] = callNode;
+
+ var connectionInvokeType = ConnectionInvokeType.IsSucceed;
+ ChildNodes[(int)connectionInvokeType][IsSuccessorNodeCount++] = callNode;
+ SuccessorNodes[connectionInvokeType].Add(callNode);
+
+ return this;
+ }
+ ///
+ /// 添加一个失败后继子节点到当前节点。
+ ///
+ ///
+ ///
+ public CallNode AddChildNodeFail(CallNode callNode)
+ {
+ var connectionInvokeType = ConnectionInvokeType.IsFail;
+ ChildNodes[(int)connectionInvokeType][IsFailNodeCount++] = callNode;
+ SuccessorNodes[connectionInvokeType].Add(callNode);
+
+ return this;
+ }
+
+ ///
+ /// 添加一个错误后继子节点到当前节点。
+ ///
+ ///
+ ///
+ public CallNode AddChildNodeError(CallNode callNode)
+ {
+ var connectionInvokeType = ConnectionInvokeType.IsError;
+ ChildNodes[(int)connectionInvokeType][IsErrorNodeCount++] = callNode;
+ SuccessorNodes[connectionInvokeType].Add(callNode);
+ return this;
+ }
+
+
+ ///
+ /// 调用
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task InvokeAsync(IFlowContext context, CancellationToken token)
+ {
+ if (token.IsCancellationRequested)
+ {
+ return;
+ }
+ if (actionType == ActionType.Action)
+ {
+ action.Invoke(context);
+ }
+ else if (actionType == ActionType.Task)
+ {
+ await taskFunc.Invoke(context);
+ }
+ else
+ {
+ throw new InvalidOperationException($"生成了错误的CallNode。【{Guid}】");
+ }
+ }
+
+ private static readonly ObjectPool> _stackPool = new ObjectPool>(() => new Stack());
+
+
+ ///
+ /// 开始执行
+ ///
+ ///
+ /// 流程运行
+ ///
+ public async Task StartFlowAsync(IFlowContext context, CancellationToken token)
+ {
+ var stack = _stackPool.Allocate();
+ stack.Push(this);
+ while (true)
+ {
+ if (token.IsCancellationRequested)
+ {
+ throw new Exception($"流程执行被取消,未能获取到流程结果。");
+ }
+
+ #region 执行相关
+ // 从栈中弹出一个节点作为当前节点进行处理
+ var currentNode = stack.Pop();
+ context.NextOrientation = ConnectionInvokeType.None; // 重置上下文状态
+ FlowResult flowResult = null;
+ try
+ {
+ context.NextOrientation = ConnectionInvokeType.IsSucceed; // 默认执行成功
+ await currentNode.InvokeAsync(context, token);
+ }
+ catch (Exception ex)
+ {
+ flowResult = FlowResult.Fail(currentNode.Guid, context, ex.Message);
+ context.Env.WriteLine(InfoType.ERROR, $"节点[{currentNode}]异常:" + ex);
+ context.NextOrientation = ConnectionInvokeType.IsError;
+ context.ExceptionOfRuning = ex;
+ }
+ #endregion
+
+ #region 执行完成时更新栈
+ // 首先将指定类别后继分支的所有节点逆序推入栈中
+ var nextNodes = currentNode.SuccessorNodes[context.NextOrientation];
+ for (int index = nextNodes.Count - 1; index >= 0; index--)
+ {
+ var node = nextNodes[index];
+ context.SetPreviousNode(node.Guid, currentNode.Guid);
+ stack.Push(node);
+ }
+
+ // 然后将指上游分支的所有节点逆序推入栈中
+ var upstreamNodes = currentNode.SuccessorNodes[ConnectionInvokeType.Upstream];
+ for (int index = upstreamNodes.Count - 1; index >= 0; index--)
+ {
+ var node = upstreamNodes[index];
+ context.SetPreviousNode(node.Guid, currentNode.Guid);
+ stack.Push(node);
+ }
+ #endregion
+
+ #region 执行完成后检查
+
+ if (stack.Count == 0)
+ {
+ _stackPool.Free(stack);
+ flowResult = context.GetFlowData(currentNode.Guid);
+ return flowResult; // 说明流程到了终点
+ }
+
+ if (context.RunState == RunState.Completion)
+ {
+
+ _stackPool.Free(stack);
+ context.Env.WriteLine(InfoType.INFO, $"流程执行到节点[{currentNode.Guid}]时提前结束,将返回当前执行结果。");
+ flowResult = context.GetFlowData(currentNode.Guid);
+ return flowResult; // 流程执行完成,返回结果
+ }
+
+ if (token.IsCancellationRequested)
+ {
+ _stackPool.Free(stack);
+ throw new Exception($"流程执行到节点[{currentNode.Guid}]时被取消,未能获取到流程结果。");
+ }
+
+
+ #endregion
+ }
+
+ }
+ }
+}
diff --git a/Library/FlowNode/Env/FlowCallTree.cs b/Library/FlowNode/Env/FlowCallTree.cs
new file mode 100644
index 0000000..abf9510
--- /dev/null
+++ b/Library/FlowNode/Env/FlowCallTree.cs
@@ -0,0 +1,76 @@
+using Serein.Library.Api;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Serein.Library
+{
+ ///
+ /// 流程调用树,管理所有的调用节点
+ ///
+ public class FlowCallTree : IFlowCallTree
+ {
+
+ private readonly SortedDictionary _callNodes = new SortedDictionary();
+
+ ///
+ public List StartNodes { get; set; }
+
+ ///
+ public List GlobalFlipflopNodes { get; set; }
+
+
+ ///
+ /// 索引器,允许通过字符串索引访问CallNode
+ ///
+ ///
+ ///
+ public CallNode this[string index]
+ {
+ get
+ {
+ _callNodes.TryGetValue(index, out CallNode callNode);
+ return callNode;
+ }
+ set
+ {
+ // 设置指定索引的值
+ _callNodes.Add(index, value);
+ }
+ }
+
+
+
+ ///
+ /// 添加一个调用节点到流程调用树中
+ ///
+ ///
+ ///
+ public void AddCallNode(string nodeGuid, Action action)
+ {
+ var node = new CallNode(nodeGuid, action);
+ _callNodes[nodeGuid] = node;
+ }
+
+ ///
+ /// 添加一个调用节点到流程调用树中,使用异步函数
+ ///
+ ///
+ ///
+ public void AddCallNode(string nodeGuid, Func func)
+ {
+ var node = new CallNode(nodeGuid, func);
+ _callNodes[nodeGuid] = node;
+ }
+
+ ///
+ /// 获取指定Key的CallNode,如果不存在则返回null
+ ///
+ ///
+ ///
+ public CallNode Get(string key)
+ {
+ return _callNodes.TryGetValue(key, out CallNode callNode) ? callNode : null;
+ }
+ }
+}
diff --git a/Library/FlowNode/Env/IFlowCallTree.cs b/Library/FlowNode/Env/IFlowCallTree.cs
new file mode 100644
index 0000000..03ed04e
--- /dev/null
+++ b/Library/FlowNode/Env/IFlowCallTree.cs
@@ -0,0 +1,35 @@
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Serein.Library
+{
+ ///
+ /// 流程调用树接口,提供获取CallNode的方法。
+ ///
+ public interface IFlowCallTree
+ {
+ ///
+ /// 起始节点
+ ///
+ List StartNodes { get; }
+
+ ///
+ /// 全局触发器节点列表
+ ///
+ List GlobalFlipflopNodes { get; }
+
+ ///
+ /// 初始化并启动流程调用树,异步执行。
+ ///
+ ///
+ Task InitAndStartAsync(CancellationToken token);
+
+ ///
+ /// 获取指定Key的CallNode,如果不存在则返回null。
+ ///
+ ///
+ ///
+ CallNode Get(string key);
+ }
+}
diff --git a/Library/FlowNode/Env/LightweightFlowControl.cs b/Library/FlowNode/Env/LightweightFlowControl.cs
new file mode 100644
index 0000000..e6f361b
--- /dev/null
+++ b/Library/FlowNode/Env/LightweightFlowControl.cs
@@ -0,0 +1,190 @@
+using Serein.Library.Api;
+using Serein.Library.Utils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+
+namespace Serein.Library
+{
+ ///
+ /// 轻量级流程控制器
+ ///
+ public class LightweightFlowControl : IFlowControl
+ {
+ private readonly IFlowCallTree flowCallTree;
+ private readonly IFlowEnvironment flowEnvironment;
+
+ ///
+ /// 轻量级流程上下文池,使用对象池模式来管理流程上下文的创建和回收。
+ ///
+ public static Serein.Library.Utils.ObjectPool FlowContextPool { get; set; }
+
+ ///
+ /// 单例IOC容器,用于依赖注入和服务定位。
+ ///
+ public ISereinIOC IOC => throw new NotImplementedException();
+
+ ///
+ /// 轻量级流程控制器构造函数,接受流程调用树和流程环境作为参数。
+ ///
+ ///
+ ///
+ public LightweightFlowControl(IFlowCallTree flowCallTree, IFlowEnvironment flowEnvironment)
+ {
+ this.flowCallTree = flowCallTree;
+ this.flowEnvironment = flowEnvironment;
+ ((LightweightFlowEnvironment)flowEnvironment).FlowControl = this;
+
+ FlowContextPool = new Utils.ObjectPool(() =>
+ {
+ return new FlowContext(flowEnvironment);
+ });
+ }
+
+
+
+ ///
+ public Task