diff --git a/Library/Api/IFlowEnvironment.cs b/Library/Api/IFlowEnvironment.cs
index 75e6bb6..6debb1e 100644
--- a/Library/Api/IFlowEnvironment.cs
+++ b/Library/Api/IFlowEnvironment.cs
@@ -1097,16 +1097,19 @@ namespace Serein.Library.Api
void SetUIContextOperation(UIContextOperation uiContextOperation);
///
- /// 开始运行
+ /// 开始运行流程
///
- Task StartFlowAsync();
+ /// 需要运行的流程Guid
+ ///
+ Task StartFlowAsync(string[] canvasGuids);
+
///
/// 从选定的节点开始运行
///
///
///
- Task StartAsyncInSelectNode(string startNodeGuid);
+ Task StartFlowFromSelectNodeAsync(string startNodeGuid);
///
/// 结束运行
diff --git a/Library/Entity/MoveNodeData.cs b/Library/Entity/MoveNodeData.cs
index bfac713..d437aa3 100644
--- a/Library/Entity/MoveNodeData.cs
+++ b/Library/Entity/MoveNodeData.cs
@@ -7,12 +7,5 @@ using System.Threading.Tasks;
namespace Serein.Library
{
- ///
- /// 拖拽创建节点使用的数据
- ///
- public class MoveNodeData
- {
- public NodeControlType NodeControlType { get; set; }
- public MethodDetailsInfo MethodDetailsInfo { get; set; }
- }
+
}
diff --git a/Library/Extension/FlowModelExtension.cs b/Library/Extension/FlowModelExtension.cs
index df53097..6e051d6 100644
--- a/Library/Extension/FlowModelExtension.cs
+++ b/Library/Extension/FlowModelExtension.cs
@@ -101,10 +101,10 @@ namespace Serein.Library
// 生成参数列表
ParameterData[] parameterData = nodeModel.SaveParameterInfo();
- NodeInfo nodeInfo = new NodeInfo
+ var nodeInfo = new NodeInfo
{
- Guid = nodeModel.Guid,
CanvasGuid = nodeModel.CanvasGuid,
+ Guid = nodeModel.Guid,
AssemblyName = nodeModel.MethodDetails.AssemblyName,
MethodName = nodeModel.MethodDetails?.MethodName,
Label = nodeModel.MethodDetails?.MethodAnotherName,
@@ -130,10 +130,12 @@ namespace Serein.Library
///
/// 从节点信息加载节点
///
+ ///
///
///
public static void LoadInfo(this NodeModelBase nodeModel, NodeInfo nodeInfo)
{
+ nodeModel.CanvasGuid = nodeInfo.CanvasGuid;
nodeModel.Guid = nodeInfo.Guid;
nodeModel.Position = nodeInfo.Position ?? new PositionOfUI(0, 0);// 加载位置信息
var md = nodeModel.MethodDetails; // 当前节点的方法说明
@@ -191,6 +193,7 @@ namespace Serein.Library
///
/// 开始执行
///
+ ///
///
/// 流程运行
///
diff --git a/Library/FlowNode/FlowCanvasDetails.cs b/Library/FlowNode/FlowCanvasDetails.cs
index 4f56a64..0fa1ef7 100644
--- a/Library/FlowNode/FlowCanvasDetails.cs
+++ b/Library/FlowNode/FlowCanvasDetails.cs
@@ -23,6 +23,7 @@ namespace Serein.Library
Env = env;
}
+
public IFlowEnvironment Env { get; }
///
@@ -79,8 +80,6 @@ namespace Serein.Library
///
private string _startNode;
-
-
}
diff --git a/Library/FlowNode/MethodDetailsInfo.cs b/Library/FlowNode/MethodDetailsInfo.cs
index 64bb13f..e8856fb 100644
--- a/Library/FlowNode/MethodDetailsInfo.cs
+++ b/Library/FlowNode/MethodDetailsInfo.cs
@@ -27,7 +27,7 @@ namespace Serein.Library
public string NodeType { get; set; }
///
- /// 方法说明
+ /// 方法别名
///
public string MethodAnotherName { get; set; }
diff --git a/Library/FlowNode/SereinProjectData.cs b/Library/FlowNode/SereinProjectData.cs
index 8ccc9fa..3cd8754 100644
--- a/Library/FlowNode/SereinProjectData.cs
+++ b/Library/FlowNode/SereinProjectData.cs
@@ -336,6 +336,7 @@ namespace Serein.Library
_x = x; _y = y;
}
+
///
/// 指示控件在画布的横向向方向上的位置
///
diff --git a/Library/Serein.Library.csproj b/Library/Serein.Library.csproj
index b0f5275..574d076 100644
--- a/Library/Serein.Library.csproj
+++ b/Library/Serein.Library.csproj
@@ -14,6 +14,7 @@
MIT
True
latest
+ no
true
true
diff --git a/NodeFlow/Env/FlowEnvironment.cs b/NodeFlow/Env/FlowEnvironment.cs
index 79265f3..1c84fb0 100644
--- a/NodeFlow/Env/FlowEnvironment.cs
+++ b/NodeFlow/Env/FlowEnvironment.cs
@@ -368,27 +368,87 @@ namespace Serein.NodeFlow.Env
/// 异步运行
///
///
- public async Task StartFlowAsync()
+ public async Task StartFlowAsync(string[] canvasGuids)
{
+ #region 校验参数
+ HashSet guids = new HashSet();
+ bool isBreak = false;
+ foreach (var canvasGuid in canvasGuids)
+ {
+ if (guids.Contains(canvasGuid))
+ {
+ SereinEnv.WriteLine(InfoType.WARN, $"画布重复,停止运行。{canvasGuid}");
+ isBreak = true;
+ }
+ if (!FlowCanvass.ContainsKey(canvasGuid))
+ {
+ SereinEnv.WriteLine(InfoType.WARN, $"画布不存在,停止运行。{canvasGuid}");
+ isBreak = true;
+ }
+ var count = NodeModels.Values.Count(n => n.CanvasGuid.Equals(canvasGuid));
+ if(count == 0)
+ {
+ SereinEnv.WriteLine(InfoType.WARN, $"画布没有节点,停止运行。{canvasGuid}");
+ isBreak = true;
+ }
+ else
+ {
+ guids.Add(canvasGuid);
+ }
+ }
+ if (isBreak)
+ {
+ guids.Clear();
+ return false;
+ }
+ #endregion
+
+
+ #region 初始化每个画布的数据,转换为流程任务
+ Dictionary flowTasks = [];
+ foreach (var guid in guids)
+ {
+ if (!TryGetCanvasModel(guid, out var canvasModel))
+ {
+ SereinEnv.WriteLine(InfoType.WARN, $"画布不存在,停止运行。{guid}");
+ return false;
+ }
+ var ft = new FlowTask();
+ ft.GetNodes = () => NodeModels.Values.Where(node => node.CanvasGuid.Equals(guid)).ToList();
+ var startNodeModel = NodeModels.GetValueOrDefault(canvasModel.StartNode);
+ if(startNodeModel is null)
+ {
+ SereinEnv.WriteLine(InfoType.WARN, $"画布不存在起始节点,将停止运行。{guid}");
+ return false;
+ }
+ ft.GetStartNode = () => startNodeModel;
+ flowTasks.Add(guid, ft);
+ }
+ #endregion
+
+
+
IOC.Reset();
IOC.Register(); // 注册脚本接口
var flowTaskOptions = new FlowWorkOptions
{
- Environment = this,
- FlowContextPool = new ObjectPool(() => new DynamicContext(this)),
- //Nodes = NodeModels.Values.ToList(),
- AutoRegisterTypes = this.FlowLibraryManagement.GetaAutoRegisterType(),
- InitMds = this.FlowLibraryManagement.GetMdsOnFlowStart(NodeType.Init),
+ Environment = this, // 流程
+ Flows = flowTasks,
+ FlowContextPool = new ObjectPool(() => new DynamicContext(this)), // 上下文对象池
+ AutoRegisterTypes = this.FlowLibraryManagement.GetaAutoRegisterType(), // 需要自动实例化的类型
+ InitMds = this.FlowLibraryManagement.GetMdsOnFlowStart(NodeType.Init),
LoadMds = this.FlowLibraryManagement.GetMdsOnFlowStart(NodeType.Loading),
ExitMds = this.FlowLibraryManagement.GetMdsOnFlowStart(NodeType.Exit),
-
};
+
+
+
flowTaskManagement = new FlowWorkManagement(flowTaskOptions);
var cts = new CancellationTokenSource();
try
{
- var t =await flowTaskManagement.RunAsync(cts.Token);
+ var t = await flowTaskManagement.RunAsync(cts.Token);
}
catch (Exception ex)
{
@@ -405,12 +465,13 @@ namespace Serein.NodeFlow.Env
}
+
///
/// 从选定节点开始运行
///
///
///
- public async Task StartAsyncInSelectNode(string startNodeGuid)
+ public async Task StartFlowFromSelectNodeAsync(string startNodeGuid)
{
if (flowTaskManagement is null)
@@ -425,12 +486,6 @@ namespace Serein.NodeFlow.Env
{
return false;
}
- //var getExp = "@get .DebugSetting.IsEnable";
- //var getExpResult1 = SerinExpressionEvaluator.Evaluate(getExp, nodeModel,out _);
- //var setExp = "@set .DebugSetting.IsEnable = false";
- //SerinExpressionEvaluator.Evaluate(setExp, nodeModel,out _);
- //var getExpResult2 = SerinExpressionEvaluator.Evaluate(getExp, nodeModel, out _);
-
await flowTaskManagement.StartFlowInSelectNodeAsync(this, nodeModel);
return true;
}
@@ -559,9 +614,22 @@ namespace Serein.NodeFlow.Env
LoadLibrary(dllFilePath); // 加载项目文件时加载对应的程序集
}
+
+
_ = Task.Run( async () =>
- {
+ {
+ // 加载画布
+ foreach (var canvasInfo in projectData.Canvass)
+ {
+ LoadCanvas(canvasInfo);
+ }
await LoadNodeInfosAsync(projectData.Nodes.ToList()); // 加载节点信息
+
+ // 加载画布
+ foreach (var canvasInfo in projectData.Canvass)
+ {
+ await SetStartNodeAsync(canvasInfo.Guid, canvasInfo.StartNode); // 设置起始节点
+ }
//await SetStartNodeAsync("", projectData.StartNode); // 设置起始节点
});
@@ -779,20 +847,31 @@ namespace Serein.NodeFlow.Env
///
public async Task CreateCanvasAsync(string canvasName, int width, int height)
{
- var model = new FlowCanvasDetails(this)
+ var info = new FlowCanvasDetailsInfo()
{
Guid = Guid.NewGuid().ToString(),
Height = height,
Width = width,
+ ViewX = 0,
+ ViewY = 0,
+ ScaleY = 1,
+ ScaleX = 1,
Name = !string.IsNullOrWhiteSpace(canvasName) ? canvasName : $"流程图{_addCanvasCount++}",
};
+ var model = LoadCanvas(info);
+ return info;
+ }
+
+ private FlowCanvasDetails LoadCanvas(FlowCanvasDetailsInfo info)
+ {
+ var model = new FlowCanvasDetails(this);
+ model.LoadInfo(info);
FlowCanvass.Add(model.Guid, model);
- await UIContextOperation.InvokeAsync(() =>
+ UIContextOperation.InvokeAsync(() =>
{
OnCanvasCreate.Invoke(new CanvasCreateEventArgs(model));
});
- var info = model.ToInfo();
- return info;
+ return model;
}
///
@@ -957,7 +1036,7 @@ namespace Serein.NodeFlow.Env
#region 确定节点之间的参数调用关系
foreach (var toNode in NodeModels.Values)
{
- var canvasGuid = toNode.Guid;
+ var canvasGuid = toNode.CanvasGuid;
if (toNode.MethodDetails.ParameterDetailss == null)
{
continue;
@@ -1727,7 +1806,7 @@ namespace Serein.NodeFlow.Env
private bool TryAddNode(NodeModelBase nodeModel)
{
nodeModel.Guid ??= Guid.NewGuid().ToString();
- NodeModels[nodeModel.Guid] = nodeModel;
+ NodeModels.TryAdd(nodeModel.Guid, nodeModel);
// 如果是触发器,则需要添加到专属集合中
if (nodeModel is SingleFlipflopNode flipflopNode)
@@ -1944,32 +2023,22 @@ namespace Serein.NodeFlow.Env
///
/// 更改起点节点
///
- ///
- ///
+ /// 节点所在的画布
+ /// 起始节点
private void SetStartNode(FlowCanvasDetails cavnasModel, NodeModelBase newStartNode)
{
var oldNodeGuid = cavnasModel.StartNode;
+ /*if(TryGetNodeModel(oldNodeGuid, out var newStartNodeModel))
+ {
+ newStartNode.IsStart = false;
+ }*/
cavnasModel.StartNode = newStartNode.Guid;
+ //newStartNode.IsStart = true;
+
UIContextOperation?.Invoke(() => OnStartNodeChange?.Invoke(new StartNodeChangeEventArgs(cavnasModel.Guid, oldNodeGuid, cavnasModel.StartNode)));
- //if (OperatingSystem.IsWindows())
- //{
- // }
}
- /////
- ///// 输出内容
- /////
- /////
- //private void Output(string msg)
- //{
- // if (OperatingSystem.IsWindows())
- // {
- // UIContextOperation?.Invoke(() => OnEnvOut?.Invoke(msg));
- // }
-
- //}
-
///
/// 向容器登记缓存的持久化实例
///
diff --git a/NodeFlow/Env/FlowEnvironmentDecorator.cs b/NodeFlow/Env/FlowEnvironmentDecorator.cs
index 5456d7c..4d6493f 100644
--- a/NodeFlow/Env/FlowEnvironmentDecorator.cs
+++ b/NodeFlow/Env/FlowEnvironmentDecorator.cs
@@ -263,7 +263,7 @@ namespace Serein.NodeFlow.Env
/// 目标节点控制点
/// 决定了方法执行后的后继行为
public async Task ConnectInvokeNodeAsync(string canvasGuid,
- string fromNodeGuid,
+ string fromNodeGuid,
string toNodeGuid,
JunctionType fromNodeJunctionType,
JunctionType toNodeJunctionType,
@@ -518,14 +518,16 @@ namespace Serein.NodeFlow.Env
return await currentFlowEnvironment.SetStartNodeAsync(canvasGuid, nodeGuid);
}
- public async Task StartFlowAsync()
+ public async Task StartFlowAsync(string[] canvasGuids)
{
- return await currentFlowEnvironment.StartFlowAsync();
+ return await currentFlowEnvironment.StartFlowAsync(canvasGuids);
}
- public async Task StartAsyncInSelectNode(string startNodeGuid)
+
+
+ public async Task StartFlowFromSelectNodeAsync(string startNodeGuid)
{
- return await currentFlowEnvironment.StartAsyncInSelectNode(startNodeGuid);
+ return await currentFlowEnvironment.StartFlowFromSelectNodeAsync(startNodeGuid);
}
diff --git a/NodeFlow/Env/MsgControllerOfServer.cs b/NodeFlow/Env/MsgControllerOfServer.cs
index 5902b98..005fce0 100644
--- a/NodeFlow/Env/MsgControllerOfServer.cs
+++ b/NodeFlow/Env/MsgControllerOfServer.cs
@@ -173,10 +173,10 @@ namespace Serein.NodeFlow.Env
///
///
[AutoSocketHandle(ThemeValue = EnvMsgTheme.StartFlow)]
- private async Task