实现了拖拽式设置方法调用顺序、方法入参参数来源

This commit is contained in:
fengjiayi
2024-10-24 23:32:43 +08:00
parent 0666f0b2c1
commit 6f26d303e4
43 changed files with 2282 additions and 763 deletions

View File

@@ -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>

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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
{

View File

@@ -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));
});

View File

@@ -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--)
{
// 筛选出启用的节点

View File

@@ -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();

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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;
}