mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-04-01 22:16:34 +08:00
实现了拖拽式设置方法调用顺序、方法入参参数来源
This commit is contained in:
@@ -7,6 +7,7 @@ using Serein.Library.Utils.SereinExpression;
|
||||
using Serein.NodeFlow.Model;
|
||||
using Serein.NodeFlow.Tool;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Numerics;
|
||||
using System.Reflection;
|
||||
using System.Xml.Linq;
|
||||
using static Serein.Library.Utils.ChannelFlowInterrupt;
|
||||
@@ -409,6 +410,24 @@ namespace Serein.NodeFlow.Env
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单独运行一个节点
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="nodeGuid"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<object> InvokeNodeAsync(string nodeGuid)
|
||||
{
|
||||
if(this.NodeModels.TryGetValue(nodeGuid, out var model))
|
||||
{
|
||||
return await model.ExecutingAsync(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出
|
||||
/// </summary>
|
||||
@@ -633,23 +652,23 @@ namespace Serein.NodeFlow.Env
|
||||
}
|
||||
|
||||
|
||||
List<(ConnectionType connectionType, string[] guids)> allToNodes = [(ConnectionType.IsSucceed,nodeInfo.TrueNodes),
|
||||
(ConnectionType.IsFail, nodeInfo.FalseNodes),
|
||||
(ConnectionType.IsError, nodeInfo.ErrorNodes),
|
||||
(ConnectionType.Upstream, nodeInfo.UpstreamNodes)];
|
||||
List<(ConnectionInvokeType connectionType, string[] guids)> allToNodes = [(ConnectionInvokeType.IsSucceed,nodeInfo.TrueNodes),
|
||||
(ConnectionInvokeType.IsFail, nodeInfo.FalseNodes),
|
||||
(ConnectionInvokeType.IsError, nodeInfo.ErrorNodes),
|
||||
(ConnectionInvokeType.Upstream, nodeInfo.UpstreamNodes)];
|
||||
|
||||
List<(ConnectionType, NodeModelBase[])> fromNodes = allToNodes.Where(info => info.guids.Length > 0)
|
||||
List<(ConnectionInvokeType, NodeModelBase[])> fromNodes = allToNodes.Where(info => info.guids.Length > 0)
|
||||
.Select(info => (info.connectionType,
|
||||
info.guids.Where(guid => NodeModels.ContainsKey(guid)).Select(guid => NodeModels[guid])
|
||||
.ToArray()))
|
||||
.ToList();
|
||||
// 遍历每种类型的节点分支(四种)
|
||||
foreach ((ConnectionType connectionType, NodeModelBase[] toNodes) item in fromNodes)
|
||||
foreach ((ConnectionInvokeType connectionType, NodeModelBase[] toNodes) item in fromNodes)
|
||||
{
|
||||
// 遍历当前类型分支的节点(确认连接关系)
|
||||
foreach (var toNode in item.toNodes)
|
||||
{
|
||||
ConnectNodeAsync(fromNode, toNode, item.connectionType); // 加载时确定节点间的连接关系
|
||||
_ = ConnectInvokeOfNode(fromNode, toNode, item.connectionType); // 加载时确定节点间的连接关系
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -859,9 +878,11 @@ namespace Serein.NodeFlow.Env
|
||||
NodeModelBase? pNode = pnc.Value[i];
|
||||
pNode.SuccessorNodes[pCType].Remove(remoteNode);
|
||||
|
||||
UIContextOperation?.Invoke(() => OnNodeConnectChange?.Invoke(new NodeConnectChangeEventArgs(pNode.Guid,
|
||||
UIContextOperation?.Invoke(() => OnNodeConnectChange?.Invoke(new NodeConnectChangeEventArgs(
|
||||
pNode.Guid,
|
||||
remoteNode.Guid,
|
||||
pCType,
|
||||
JunctionOfConnectionType.Invoke,
|
||||
pCType, // 对应的连接关系
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Remote))); // 通知UI
|
||||
|
||||
}
|
||||
@@ -894,15 +915,63 @@ namespace Serein.NodeFlow.Env
|
||||
/// <param name="fromNodeJunctionType">起始节点控制点</param>
|
||||
/// <param name="toNodeJunctionType">目标节点控制点</param>
|
||||
/// <param name="connectionType">连接关系</param>
|
||||
public async Task<bool> ConnectNodeAsync(string fromNodeGuid, string toNodeGuid, JunctionType fromNodeJunctionType, JunctionType toNodeJunctionType, ConnectionType connectionType)
|
||||
public async Task<bool> ConnectNodeAsync(string fromNodeGuid,
|
||||
string toNodeGuid,
|
||||
JunctionType fromNodeJunctionType,
|
||||
JunctionType toNodeJunctionType,
|
||||
ConnectionInvokeType connectionType,
|
||||
int argIndex)
|
||||
{
|
||||
|
||||
// 获取起始节点与目标节点
|
||||
var fromNode = GuidToModel(fromNodeGuid);
|
||||
var toNode = GuidToModel(toNodeGuid);
|
||||
if (fromNode is null || toNode is null) return false;
|
||||
(var type,var state) = CheckConnect(fromNode, toNode, fromNodeJunctionType, toNodeJunctionType);
|
||||
if (!state)
|
||||
{
|
||||
Console.WriteLine("出现非预期的连接行为");
|
||||
return false; // 出现不符预期的连接行为,忽略此次连接行为
|
||||
}
|
||||
|
||||
// 开始连接
|
||||
return await ConnectNodeAsync(fromNode, toNode, connectionType); // 外部调用连接方法
|
||||
|
||||
if(type == JunctionOfConnectionType.Invoke)
|
||||
{
|
||||
if (fromNodeJunctionType == JunctionType.Execute)
|
||||
{
|
||||
// 如果 起始控制点 是“方法调用”,需要反转 from to 节点
|
||||
(fromNode, toNode) = (toNode, fromNode);
|
||||
}
|
||||
// 从起始节点“下一个方法”控制点,连接到目标节点“方法调用”控制点
|
||||
state = ConnectInvokeOfNode(fromNode, toNode, connectionType); // 本地环境进行连接
|
||||
}
|
||||
else if (type == JunctionOfConnectionType.Arg)
|
||||
{
|
||||
ConnectionArgSourceType connectionArgSourceType;
|
||||
|
||||
if (fromNode.Guid.Equals(toNode.Guid))
|
||||
{
|
||||
connectionArgSourceType = ConnectionArgSourceType.GetPreviousNodeData;
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionArgSourceType = ConnectionArgSourceType.GetOtherNodeData;
|
||||
}
|
||||
|
||||
// (连接自身的情况下)从上一个节点“返回值”控制点,连接到目标节点“方法入参”控制点
|
||||
// 从起始节点“返回值”控制点,连接到目标节点“方法入参”控制点
|
||||
if (fromNodeJunctionType == JunctionType.ArgData)
|
||||
{
|
||||
// 如果 起始控制点 是“方法入参”,需要反转 from to 节点
|
||||
(fromNode, toNode) = (toNode, fromNode);
|
||||
}
|
||||
|
||||
|
||||
// 确定方法入参关系
|
||||
state = ConnectGerResultOfNode(fromNode, toNode, connectionArgSourceType, argIndex); // 本地环境进行连接
|
||||
}
|
||||
|
||||
return state;
|
||||
|
||||
}
|
||||
|
||||
@@ -913,7 +982,7 @@ namespace Serein.NodeFlow.Env
|
||||
/// <param name="toNodeGuid">目标节点Guid</param>
|
||||
/// <param name="connectionType">连接关系</param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public async Task<bool> RemoveConnectAsync(string fromNodeGuid, string toNodeGuid, ConnectionType connectionType)
|
||||
public async Task<bool> RemoveConnectAsync(string fromNodeGuid, string toNodeGuid, ConnectionInvokeType connectionType)
|
||||
{
|
||||
// 获取起始节点与目标节点
|
||||
var fromNode = GuidToModel(fromNodeGuid);
|
||||
@@ -923,8 +992,6 @@ namespace Serein.NodeFlow.Env
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取方法描述
|
||||
/// </summary>
|
||||
@@ -1245,6 +1312,9 @@ namespace Serein.NodeFlow.Env
|
||||
#region 私有方法
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 加载指定路径的DLL文件
|
||||
/// </summary>
|
||||
@@ -1290,7 +1360,7 @@ namespace Serein.NodeFlow.Env
|
||||
/// <param name="toNodeGuid">目标节点Model</param>
|
||||
/// <param name="connectionType">连接关系</param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private async Task<bool> RemoteConnectAsync(NodeModelBase fromNode, NodeModelBase toNode, ConnectionType connectionType)
|
||||
private async Task<bool> RemoteConnectAsync(NodeModelBase fromNode, NodeModelBase toNode, ConnectionInvokeType connectionType)
|
||||
{
|
||||
fromNode.SuccessorNodes[connectionType].Remove(toNode);
|
||||
toNode.PreviousNodes[connectionType].Remove(fromNode);
|
||||
@@ -1298,8 +1368,10 @@ namespace Serein.NodeFlow.Env
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
await UIContextOperation.InvokeAsync(() => OnNodeConnectChange?.Invoke(new NodeConnectChangeEventArgs(fromNode.Guid,
|
||||
await UIContextOperation.InvokeAsync(() => OnNodeConnectChange?.Invoke(new NodeConnectChangeEventArgs(
|
||||
fromNode.Guid,
|
||||
toNode.Guid,
|
||||
JunctionOfConnectionType.Invoke,
|
||||
connectionType,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Remote)));
|
||||
}
|
||||
@@ -1431,13 +1503,85 @@ namespace Serein.NodeFlow.Env
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 检查连接
|
||||
/// </summary>
|
||||
/// <param name="fromNode">发起连接的起始节点</param>
|
||||
/// <param name="toNode">要连接的目标节点</param>
|
||||
/// <param name="fromNodeJunctionType">发起连接节点的控制点类型</param>
|
||||
/// <param name="toNodeJunctionType">被连接节点的控制点类型</param>
|
||||
/// <returns></returns>
|
||||
public static (JunctionOfConnectionType,bool) CheckConnect(NodeModelBase fromNode,
|
||||
NodeModelBase toNode,
|
||||
JunctionType fromNodeJunctionType,
|
||||
JunctionType toNodeJunctionType)
|
||||
{
|
||||
var type = JunctionOfConnectionType.None;
|
||||
var state = false;
|
||||
if (fromNodeJunctionType == JunctionType.Execute)
|
||||
{
|
||||
if (toNodeJunctionType == JunctionType.NextStep && !fromNode.Guid.Equals(toNode.Guid))
|
||||
{
|
||||
// “方法执行”控制点拖拽到“下一节点”控制点,且不是同一个节点, 添加方法执行关系
|
||||
type = JunctionOfConnectionType.Invoke;
|
||||
state = true;
|
||||
}
|
||||
else if (toNodeJunctionType == JunctionType.ArgData && fromNode.Guid.Equals(toNode.Guid))
|
||||
{
|
||||
// “方法执行”控制点拖拽到“方法入参”控制点,且是同一个节点,则添加获取参数关系,表示生成入参参数时自动从该节点的上一节点获取flowdata
|
||||
type = JunctionOfConnectionType.Arg;
|
||||
state = true;
|
||||
}
|
||||
}
|
||||
else if (fromNodeJunctionType == JunctionType.NextStep && !fromNode.Guid.Equals(toNode.Guid))
|
||||
{
|
||||
// “下一节点”控制点只能拖拽到“方法执行”控制点,且不能是同一个节点
|
||||
if (toNodeJunctionType == JunctionType.Execute && !fromNode.Guid.Equals(toNode.Guid))
|
||||
{
|
||||
type = JunctionOfConnectionType.Invoke;
|
||||
state = true;
|
||||
}
|
||||
}
|
||||
else if (fromNodeJunctionType == JunctionType.ArgData)
|
||||
{
|
||||
if (toNodeJunctionType == JunctionType.Execute && fromNode.Guid.Equals(toNode.Guid)) // 添加获取参数关系
|
||||
{
|
||||
// “方法入参”控制点拖拽到“方法执行”控制点,且是同一个节点,则添加获取参数关系,生成入参参数时自动从该节点的上一节点获取flowdata
|
||||
type = JunctionOfConnectionType.Arg;
|
||||
state = true;
|
||||
}
|
||||
if(toNodeJunctionType == JunctionType.ReturnData && !fromNode.Guid.Equals(toNode.Guid))
|
||||
{
|
||||
// “”控制点拖拽到“方法返回值”控制点,且不是同一个节点,添加获取参数关系,生成参数时从目标节点获取flowdata
|
||||
type = JunctionOfConnectionType.Arg;
|
||||
state = true;
|
||||
}
|
||||
}
|
||||
else if (fromNodeJunctionType == JunctionType.ReturnData)
|
||||
{
|
||||
if (toNodeJunctionType == JunctionType.ArgData && !fromNode.Guid.Equals(toNode.Guid))
|
||||
{
|
||||
// “方法返回值”控制点拖拽到“方法入参”控制点,且不是同一个节点,添加获取参数关系,生成参数时从目标节点获取flowdata
|
||||
type = JunctionOfConnectionType.Arg;
|
||||
state = true;
|
||||
}
|
||||
}
|
||||
// 剩下的情况都是不符预期的连接行为,忽略。
|
||||
return (type,state);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 连接节点
|
||||
/// </summary>
|
||||
/// <param name="fromNode">起始节点</param>
|
||||
/// <param name="toNode">目标节点</param>
|
||||
/// <param name="connectionType">连接关系</param>
|
||||
private async Task<bool> ConnectNodeAsync(NodeModelBase fromNode, NodeModelBase toNode, ConnectionType connectionType)
|
||||
private bool ConnectInvokeOfNode(NodeModelBase fromNode, NodeModelBase toNode, ConnectionInvokeType connectionType)
|
||||
{
|
||||
if (fromNode is null || toNode is null || fromNode == toNode)
|
||||
{
|
||||
@@ -1446,10 +1590,10 @@ namespace Serein.NodeFlow.Env
|
||||
|
||||
var ToExistOnFrom = true;
|
||||
var FromExistInTo = true;
|
||||
ConnectionType[] ct = [ConnectionType.IsSucceed,
|
||||
ConnectionType.IsFail,
|
||||
ConnectionType.IsError,
|
||||
ConnectionType.Upstream];
|
||||
ConnectionInvokeType[] ct = [ConnectionInvokeType.IsSucceed,
|
||||
ConnectionInvokeType.IsFail,
|
||||
ConnectionInvokeType.IsError,
|
||||
ConnectionInvokeType.Upstream];
|
||||
|
||||
if (toNode is SingleFlipflopNode flipflopNode)
|
||||
{
|
||||
@@ -1457,7 +1601,7 @@ namespace Serein.NodeFlow.Env
|
||||
}
|
||||
|
||||
var isPass = false;
|
||||
foreach (ConnectionType ctType in ct)
|
||||
foreach (ConnectionInvokeType ctType in ct)
|
||||
{
|
||||
var FToTo = fromNode.SuccessorNodes[ctType].Where(it => it.Guid.Equals(toNode.Guid)).ToArray();
|
||||
var ToOnF = toNode.PreviousNodes[ctType].Where(it => it.Guid.Equals(fromNode.Guid)).ToArray();
|
||||
@@ -1494,12 +1638,18 @@ namespace Serein.NodeFlow.Env
|
||||
toNode.PreviousNodes[connectionType].Add(fromNode); // 添加到目标节点的父分支
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
UIContextOperation?.Invoke(() => OnNodeConnectChange?.Invoke(new NodeConnectChangeEventArgs(fromNode.Guid,
|
||||
toNode.Guid,
|
||||
connectionType,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Create))); // 通知UI
|
||||
UIContextOperation?.Invoke(() =>
|
||||
OnNodeConnectChange?.Invoke(
|
||||
new NodeConnectChangeEventArgs(
|
||||
fromNode.Guid, // 从哪个节点开始
|
||||
toNode.Guid, // 连接到那个节点
|
||||
JunctionOfConnectionType.Invoke,
|
||||
connectionType, // 连接线的样式类型
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Create // 是创建连接还是删除连接
|
||||
))); // 通知UI
|
||||
}
|
||||
|
||||
// Invoke
|
||||
// GetResult
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -1510,6 +1660,30 @@ namespace Serein.NodeFlow.Env
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接节点参数
|
||||
/// </summary>
|
||||
/// <param name="fromNode"></param>
|
||||
/// <param name="toNode"></param>
|
||||
/// <param name="connectionArgSourceType"></param>
|
||||
/// <param name="argIndex"></param>
|
||||
/// <returns></returns>
|
||||
private bool ConnectGerResultOfNode(NodeModelBase fromNode, NodeModelBase toNode, ConnectionArgSourceType connectionArgSourceType,int argIndex)
|
||||
{
|
||||
UIContextOperation?.Invoke(() =>
|
||||
OnNodeConnectChange?.Invoke(
|
||||
new NodeConnectChangeEventArgs(
|
||||
fromNode.Guid, // 从哪个节点开始
|
||||
toNode.Guid, // 连接到那个节点
|
||||
JunctionOfConnectionType.Arg,
|
||||
(int)argIndex, // 连接线的样式类型
|
||||
connectionArgSourceType,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Create // 是创建连接还是删除连接
|
||||
))); // 通知UI
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 更改起点节点
|
||||
/// </summary>
|
||||
|
||||
@@ -180,9 +180,14 @@ namespace Serein.NodeFlow.Env
|
||||
currentFlowEnvironment.ClearAll();
|
||||
}
|
||||
|
||||
public async Task<bool> ConnectNodeAsync(string fromNodeGuid, string toNodeGuid, JunctionType fromNodeJunctionType, JunctionType toNodeJunctionType, ConnectionType connectionType)
|
||||
public async Task<bool> ConnectNodeAsync(string fromNodeGuid,
|
||||
string toNodeGuid,
|
||||
JunctionType fromNodeJunctionType,
|
||||
JunctionType toNodeJunctionType,
|
||||
ConnectionInvokeType connectionType,
|
||||
int argIndex)
|
||||
{
|
||||
return await currentFlowEnvironment.ConnectNodeAsync(fromNodeGuid, toNodeGuid, fromNodeJunctionType, toNodeJunctionType, connectionType);
|
||||
return await currentFlowEnvironment.ConnectNodeAsync(fromNodeGuid, toNodeGuid, fromNodeJunctionType, toNodeJunctionType, connectionType, argIndex);
|
||||
}
|
||||
|
||||
public async Task<(bool, RemoteEnvControl)> ConnectRemoteEnv(string addres, int port, string token)
|
||||
@@ -265,13 +270,12 @@ namespace Serein.NodeFlow.Env
|
||||
}
|
||||
|
||||
|
||||
|
||||
public bool RemoteDll(string assemblyFullName)
|
||||
{
|
||||
return currentFlowEnvironment.RemoteDll(assemblyFullName);
|
||||
}
|
||||
|
||||
public async Task<bool> RemoveConnectAsync(string fromNodeGuid, string toNodeGuid, ConnectionType connectionType)
|
||||
public async Task<bool> RemoveConnectAsync(string fromNodeGuid, string toNodeGuid, ConnectionInvokeType connectionType)
|
||||
{
|
||||
return await currentFlowEnvironment.RemoveConnectAsync(fromNodeGuid, toNodeGuid, connectionType);
|
||||
}
|
||||
@@ -282,7 +286,6 @@ namespace Serein.NodeFlow.Env
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void SetConsoleOut()
|
||||
{
|
||||
currentFlowEnvironment.SetConsoleOut();
|
||||
@@ -313,6 +316,11 @@ namespace Serein.NodeFlow.Env
|
||||
await currentFlowEnvironment.StartAsyncInSelectNode(startNodeGuid);
|
||||
}
|
||||
|
||||
public async Task<object> InvokeNodeAsync(string nodeGuid)
|
||||
{
|
||||
return await currentFlowEnvironment.InvokeNodeAsync(nodeGuid);
|
||||
}
|
||||
|
||||
public async Task StartRemoteServerAsync(int port = 7525)
|
||||
{
|
||||
await currentFlowEnvironment.StartRemoteServerAsync(port);
|
||||
|
||||
@@ -107,14 +107,14 @@ namespace Serein.NodeFlow.Env
|
||||
/// <param name="flowStateType"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public static ConnectionType ToContentType(this FlipflopStateType flowStateType)
|
||||
public static ConnectionInvokeType ToContentType(this FlipflopStateType flowStateType)
|
||||
{
|
||||
return flowStateType switch
|
||||
{
|
||||
FlipflopStateType.Succeed => ConnectionType.IsSucceed,
|
||||
FlipflopStateType.Fail => ConnectionType.IsFail,
|
||||
FlipflopStateType.Error => ConnectionType.IsError,
|
||||
FlipflopStateType.Cancel => ConnectionType.None,
|
||||
FlipflopStateType.Succeed => ConnectionInvokeType.IsSucceed,
|
||||
FlipflopStateType.Fail => ConnectionInvokeType.IsFail,
|
||||
FlipflopStateType.Error => ConnectionInvokeType.IsError,
|
||||
FlipflopStateType.Cancel => ConnectionInvokeType.None,
|
||||
_ => throw new NotImplementedException("未定义的流程状态")
|
||||
};
|
||||
}
|
||||
@@ -126,11 +126,11 @@ namespace Serein.NodeFlow.Env
|
||||
/// <returns></returns>
|
||||
public static bool NotExitPreviousNode(this SingleFlipflopNode node)
|
||||
{
|
||||
ConnectionType[] ct = [ConnectionType.IsSucceed,
|
||||
ConnectionType.IsFail,
|
||||
ConnectionType.IsError,
|
||||
ConnectionType.Upstream];
|
||||
foreach (ConnectionType ctType in ct)
|
||||
ConnectionInvokeType[] ct = [ConnectionInvokeType.IsSucceed,
|
||||
ConnectionInvokeType.IsFail,
|
||||
ConnectionInvokeType.IsError,
|
||||
ConnectionInvokeType.Upstream];
|
||||
foreach (ConnectionInvokeType ctType in ct)
|
||||
{
|
||||
if (node.PreviousNodes[ctType].Count > 0)
|
||||
{
|
||||
|
||||
@@ -340,7 +340,7 @@ namespace Serein.NodeFlow.Env
|
||||
[AutoSocketHandle(ThemeValue = EnvMsgTheme.ConnectNode)]
|
||||
public async Task<object> ConnectNode(string fromNodeGuid, string toNodeGuid, string connectionType)
|
||||
{
|
||||
if (!EnumHelper.TryConvertEnum<ConnectionType>(connectionType, out var tmpConnectionType))
|
||||
if (!EnumHelper.TryConvertEnum<ConnectionInvokeType>(connectionType, out var tmpConnectionType))
|
||||
{
|
||||
return new
|
||||
{
|
||||
@@ -348,7 +348,7 @@ namespace Serein.NodeFlow.Env
|
||||
};
|
||||
}
|
||||
//environment.ConnectNodeAsync(fromNodeGuid, toNodeGuid, tmpConnectionType);
|
||||
var result = await environment.ConnectNodeAsync(fromNodeGuid, toNodeGuid, tmpConnectionType);
|
||||
var result = await environment.ConnectNodeAsync(fromNodeGuid, toNodeGuid,0,0, tmpConnectionType,0);
|
||||
return new
|
||||
{
|
||||
state = result
|
||||
@@ -365,7 +365,7 @@ namespace Serein.NodeFlow.Env
|
||||
[AutoSocketHandle(ThemeValue = EnvMsgTheme.RemoveConnect)]
|
||||
public async Task<object> RemoveConnect(string fromNodeGuid, string toNodeGuid, string connectionType)
|
||||
{
|
||||
if (!EnumHelper.TryConvertEnum<ConnectionType>(connectionType, out var tmpConnectionType))
|
||||
if (!EnumHelper.TryConvertEnum<ConnectionInvokeType>(connectionType, out var tmpConnectionType))
|
||||
{
|
||||
return new
|
||||
{
|
||||
|
||||
@@ -218,18 +218,18 @@ namespace Serein.NodeFlow.Env
|
||||
}
|
||||
|
||||
|
||||
List<(ConnectionType connectionType, string[] guids)> allToNodes = [(ConnectionType.IsSucceed,nodeInfo.TrueNodes),
|
||||
(ConnectionType.IsFail, nodeInfo.FalseNodes),
|
||||
(ConnectionType.IsError, nodeInfo.ErrorNodes),
|
||||
(ConnectionType.Upstream, nodeInfo.UpstreamNodes)];
|
||||
List<(ConnectionInvokeType connectionType, string[] guids)> allToNodes = [(ConnectionInvokeType.IsSucceed,nodeInfo.TrueNodes),
|
||||
(ConnectionInvokeType.IsFail, nodeInfo.FalseNodes),
|
||||
(ConnectionInvokeType.IsError, nodeInfo.ErrorNodes),
|
||||
(ConnectionInvokeType.Upstream, nodeInfo.UpstreamNodes)];
|
||||
|
||||
List<(ConnectionType, NodeModelBase[])> fromNodes = allToNodes.Where(info => info.guids.Length > 0)
|
||||
List<(ConnectionInvokeType, NodeModelBase[])> fromNodes = allToNodes.Where(info => info.guids.Length > 0)
|
||||
.Select(info => (info.connectionType,
|
||||
info.guids.Where(guid => NodeModels.ContainsKey(guid)).Select(guid => NodeModels[guid])
|
||||
.ToArray()))
|
||||
.ToList();
|
||||
// 遍历每种类型的节点分支(四种)
|
||||
foreach ((ConnectionType connectionType, NodeModelBase[] toNodes) item in fromNodes)
|
||||
foreach ((ConnectionInvokeType connectionType, NodeModelBase[] toNodes) item in fromNodes)
|
||||
{
|
||||
// 遍历当前类型分支的节点(确认连接关系)
|
||||
foreach (var toNode in item.toNodes)
|
||||
@@ -237,6 +237,7 @@ namespace Serein.NodeFlow.Env
|
||||
|
||||
UIContextOperation?.Invoke(() => OnNodeConnectChange?.Invoke(new NodeConnectChangeEventArgs(fromNode.Guid,
|
||||
toNode.Guid,
|
||||
JunctionOfConnectionType.Invoke,
|
||||
item.connectionType,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Create))); // 通知UI连接节点
|
||||
//OnNodeConnectChange?.Invoke(new NodeConnectChangeEventArgs(fromNode.Guid,
|
||||
@@ -273,7 +274,7 @@ namespace Serein.NodeFlow.Env
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ConnectNode(NodeModelBase fromNode, NodeModelBase toNode, ConnectionType connectionType)
|
||||
private void ConnectNode(NodeModelBase fromNode, NodeModelBase toNode, ConnectionInvokeType connectionType)
|
||||
{
|
||||
if (fromNode is null || toNode is null || fromNode == toNode)
|
||||
{
|
||||
@@ -282,13 +283,13 @@ namespace Serein.NodeFlow.Env
|
||||
|
||||
var ToExistOnFrom = true;
|
||||
var FromExistInTo = true;
|
||||
ConnectionType[] ct = [ConnectionType.IsSucceed,
|
||||
ConnectionType.IsFail,
|
||||
ConnectionType.IsError,
|
||||
ConnectionType.Upstream];
|
||||
ConnectionInvokeType[] ct = [ConnectionInvokeType.IsSucceed,
|
||||
ConnectionInvokeType.IsFail,
|
||||
ConnectionInvokeType.IsError,
|
||||
ConnectionInvokeType.Upstream];
|
||||
|
||||
|
||||
foreach (ConnectionType ctType in ct)
|
||||
foreach (ConnectionInvokeType ctType in ct)
|
||||
{
|
||||
var FToTo = fromNode.SuccessorNodes[ctType].Where(it => it.Guid.Equals(toNode.Guid)).ToArray();
|
||||
var ToOnF = toNode.PreviousNodes[ctType].Where(it => it.Guid.Equals(fromNode.Guid)).ToArray();
|
||||
@@ -325,6 +326,7 @@ namespace Serein.NodeFlow.Env
|
||||
toNode.PreviousNodes[connectionType].Add(fromNode); // 添加到目标节点的父分支
|
||||
OnNodeConnectChange?.Invoke(new NodeConnectChangeEventArgs(fromNode.Guid,
|
||||
toNode.Guid,
|
||||
JunctionOfConnectionType.Invoke,
|
||||
connectionType,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Create)); // 通知UI
|
||||
}
|
||||
@@ -424,7 +426,22 @@ namespace Serein.NodeFlow.Env
|
||||
//UIContextOperation?.Invoke(() => OnStartNodeChange?.Invoke(new StartNodeChangeEventArgs(nodeGuid,nodeGuid)));
|
||||
}
|
||||
|
||||
public async Task<bool> ConnectNodeAsync(string fromNodeGuid, string toNodeGuid, JunctionType fromNodeJunctionType, JunctionType toNodeJunctionType, ConnectionType connectionType)
|
||||
public async Task<object> InvokeNodeAsync(string nodeGuid)
|
||||
{
|
||||
Console.WriteLine("远程环境尚未实现接口 InvokeNodeAsync");
|
||||
_ = msgClient.SendAsync(EnvMsgTheme.SetStartNode, new
|
||||
{
|
||||
nodeGuid
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<bool> ConnectNodeAsync(string fromNodeGuid,
|
||||
string toNodeGuid,
|
||||
JunctionType fromNodeJunctionType,
|
||||
JunctionType toNodeJunctionType,
|
||||
ConnectionInvokeType connectionType,
|
||||
int argIndex = 0)
|
||||
{
|
||||
var result = await msgClient.SendAndWaitDataAsync<bool>(EnvMsgTheme.ConnectNode, new
|
||||
{
|
||||
@@ -438,6 +455,7 @@ namespace Serein.NodeFlow.Env
|
||||
{
|
||||
OnNodeConnectChange?.Invoke(new NodeConnectChangeEventArgs(fromNodeGuid,
|
||||
toNodeGuid,
|
||||
JunctionOfConnectionType.Invoke,
|
||||
connectionType,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Create)); // 通知UI
|
||||
}
|
||||
@@ -472,7 +490,7 @@ namespace Serein.NodeFlow.Env
|
||||
return nodeInfo;
|
||||
}
|
||||
|
||||
public async Task<bool> RemoveConnectAsync(string fromNodeGuid, string toNodeGuid, ConnectionType connectionType)
|
||||
public async Task<bool> RemoveConnectAsync(string fromNodeGuid, string toNodeGuid, ConnectionInvokeType connectionType)
|
||||
{
|
||||
var result = await msgClient.SendAndWaitDataAsync<bool>(EnvMsgTheme.RemoveConnect, new
|
||||
{
|
||||
@@ -486,6 +504,7 @@ namespace Serein.NodeFlow.Env
|
||||
{
|
||||
OnNodeConnectChange?.Invoke(new NodeConnectChangeEventArgs(fromNodeGuid,
|
||||
toNodeGuid,
|
||||
JunctionOfConnectionType.Invoke,
|
||||
connectionType,
|
||||
NodeConnectChangeEventArgs.ConnectChangeType.Remote));
|
||||
});
|
||||
|
||||
@@ -351,9 +351,9 @@ namespace Serein.NodeFlow
|
||||
{
|
||||
var newFlowData = await singleFlipFlopNode.ExecutingAsync(context); // 获取触发器等待Task
|
||||
await NodeModelBase.RefreshFlowDataAndExpInterrupt(context, singleFlipFlopNode, newFlowData); // 全局触发器触发后刷新该触发器的节点数据
|
||||
if (singleFlipFlopNode.NextOrientation != ConnectionType.None)
|
||||
if (context.NextOrientation != ConnectionInvokeType.None)
|
||||
{
|
||||
var nextNodes = singleFlipFlopNode.SuccessorNodes[singleFlipFlopNode.NextOrientation];
|
||||
var nextNodes = singleFlipFlopNode.SuccessorNodes[context.NextOrientation];
|
||||
for (int i = nextNodes.Count - 1; i >= 0 && !_flipFlopCts.IsCancellationRequested; i--)
|
||||
{
|
||||
// 筛选出启用的节点
|
||||
|
||||
@@ -35,10 +35,10 @@ namespace Serein.NodeFlow.Model
|
||||
{
|
||||
if (MethodDetails is null) return null;
|
||||
|
||||
var trueNodes = SuccessorNodes[ConnectionType.IsSucceed].Select(item => item.Guid); // 真分支
|
||||
var falseNodes = SuccessorNodes[ConnectionType.IsFail].Select(item => item.Guid);// 假分支
|
||||
var errorNodes = SuccessorNodes[ConnectionType.IsError].Select(item => item.Guid);// 异常分支
|
||||
var upstreamNodes = SuccessorNodes[ConnectionType.Upstream].Select(item => item.Guid);// 上游分支
|
||||
var trueNodes = SuccessorNodes[ConnectionInvokeType.IsSucceed].Select(item => item.Guid); // 真分支
|
||||
var falseNodes = SuccessorNodes[ConnectionInvokeType.IsFail].Select(item => item.Guid);// 假分支
|
||||
var errorNodes = SuccessorNodes[ConnectionInvokeType.IsError].Select(item => item.Guid);// 异常分支
|
||||
var upstreamNodes = SuccessorNodes[ConnectionInvokeType.Upstream].Select(item => item.Guid);// 上游分支
|
||||
// 生成参数列表
|
||||
Parameterdata[] parameterData = GetParameterdatas();
|
||||
|
||||
|
||||
@@ -51,8 +51,8 @@ namespace Serein.NodeFlow.Model
|
||||
foreach (SingleConditionNode? node in ConditionNodes)
|
||||
{
|
||||
var state = await JudgeAsync(context, node);
|
||||
NextOrientation = state; // 每次判读完成后,设置区域后继方向为判断结果
|
||||
if (state != ConnectionType.IsSucceed)
|
||||
context.NextOrientation = state; // 每次判读完成后,设置区域后继方向为判断结果
|
||||
if (state != ConnectionInvokeType.IsSucceed)
|
||||
{
|
||||
// 如果条件不通过,立刻推出循环
|
||||
break;
|
||||
@@ -62,19 +62,19 @@ namespace Serein.NodeFlow.Model
|
||||
}
|
||||
|
||||
|
||||
private async Task<ConnectionType> JudgeAsync(IDynamicContext context, SingleConditionNode node)
|
||||
private async Task<ConnectionInvokeType> JudgeAsync(IDynamicContext context, SingleConditionNode node)
|
||||
{
|
||||
try
|
||||
{
|
||||
await node.ExecutingAsync(context);
|
||||
return node.NextOrientation;
|
||||
return context.NextOrientation;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
NextOrientation = ConnectionType.IsError;
|
||||
context.NextOrientation = ConnectionInvokeType.IsError;
|
||||
RuningException = ex;
|
||||
return ConnectionType.IsError;
|
||||
return ConnectionInvokeType.IsError;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,10 +91,10 @@ namespace Serein.NodeFlow.Model
|
||||
//var falseNodes = FailBranch.Select(item => item.Guid);// 假分支
|
||||
//var upstreamNodes = UpstreamBranch.Select(item => item.Guid);// 上游分支
|
||||
//var errorNodes = ErrorBranch.Select(item => item.Guid);// 异常分支
|
||||
var trueNodes = SuccessorNodes[ConnectionType.IsSucceed].Select(item => item.Guid); // 真分支
|
||||
var falseNodes = SuccessorNodes[ConnectionType.IsFail].Select(item => item.Guid);// 假分支
|
||||
var errorNodes = SuccessorNodes[ConnectionType.IsError].Select(item => item.Guid);// 异常分支
|
||||
var upstreamNodes = SuccessorNodes[ConnectionType.Upstream].Select(item => item.Guid);// 上游分支
|
||||
var trueNodes = SuccessorNodes[ConnectionInvokeType.IsSucceed].Select(item => item.Guid); // 真分支
|
||||
var falseNodes = SuccessorNodes[ConnectionInvokeType.IsFail].Select(item => item.Guid);// 假分支
|
||||
var errorNodes = SuccessorNodes[ConnectionInvokeType.IsError].Select(item => item.Guid);// 异常分支
|
||||
var upstreamNodes = SuccessorNodes[ConnectionInvokeType.Upstream].Select(item => item.Guid);// 上游分支
|
||||
|
||||
// 生成参数列表
|
||||
Parameterdata[] parameterData = GetParameterdatas();
|
||||
|
||||
@@ -76,15 +76,15 @@ namespace Serein.NodeFlow.Model
|
||||
{
|
||||
|
||||
var isPass = SereinConditionParser.To(parameter, Expression);
|
||||
NextOrientation = isPass ? ConnectionType.IsSucceed : ConnectionType.IsFail;
|
||||
context.NextOrientation = isPass ? ConnectionInvokeType.IsSucceed : ConnectionInvokeType.IsFail;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
NextOrientation = ConnectionType.IsError;
|
||||
context.NextOrientation = ConnectionInvokeType.IsError;
|
||||
RuningException = ex;
|
||||
}
|
||||
|
||||
Console.WriteLine($"{result} {Expression} -> " + NextOrientation);
|
||||
Console.WriteLine($"{result} {Expression} -> " + context.NextOrientation);
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,12 +47,12 @@ namespace Serein.NodeFlow.Model
|
||||
result = data;
|
||||
}
|
||||
|
||||
NextOrientation = ConnectionType.IsSucceed;
|
||||
context.NextOrientation = ConnectionInvokeType.IsSucceed;
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
NextOrientation = ConnectionType.IsError;
|
||||
context.NextOrientation = ConnectionInvokeType.IsError;
|
||||
RuningException = ex;
|
||||
return Task.FromResult(data);
|
||||
}
|
||||
|
||||
@@ -42,11 +42,11 @@ namespace Serein.NodeFlow.Model
|
||||
object instance = md.ActingInstance;
|
||||
try
|
||||
{
|
||||
var args = GetParameters(context, this, md);
|
||||
var args = await GetParametersAsync(context, this, md);
|
||||
var result = await dd.InvokeAsync(md.ActingInstance, args);
|
||||
dynamic flipflopContext = result;
|
||||
FlipflopStateType flipflopStateType = flipflopContext.State;
|
||||
NextOrientation = flipflopStateType.ToContentType();
|
||||
context.NextOrientation = flipflopStateType.ToContentType();
|
||||
if (flipflopContext.Type == TriggerType.Overtime)
|
||||
{
|
||||
throw new FlipflopException(base.MethodDetails.MethodName + "触发器超时触发。Guid" + base.Guid);
|
||||
@@ -61,14 +61,14 @@ namespace Serein.NodeFlow.Model
|
||||
throw;
|
||||
}
|
||||
await Console.Out.WriteLineAsync($"触发器[{this.MethodDetails.MethodName}]异常:" + ex);
|
||||
NextOrientation = ConnectionType.None;
|
||||
context.NextOrientation = ConnectionInvokeType.None;
|
||||
RuningException = ex;
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Console.Out.WriteLineAsync($"触发器[{this.MethodDetails.MethodName}]异常:" + ex);
|
||||
NextOrientation = ConnectionType.IsError;
|
||||
context.NextOrientation = ConnectionInvokeType.IsError;
|
||||
RuningException = ex;
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user