mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-04-26 17:57:54 +08:00
优化了节点加载逻辑
This commit is contained in:
@@ -13,23 +13,23 @@ namespace Serein.Library
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 将不会继续执行
|
/// 将不会继续执行
|
||||||
/// </summary>
|
/// </summary>
|
||||||
None,
|
None = -1,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 上游分支(执行当前节点前会执行一次上游分支),默认执行。
|
/// 上游分支(执行当前节点前会执行一次上游分支),默认执行。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Upstream,
|
Upstream = 0,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 真分支(表示当前节点顺利完成)
|
/// 真分支(表示当前节点顺利完成)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IsSucceed,
|
IsSucceed = 1,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 假分支(一般用于条件控件,条件为假时才会触发该类型的分支)
|
/// 假分支(一般用于条件控件,条件为假时才会触发该类型的分支)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IsFail,
|
IsFail = 2,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异常发生分支(当前节点对应的方法执行时出现非预期的异常)
|
/// 异常发生分支(当前节点对应的方法执行时出现非预期的异常)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IsError,
|
IsError = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -96,12 +96,17 @@ namespace Serein.Library
|
|||||||
public static NodeInfo ToInfo(this IFlowNode nodeModel)
|
public static NodeInfo ToInfo(this IFlowNode nodeModel)
|
||||||
{
|
{
|
||||||
// if (MethodDetails == null) return null;
|
// if (MethodDetails == null) return null;
|
||||||
var trueNodes = nodeModel.SuccessorNodes[ConnectionInvokeType.IsSucceed].Select(item => item.Guid); // 真分支
|
/*var trueNodes = nodeModel.SuccessorNodes[ConnectionInvokeType.IsSucceed].Select(item => item.Guid); // 真分支
|
||||||
var falseNodes = nodeModel.SuccessorNodes[ConnectionInvokeType.IsFail].Select(item => item.Guid);// 假分支
|
var falseNodes = nodeModel.SuccessorNodes[ConnectionInvokeType.IsFail].Select(item => item.Guid);// 假分支
|
||||||
var errorNodes = nodeModel.SuccessorNodes[ConnectionInvokeType.IsError].Select(item => item.Guid);// 异常分支
|
var errorNodes = nodeModel.SuccessorNodes[ConnectionInvokeType.IsError].Select(item => item.Guid);// 异常分支
|
||||||
var upstreamNodes = nodeModel.SuccessorNodes[ConnectionInvokeType.Upstream].Select(item => item.Guid);// 上游分支
|
var upstreamNodes = nodeModel.SuccessorNodes[ConnectionInvokeType.Upstream].Select(item => item.Guid);// 上游分支*/
|
||||||
|
|
||||||
|
var successorNodes = nodeModel.SuccessorNodes.ToDictionary(kv => kv.Key, kv => kv.Value.Select(item => item.Guid).ToArray()); // 后继分支
|
||||||
|
var previousNodes = nodeModel.PreviousNodes.ToDictionary(kv => kv.Key, kv => kv.Value.Select(item => item.Guid).ToArray()); // 后继分支
|
||||||
|
|
||||||
|
|
||||||
// 生成参数列表
|
// 生成参数列表
|
||||||
ParameterData[] parameterData = nodeModel.SaveParameterInfo();
|
ParameterData[] parameterDatas = nodeModel.SaveParameterInfo();
|
||||||
|
|
||||||
var nodeInfo = new NodeInfo
|
var nodeInfo = new NodeInfo
|
||||||
{
|
{
|
||||||
@@ -112,17 +117,19 @@ namespace Serein.Library
|
|||||||
MethodName = nodeModel.MethodDetails?.MethodName,
|
MethodName = nodeModel.MethodDetails?.MethodName,
|
||||||
Label = nodeModel.MethodDetails?.MethodAnotherName,
|
Label = nodeModel.MethodDetails?.MethodAnotherName,
|
||||||
Type = nodeModel.ControlType.ToString(), //this.GetType().ToString(),
|
Type = nodeModel.ControlType.ToString(), //this.GetType().ToString(),
|
||||||
TrueNodes = trueNodes.ToArray(),
|
/*TrueNodes = trueNodes.ToArray(),
|
||||||
FalseNodes = falseNodes.ToArray(),
|
FalseNodes = falseNodes.ToArray(),
|
||||||
UpstreamNodes = upstreamNodes.ToArray(),
|
UpstreamNodes = upstreamNodes.ToArray(),
|
||||||
ParameterData = parameterData.ToArray(),
|
ErrorNodes = errorNodes.ToArray(),*/
|
||||||
ErrorNodes = errorNodes.ToArray(),
|
ParameterData = parameterDatas,
|
||||||
Position = nodeModel.Position,
|
Position = nodeModel.Position,
|
||||||
IsProtectionParameter = nodeModel.DebugSetting.IsProtectionParameter,
|
IsProtectionParameter = nodeModel.DebugSetting.IsProtectionParameter,
|
||||||
IsInterrupt = nodeModel.DebugSetting.IsInterrupt,
|
IsInterrupt = nodeModel.DebugSetting.IsInterrupt,
|
||||||
IsEnable = nodeModel.DebugSetting.IsEnable,
|
IsEnable = nodeModel.DebugSetting.IsEnable,
|
||||||
ParentNodeGuid = nodeModel.ContainerNode?.Guid,
|
ParentNodeGuid = nodeModel.ContainerNode?.Guid,
|
||||||
ChildNodeGuids = nodeModel.ChildrenNode.Select(item => item.Guid).ToArray(),
|
ChildNodeGuids = nodeModel.ChildrenNode.Select(item => item.Guid).ToArray(),
|
||||||
|
SuccessorNodes = successorNodes,
|
||||||
|
PreviousNodes = previousNodes,
|
||||||
};
|
};
|
||||||
nodeInfo.Position.X = Math.Round(nodeInfo.Position.X, 1);
|
nodeInfo.Position.X = Math.Round(nodeInfo.Position.X, 1);
|
||||||
nodeInfo.Position.Y = Math.Round(nodeInfo.Position.Y, 1);
|
nodeInfo.Position.Y = Math.Round(nodeInfo.Position.Y, 1);
|
||||||
|
|||||||
@@ -148,11 +148,11 @@ namespace Serein.Library
|
|||||||
|
|
||||||
private void Init()
|
private void Init()
|
||||||
{
|
{
|
||||||
PreviousNodes = new Dictionary<ConnectionInvokeType, List<CallNode>>();
|
//PreviousNodes = new Dictionary<ConnectionInvokeType, List<CallNode>>();
|
||||||
SuccessorNodes = new Dictionary<ConnectionInvokeType, List<CallNode>>();
|
SuccessorNodes = new Dictionary<ConnectionInvokeType, List<CallNode>>();
|
||||||
foreach (ConnectionInvokeType ctType in NodeStaticConfig.ConnectionTypes)
|
foreach (ConnectionInvokeType ctType in NodeStaticConfig.ConnectionTypes)
|
||||||
{
|
{
|
||||||
PreviousNodes[ctType] = new List<CallNode>();
|
//PreviousNodes[ctType] = new List<CallNode>();
|
||||||
SuccessorNodes[ctType] = new List<CallNode>();
|
SuccessorNodes[ctType] = new List<CallNode>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,23 +175,48 @@ namespace Serein.Library
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 不同分支的父节点(流程调用)
|
/// 不同分支的父节点(流程调用)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<ConnectionInvokeType, List<CallNode>> PreviousNodes { get; private set; }
|
//public Dictionary<ConnectionInvokeType, List<CallNode>> PreviousNodes { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 不同分支的子节点(流程调用)
|
/// 不同分支的子节点(流程调用)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<ConnectionInvokeType, List<CallNode>> SuccessorNodes { get; private set; }
|
public Dictionary<ConnectionInvokeType, List<CallNode>> SuccessorNodes { get; private set; }
|
||||||
|
public CallNode[][] ChildNodes { get; private set; } = new CallNode[][]
|
||||||
|
{
|
||||||
|
new CallNode[32],
|
||||||
|
new CallNode[32],
|
||||||
|
new CallNode[32],
|
||||||
|
new CallNode[32]
|
||||||
|
};
|
||||||
|
|
||||||
|
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)
|
public CallNode AddChildNodeUpstream(CallNode callNode)
|
||||||
{
|
{
|
||||||
var connectionInvokeType = ConnectionInvokeType.Upstream;
|
var connectionInvokeType = ConnectionInvokeType.Upstream;
|
||||||
|
ChildNodes[(int)connectionInvokeType][UpstreamNodeCount++] = callNode;
|
||||||
SuccessorNodes[connectionInvokeType].Add(callNode);
|
SuccessorNodes[connectionInvokeType].Add(callNode);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CallNode AddChildNodeSucceed(CallNode callNode)
|
public CallNode AddChildNodeSucceed(CallNode callNode)
|
||||||
{
|
{
|
||||||
|
ChildNodes[0][UpstreamNodeCount++] = callNode;
|
||||||
|
|
||||||
var connectionInvokeType = ConnectionInvokeType.IsSucceed;
|
var connectionInvokeType = ConnectionInvokeType.IsSucceed;
|
||||||
|
ChildNodes[(int)connectionInvokeType][IsSuccessorNodeCount++] = callNode;
|
||||||
SuccessorNodes[connectionInvokeType].Add(callNode);
|
SuccessorNodes[connectionInvokeType].Add(callNode);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@@ -199,6 +224,7 @@ namespace Serein.Library
|
|||||||
public CallNode AddChildNodeFail(CallNode callNode)
|
public CallNode AddChildNodeFail(CallNode callNode)
|
||||||
{
|
{
|
||||||
var connectionInvokeType = ConnectionInvokeType.IsFail;
|
var connectionInvokeType = ConnectionInvokeType.IsFail;
|
||||||
|
ChildNodes[(int)connectionInvokeType][IsFailNodeCount++] = callNode;
|
||||||
SuccessorNodes[connectionInvokeType].Add(callNode);
|
SuccessorNodes[connectionInvokeType].Add(callNode);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@@ -206,6 +232,7 @@ namespace Serein.Library
|
|||||||
public CallNode AddChildNodeError(CallNode callNode)
|
public CallNode AddChildNodeError(CallNode callNode)
|
||||||
{
|
{
|
||||||
var connectionInvokeType = ConnectionInvokeType.IsError;
|
var connectionInvokeType = ConnectionInvokeType.IsError;
|
||||||
|
ChildNodes[(int)connectionInvokeType][IsErrorNodeCount++] = callNode;
|
||||||
SuccessorNodes[connectionInvokeType].Add(callNode);
|
SuccessorNodes[connectionInvokeType].Add(callNode);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -241,7 +268,6 @@ namespace Serein.Library
|
|||||||
private static readonly DefaultObjectPool<Stack<CallNode>> _stackPool = new DefaultObjectPool<Stack<CallNode>>(new DefaultPooledObjectPolicy<Stack<CallNode>>());
|
private static readonly DefaultObjectPool<Stack<CallNode>> _stackPool = new DefaultObjectPool<Stack<CallNode>>(new DefaultPooledObjectPolicy<Stack<CallNode>>());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 开始执行
|
/// 开始执行
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -282,7 +308,6 @@ namespace Serein.Library
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 执行完成时更新栈
|
#region 执行完成时更新栈
|
||||||
|
|
||||||
// 首先将指定类别后继分支的所有节点逆序推入栈中
|
// 首先将指定类别后继分支的所有节点逆序推入栈中
|
||||||
var nextNodes = currentNode.SuccessorNodes[context.NextOrientation];
|
var nextNodes = currentNode.SuccessorNodes[context.NextOrientation];
|
||||||
for (int index = nextNodes.Count - 1; index >= 0; index--)
|
for (int index = nextNodes.Count - 1; index >= 0; index--)
|
||||||
@@ -345,11 +370,16 @@ namespace Serein.Library
|
|||||||
{
|
{
|
||||||
private readonly IFlowCallTree flowCallTree;
|
private readonly IFlowCallTree flowCallTree;
|
||||||
private readonly IFlowEnvironment flowEnvironment;
|
private readonly IFlowEnvironment flowEnvironment;
|
||||||
|
public static Serein.Library.Utils.ObjectPool<IDynamicContext> FlowContextPool { get; set; }
|
||||||
|
|
||||||
public LightweightFlowControl(IFlowCallTree flowCallTree, IFlowEnvironment flowEnvironment)
|
public LightweightFlowControl(IFlowCallTree flowCallTree, IFlowEnvironment flowEnvironment)
|
||||||
{
|
{
|
||||||
this.flowCallTree = flowCallTree;
|
this.flowCallTree = flowCallTree;
|
||||||
this.flowEnvironment = flowEnvironment;
|
this.flowEnvironment = flowEnvironment;
|
||||||
|
FlowContextPool = new Utils.ObjectPool<IDynamicContext>(() =>
|
||||||
|
{
|
||||||
|
return new DynamicContext(flowEnvironment);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<object> InvokeAsync(string apiGuid, Dictionary<string, object> dict)
|
public Task<object> InvokeAsync(string apiGuid, Dictionary<string, object> dict)
|
||||||
@@ -368,11 +398,12 @@ namespace Serein.Library
|
|||||||
|
|
||||||
public async Task<TResult> StartFlowAsync<TResult>(string startNodeGuid)
|
public async Task<TResult> StartFlowAsync<TResult>(string startNodeGuid)
|
||||||
{
|
{
|
||||||
IDynamicContext context = new DynamicContext(flowEnvironment);
|
IDynamicContext context = Serein.Library.LightweightFlowControl.FlowContextPool.Allocate();
|
||||||
CancellationTokenSource cts = new CancellationTokenSource();
|
CancellationTokenSource cts = new CancellationTokenSource();
|
||||||
|
FlowResult flowResult;
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
|
||||||
FlowResult flowResult = await BenchmarkHelpers.BenchmarkAsync(async () =>
|
flowResult = await BenchmarkHelpers.BenchmarkAsync(async () =>
|
||||||
{
|
{
|
||||||
var node = flowCallTree.Get(startNodeGuid);
|
var node = flowCallTree.Get(startNodeGuid);
|
||||||
var flowResult = await node.StartFlowAsync(context, cts.Token);
|
var flowResult = await node.StartFlowAsync(context, cts.Token);
|
||||||
@@ -380,7 +411,19 @@ namespace Serein.Library
|
|||||||
});
|
});
|
||||||
#else
|
#else
|
||||||
var node = flowCallTree.Get(startNodeGuid);
|
var node = flowCallTree.Get(startNodeGuid);
|
||||||
FlowResult flowResult = await node.StartFlowAsync(context, cts.Token);
|
try
|
||||||
|
{
|
||||||
|
flowResult = await node.StartFlowAsync(context, cts.Token);
|
||||||
|
}
|
||||||
|
catch (global::System.Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
context.Reset();
|
||||||
|
FlowContextPool.Free(context);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cts?.Cancel();
|
cts?.Cancel();
|
||||||
|
|||||||
@@ -162,6 +162,16 @@ namespace Serein.Library
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 父节点集合
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<ConnectionInvokeType, string[]> PreviousNodes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 后续节点集合
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<ConnectionInvokeType, string[]> SuccessorNodes { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 真分支节点GUID
|
/// 真分支节点GUID
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -189,7 +199,7 @@ namespace Serein.Library
|
|||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 父级节点Guid
|
/// 如果节点放置在了区域控件上,这里会有父级节点Guid
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ParentNodeGuid{ get; set; }
|
public string ParentNodeGuid{ get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Serein.Library.Utils
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 运行指定异步方法多次并输出耗时的最大、最小和平均值。
|
/// 运行指定异步方法多次并输出耗时的最大、最小和平均值。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="func">需要执行的异步方法</param>
|
/// <param name="action">需要执行的方法</param>
|
||||||
/// <param name="count">执行次数,默认10000</param>
|
/// <param name="count">执行次数,默认10000</param>
|
||||||
public static void Benchmark(Action action, int count = 10000)
|
public static void Benchmark(Action action, int count = 10000)
|
||||||
{
|
{
|
||||||
@@ -38,6 +38,7 @@ namespace Serein.Library.Utils
|
|||||||
double avg = total / count;
|
double avg = total / count;
|
||||||
|
|
||||||
Console.WriteLine($"运行 {count} 次:");
|
Console.WriteLine($"运行 {count} 次:");
|
||||||
|
Console.WriteLine($"总耗时 :{total} 毫秒:");
|
||||||
Console.WriteLine($"最大耗时:{max} 毫秒");
|
Console.WriteLine($"最大耗时:{max} 毫秒");
|
||||||
Console.WriteLine($"最小耗时:{min} 毫秒");
|
Console.WriteLine($"最小耗时:{min} 毫秒");
|
||||||
Console.WriteLine($"平均耗时:{avg} 毫秒");
|
Console.WriteLine($"平均耗时:{avg} 毫秒");
|
||||||
|
|||||||
@@ -504,6 +504,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
await Task.Delay(100);
|
await Task.Delay(100);
|
||||||
|
|
||||||
#region 确定节点之间的方法调用关系
|
#region 确定节点之间的方法调用关系
|
||||||
foreach (var nodeInfo in nodeInfos)
|
foreach (var nodeInfo in nodeInfos)
|
||||||
{
|
{
|
||||||
@@ -513,14 +514,13 @@ namespace Serein.NodeFlow.Env
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fromNodeModel is null) continue;
|
if (fromNodeModel is null) continue;
|
||||||
List<(ConnectionInvokeType connectionType, string[] guids)> allToNodes = [(ConnectionInvokeType.IsSucceed,nodeInfo.TrueNodes),
|
foreach (var kvp in nodeInfo.SuccessorNodes)
|
||||||
(ConnectionInvokeType.IsFail, nodeInfo.FalseNodes),
|
|
||||||
(ConnectionInvokeType.IsError, nodeInfo.ErrorNodes),
|
|
||||||
(ConnectionInvokeType.Upstream, nodeInfo.UpstreamNodes)];
|
|
||||||
foreach ((ConnectionInvokeType connectionType, string[] toNodeGuids) item in allToNodes)
|
|
||||||
{
|
{
|
||||||
|
var type = kvp.Key;
|
||||||
|
var nodes = kvp.Value;
|
||||||
|
if (nodes.Length == 0) continue;
|
||||||
// 遍历当前类型分支的节点(确认连接关系)
|
// 遍历当前类型分支的节点(确认连接关系)
|
||||||
foreach (var toNodeGuid in item.toNodeGuids)
|
foreach (var toNodeGuid in nodes)
|
||||||
{
|
{
|
||||||
if (!TryGetNodeModel(toNodeGuid, out var toNodeModel))
|
if (!TryGetNodeModel(toNodeGuid, out var toNodeModel))
|
||||||
{
|
{
|
||||||
@@ -531,17 +531,76 @@ namespace Serein.NodeFlow.Env
|
|||||||
// 防御性代码,加载正常保存的项目文件不会进入这里
|
// 防御性代码,加载正常保存的项目文件不会进入这里
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (fromNodeModel.SuccessorNodes[type].Contains(toNodeModel) || toNodeModel.PreviousNodes[type].Contains(fromNodeModel))
|
||||||
ConnectInvokeNode(canvasGuid, fromNodeModel.Guid, toNodeModel.Guid, JunctionType.NextStep, JunctionType.Execute, item.connectionType);
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ConnectInvokeNode(canvasGuid, fromNodeModel.Guid, toNodeModel.Guid, JunctionType.NextStep, JunctionType.Execute, type);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var nodeInfo in nodeInfos)
|
||||||
|
{
|
||||||
|
var canvasGuid = nodeInfo.CanvasGuid;
|
||||||
|
if (!TryGetNodeModel(nodeInfo.Guid, out var toNodeModel))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (toNodeModel is null) continue;
|
||||||
|
foreach (var kvp in nodeInfo.PreviousNodes)
|
||||||
|
{
|
||||||
|
var type = kvp.Key;
|
||||||
|
var nodes = kvp.Value;
|
||||||
|
if (nodes.Length == 0) continue;
|
||||||
|
// 遍历当前类型分支的节点(确认连接关系)
|
||||||
|
foreach (var toNodeGuid in nodes)
|
||||||
|
{
|
||||||
|
if (!TryGetNodeModel(toNodeGuid, out var fromNodeModel))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (toNodeModel is null)
|
||||||
|
{
|
||||||
|
// 防御性代码,加载正常保存的项目文件不会进入这里
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (fromNodeModel.SuccessorNodes[type].Contains(toNodeModel) || toNodeModel.PreviousNodes[type].Contains(fromNodeModel))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ConnectInvokeNode(canvasGuid, fromNodeModel.Guid, toNodeModel.Guid, JunctionType.NextStep, JunctionType.Execute, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 确定节点之间的参数调用关系
|
#region 确定节点之间的参数调用关系
|
||||||
var nodeModels = flowModelService.GetAllNodeModel();
|
foreach (var nodeInfo in nodeInfos)
|
||||||
|
{
|
||||||
|
var pdInfos = nodeInfo.ParameterData;
|
||||||
|
var toNodeGuid = nodeInfo.Guid;
|
||||||
|
for (global::System.Int32 index = 0; index < pdInfos.Length; index++)
|
||||||
|
{
|
||||||
|
var pdInfo = pdInfos[index];
|
||||||
|
var fromNodeGuid = pdInfo.SourceNodeGuid;
|
||||||
|
if (!string.IsNullOrWhiteSpace(fromNodeGuid) && flowModelService.TryGetCanvasModel(fromNodeGuid,out var fromNode))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var type = EnumHelper.ConvertEnum<ConnectionArgSourceType>(pdInfo.SourceType);
|
||||||
|
var canvasGuid = nodeInfo.CanvasGuid;
|
||||||
|
ConnectArgSourceNode(canvasGuid, fromNodeGuid, toNodeGuid, JunctionType.ReturnData, JunctionType.ArgData, type,index);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* var nodeModels = flowModelService.GetAllNodeModel();
|
||||||
foreach (var toNode in nodeModels)
|
foreach (var toNode in nodeModels)
|
||||||
{
|
{
|
||||||
var canvasGuid = toNode.CanvasDetails.Guid;
|
var canvasGuid = toNode.CanvasDetails.Guid;
|
||||||
@@ -555,10 +614,16 @@ namespace Serein.NodeFlow.Env
|
|||||||
if (!string.IsNullOrEmpty(pd.ArgDataSourceNodeGuid)
|
if (!string.IsNullOrEmpty(pd.ArgDataSourceNodeGuid)
|
||||||
&& TryGetNodeModel(pd.ArgDataSourceNodeGuid, out var fromNode))
|
&& TryGetNodeModel(pd.ArgDataSourceNodeGuid, out var fromNode))
|
||||||
{
|
{
|
||||||
|
*//*if (fromNode.NeedResultNodes[pd.ArgDataSourceType].Contains(toNode)
|
||||||
|
&& pd.ArgDataSourceNodeGuid == fromNode.Guid
|
||||||
|
&& )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}*//*
|
||||||
ConnectArgSourceNode(canvasGuid, fromNode.Guid, toNode.Guid, JunctionType.ReturnData, JunctionType.ArgData, pd.ArgDataSourceType, pd.Index);
|
ConnectArgSourceNode(canvasGuid, fromNode.Guid, toNode.Guid, JunctionType.ReturnData, JunctionType.ArgData, pd.ArgDataSourceType, pd.Index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -627,7 +627,7 @@ namespace Serein.NodeFlow.Services
|
|||||||
|
|
||||||
// 初始化 Get 函数
|
// 初始化 Get 函数
|
||||||
var nodeIndexName = "node_index";
|
var nodeIndexName = "node_index";
|
||||||
sb.AppendCode(2, $" [MethodImpl(MethodImplOptions.AggressiveInlining)]"); // 内联优化
|
//sb.AppendCode(2, $" [MethodImpl(MethodImplOptions.AggressiveInlining)]"); // 内联优化
|
||||||
sb.AppendCode(2, $"public global::Serein.Library.CallNode {nameof(IFlowCallTree.Get)}( global::System.String key)");
|
sb.AppendCode(2, $"public global::Serein.Library.CallNode {nameof(IFlowCallTree.Get)}( global::System.String key)");
|
||||||
sb.AppendCode(2, $"{{");
|
sb.AppendCode(2, $"{{");
|
||||||
sb.AppendCode(3, $"global::System.Int32 {nodeIndexName};");
|
sb.AppendCode(3, $"global::System.Int32 {nodeIndexName};");
|
||||||
@@ -703,7 +703,6 @@ namespace Serein.NodeFlow.Services
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void GenerateFlowApi_ApiParamClass(StringBuilder sb)
|
private void GenerateFlowApi_ApiParamClass(StringBuilder sb)
|
||||||
{
|
{
|
||||||
var infos = flowApiMethodInfos.Values.ToArray();
|
var infos = flowApiMethodInfos.Values.ToArray();
|
||||||
@@ -887,6 +886,7 @@ namespace Serein.NodeFlow.Services
|
|||||||
var contextImpleFullName = $"global::{typeof(DynamicContext).FullName}";
|
var contextImpleFullName = $"global::{typeof(DynamicContext).FullName}";
|
||||||
var tokenSourceFullName = $"global::{typeof(CancellationTokenSource).FullName}";
|
var tokenSourceFullName = $"global::{typeof(CancellationTokenSource).FullName}";
|
||||||
var tokenFullName = $"global::{typeof(CancellationToken).FullName}";
|
var tokenFullName = $"global::{typeof(CancellationToken).FullName}";
|
||||||
|
var flowContextPoolName = $"global::{typeof(LightweightFlowControl).FullName}";
|
||||||
string flowEnvironment = nameof(flowEnvironment);
|
string flowEnvironment = nameof(flowEnvironment);
|
||||||
string flowContext = nameof(flowContext);
|
string flowContext = nameof(flowContext);
|
||||||
string token = nameof(token);
|
string token = nameof(token);
|
||||||
@@ -902,11 +902,22 @@ namespace Serein.NodeFlow.Services
|
|||||||
var invokeParamSignature = string.Join(", ", ParamInfos.Select(p => p.ParamName));
|
var invokeParamSignature = string.Join(", ", ParamInfos.Select(p => p.ParamName));
|
||||||
sb.AppendCode(2, $"public async {returnTypeContext} {ApiMethodName}({paramSignature})");
|
sb.AppendCode(2, $"public async {returnTypeContext} {ApiMethodName}({paramSignature})");
|
||||||
sb.AppendCode(2, $"{{");
|
sb.AppendCode(2, $"{{");
|
||||||
sb.AppendCode(3, $"{contextApiFullName} {flowContext} = new {contextImpleFullName}({flowEnvironment}); // 创建上下文");
|
sb.AppendCode(3, $"{contextApiFullName} {flowContext} = {flowContextPoolName}.{nameof(LightweightFlowControl.FlowContextPool)}.{nameof(LightweightFlowControl.FlowContextPool.Allocate)}(); // 从对象池获取一个上下文");
|
||||||
sb.AppendCode(3, $"{tokenSourceFullName} cts = new {tokenSourceFullName}(); // 创建取消令牌");
|
sb.AppendCode(3, $"{tokenSourceFullName} cts = new {tokenSourceFullName}(); // 创建取消令牌");
|
||||||
sb.AppendCode(3, $"await {ApiMethodName}({flowContext}, cts.Token, {invokeParamSignature}); // 调用目标方法");
|
sb.AppendCode(3, $"try");
|
||||||
sb.AppendCode(3, $"{flowContext}.{nameof(IDynamicContext.Reset)}(); ");
|
sb.AppendCode(3, $"{{");
|
||||||
sb.AppendCode(3, $"cts.{nameof(CancellationTokenSource.Dispose)}(); ");
|
sb.AppendCode(4, $"await {ApiMethodName}({flowContext}, cts.Token, {invokeParamSignature}); // 调用目标方法");
|
||||||
|
sb.AppendCode(3, $"}}");
|
||||||
|
sb.AppendCode(3, $"catch (Exception)");
|
||||||
|
sb.AppendCode(3, $"{{");
|
||||||
|
sb.AppendCode(4, $"throw;");
|
||||||
|
sb.AppendCode(3, $"}}");
|
||||||
|
sb.AppendCode(3, $"finally");
|
||||||
|
sb.AppendCode(3, $"{{");
|
||||||
|
sb.AppendCode(4, $"{flowContext}.{nameof(IDynamicContext.Reset)}(); ");
|
||||||
|
sb.AppendCode(4, $"cts.{nameof(CancellationTokenSource.Dispose)}(); ");
|
||||||
|
sb.AppendCode(4, $"{flowContextPoolName}.{nameof(LightweightFlowControl.FlowContextPool)}.{nameof(LightweightFlowControl.FlowContextPool.Free)}({flowContext}); // 释放上下文");
|
||||||
|
sb.AppendCode(3, $"}}");
|
||||||
sb.AppendCode(2, $"}}");
|
sb.AppendCode(2, $"}}");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
@@ -916,9 +927,20 @@ namespace Serein.NodeFlow.Services
|
|||||||
var invokeParamSignature = string.Join(", ", ParamInfos.Select(p => p.ParamName));
|
var invokeParamSignature = string.Join(", ", ParamInfos.Select(p => p.ParamName));
|
||||||
sb.AppendCode(2, $"public async {returnTypeContext} {ApiMethodName}({tokenFullName} {token}, {paramSignature})");
|
sb.AppendCode(2, $"public async {returnTypeContext} {ApiMethodName}({tokenFullName} {token}, {paramSignature})");
|
||||||
sb.AppendCode(2, $"{{");
|
sb.AppendCode(2, $"{{");
|
||||||
sb.AppendCode(3, $"{contextApiFullName} {flowContext} = new {contextImpleFullName}({flowEnvironment}); // 创建上下文");
|
sb.AppendCode(3, $"{contextApiFullName} {flowContext} = {flowContextPoolName}.{nameof(LightweightFlowControl.FlowContextPool)}.{nameof(LightweightFlowControl.FlowContextPool.Allocate)}(); // 从对象池获取一个上下文");
|
||||||
sb.AppendCode(3, $"await {ApiMethodName}({flowContext}, {token}, {invokeParamSignature}); // 调用目标方法");
|
sb.AppendCode(3, $"try");
|
||||||
sb.AppendCode(3, $"{flowContext}.{nameof(IDynamicContext.Reset)}(); ");
|
sb.AppendCode(3, $"{{");
|
||||||
|
sb.AppendCode(4, $"await {ApiMethodName}({flowContext}, {token}, {invokeParamSignature}); // 调用目标方法");
|
||||||
|
sb.AppendCode(4, $"{flowContext}.{nameof(IDynamicContext.Reset)}(); ");
|
||||||
|
sb.AppendCode(3, $"}}");
|
||||||
|
sb.AppendCode(3, $"catch (Exception)");
|
||||||
|
sb.AppendCode(3, $"{{");
|
||||||
|
sb.AppendCode(4, $"throw;");
|
||||||
|
sb.AppendCode(3, $"}}");
|
||||||
|
sb.AppendCode(3, $"finally");
|
||||||
|
sb.AppendCode(3, $"{{");
|
||||||
|
sb.AppendCode(4, $"{flowContextPoolName}.{nameof(LightweightFlowControl.FlowContextPool)}.{nameof(LightweightFlowControl.FlowContextPool.Free)}({flowContext}); // 释放上下文");
|
||||||
|
sb.AppendCode(3, $"}}");
|
||||||
sb.AppendCode(2, $"}}");
|
sb.AppendCode(2, $"}}");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
@@ -930,21 +952,28 @@ namespace Serein.NodeFlow.Services
|
|||||||
|
|
||||||
sb.AppendCode(2, $"public async {returnTypeContext} {ApiMethodName}({contextApiFullName} {flowContext}, {tokenFullName} token, {paramSignature})");
|
sb.AppendCode(2, $"public async {returnTypeContext} {ApiMethodName}({contextApiFullName} {flowContext}, {tokenFullName} token, {paramSignature})");
|
||||||
sb.AppendCode(2, $"{{");
|
sb.AppendCode(2, $"{{");
|
||||||
sb.AppendCode(3, $"token.ThrowIfCancellationRequested(); // 检查任务是否取消");
|
sb.AppendCode(3, $"token.ThrowIfCancellationRequested(); // 检查任务是否取消");
|
||||||
// 生成参数类实例化代码
|
sb.AppendCode(3, $"try");
|
||||||
sb.AppendCode(3, $"global::{ParamTypeName} data = new global::{ParamTypeName}");
|
sb.AppendCode(3, $"{{");
|
||||||
sb.AppendCode(3, $"{{");
|
sb.AppendCode(3, $"global::{ParamTypeName} data = {ObjPoolName}.Get(); // 从对象池获取一个对象");
|
||||||
for (int index = 0; index < ParamInfos.Count; index++)
|
for (int index = 0; index < ParamInfos.Count; index++)
|
||||||
{
|
{
|
||||||
ParamInfo? info = ParamInfos[index];
|
ParamInfo? info = ParamInfos[index];
|
||||||
sb.AppendCode(4, $"{info.ParamName.ToPascalCase()} = {info.ParamName}; // [{index}] {info.Comments}");
|
sb.AppendCode(4, $"data.{info.ParamName.ToPascalCase()} = {info.ParamName}; // [{index}] {info.Comments}");
|
||||||
}
|
}
|
||||||
sb.AppendCode(3, $"}}");
|
sb.AppendCode(3, $"{flowContext}.{nameof(IDynamicContext.AddOrUpdate)}(\"{ApiMethodName}\", data);");
|
||||||
|
sb.AppendCode(3, $"{flowContext}.{nameof(IDynamicContext.SetPreviousNode)}(\"{NodeModel.TargetNode.Guid}\", \"{ApiMethodName}\");");
|
||||||
sb.AppendCode(3, $"{flowContext}.{nameof(IDynamicContext.AddOrUpdate)}(\"{ApiMethodName}\", data);");
|
sb.AppendCode(3, $"global::{typeof(CallNode).FullName} node = Get(\"{NodeModel.Guid}\");");
|
||||||
sb.AppendCode(3, $"{flowContext}.{nameof(IDynamicContext.SetPreviousNode)}(\"{NodeModel.Guid}\", \"{ApiMethodName}\");");
|
sb.AppendCode(3, $"await node.{nameof(CallNode.StartFlowAsync)}({flowContext}, {token}); // 调用目标方法");
|
||||||
sb.AppendCode(3, $"global::{typeof(CallNode).FullName} node = Get(\"{NodeModel.Guid}\");");
|
sb.AppendCode(3, $"}}");
|
||||||
sb.AppendCode(3, $"await node.{nameof(CallNode.StartFlowAsync)}({flowContext}, {token}); // 调用目标方法");
|
sb.AppendCode(3, $"catch (Exception)");
|
||||||
|
sb.AppendCode(3, $"{{");
|
||||||
|
sb.AppendCode(4, $"throw;");
|
||||||
|
sb.AppendCode(3, $"}}");
|
||||||
|
sb.AppendCode(3, $"finally");
|
||||||
|
sb.AppendCode(3, $"{{");
|
||||||
|
sb.AppendCode(4, $"{flowContextPoolName}.{nameof(LightweightFlowControl.FlowContextPool)}.{nameof(LightweightFlowControl.FlowContextPool.Free)}({flowContext}); // 释放上下文");
|
||||||
|
sb.AppendCode(3, $"}}");
|
||||||
sb.AppendCode(2, $"}}");
|
sb.AppendCode(2, $"}}");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
@@ -954,16 +983,29 @@ namespace Serein.NodeFlow.Services
|
|||||||
string flowResult = nameof(flowResult);
|
string flowResult = nameof(flowResult);
|
||||||
if (type == ParamType.Defute)
|
if (type == ParamType.Defute)
|
||||||
{
|
{
|
||||||
|
//sb.AppendCode(3, $"{contextApiFullName} {flowContext} = new {contextImpleFullName}({flowEnvironment}); // 创建上下文");
|
||||||
|
|
||||||
var paramSignature = string.Join(", ", ParamInfos.Select(p => $"global::{p.Type.FullName} {p.ParamName}"));
|
var paramSignature = string.Join(", ", ParamInfos.Select(p => $"global::{p.Type.FullName} {p.ParamName}"));
|
||||||
var invokeParamSignature = string.Join(", ", ParamInfos.Select(p => p.ParamName));
|
var invokeParamSignature = string.Join(", ", ParamInfos.Select(p => p.ParamName));
|
||||||
sb.AppendCode(2, $"public async {returnTypeContext} {ApiMethodName}({paramSignature})");
|
sb.AppendCode(2, $"public async {returnTypeContext} {ApiMethodName}({paramSignature})");
|
||||||
sb.AppendCode(2, $"{{");
|
sb.AppendCode(2, $"{{");
|
||||||
sb.AppendCode(3, $"{contextApiFullName} {flowContext} = new {contextImpleFullName}({flowEnvironment}); // 创建上下文");
|
sb.AppendCode(3, $"{contextApiFullName} {flowContext} = {flowContextPoolName}.{nameof(LightweightFlowControl.FlowContextPool)}.{nameof(LightweightFlowControl.FlowContextPool.Allocate)}(); // 从对象池获取一个上下文");
|
||||||
sb.AppendCode(3, $"{tokenSourceFullName} cts = new {tokenSourceFullName}(); // 创建取消令牌");
|
sb.AppendCode(3, $"{tokenSourceFullName} cts = new {tokenSourceFullName}(); // 创建取消令牌");
|
||||||
sb.AppendCode(3, $"{ReturnType.FullName} {flowResult} = await {ApiMethodName}({flowContext}, cts.{nameof(CancellationTokenSource.Token)}, {invokeParamSignature}); // 调用目标方法");
|
sb.AppendCode(3, $"try");
|
||||||
sb.AppendCode(3, $"{flowContext}.{nameof(IDynamicContext.Reset)}(); ");
|
sb.AppendCode(3, $"{{");
|
||||||
sb.AppendCode(3, $"cts.{nameof(CancellationTokenSource.Dispose)}(); ");
|
sb.AppendCode(4, $"{ReturnType.FullName} {flowResult} = await {ApiMethodName}({flowContext}, cts.{nameof(CancellationTokenSource.Token)}, {invokeParamSignature}); // 调用目标方法");
|
||||||
sb.AppendCode(3, $"return {flowResult};");
|
sb.AppendCode(4, $"return {flowResult};");
|
||||||
|
sb.AppendCode(3, $"}}");
|
||||||
|
sb.AppendCode(3, $"catch (Exception)");
|
||||||
|
sb.AppendCode(3, $"{{");
|
||||||
|
sb.AppendCode(4, $"throw;");
|
||||||
|
sb.AppendCode(3, $"}}");
|
||||||
|
sb.AppendCode(3, $"finally");
|
||||||
|
sb.AppendCode(3, $"{{");
|
||||||
|
sb.AppendCode(4, $"{flowContext}.{nameof(IDynamicContext.Reset)}(); ");
|
||||||
|
sb.AppendCode(4, $"cts.{nameof(CancellationTokenSource.Dispose)}(); ");
|
||||||
|
sb.AppendCode(4, $"{flowContextPoolName}.{nameof(LightweightFlowControl.FlowContextPool)}.{nameof(LightweightFlowControl.FlowContextPool.Free)}({flowContext}); // 释放上下文");
|
||||||
|
sb.AppendCode(3, $"}}");
|
||||||
sb.AppendCode(2, $"}}");
|
sb.AppendCode(2, $"}}");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
@@ -973,52 +1015,50 @@ namespace Serein.NodeFlow.Services
|
|||||||
var invokeParamSignature = string.Join(", ", ParamInfos.Select(p => p.ParamName));
|
var invokeParamSignature = string.Join(", ", ParamInfos.Select(p => p.ParamName));
|
||||||
sb.AppendCode(2, $"public async {returnTypeContext} {ApiMethodName}({tokenFullName} {token}, {paramSignature})");
|
sb.AppendCode(2, $"public async {returnTypeContext} {ApiMethodName}({tokenFullName} {token}, {paramSignature})");
|
||||||
sb.AppendCode(2, $"{{");
|
sb.AppendCode(2, $"{{");
|
||||||
sb.AppendCode(3, $"{contextApiFullName} {flowContext} = new {contextImpleFullName}({flowEnvironment}); // 创建上下文");
|
sb.AppendCode(3, $"{contextApiFullName} {flowContext} = {flowContextPoolName}.{nameof(LightweightFlowControl.FlowContextPool)}.{nameof(LightweightFlowControl.FlowContextPool.Allocate)}(); // 从对象池获取一个上下文");
|
||||||
sb.AppendCode(3, $"{ReturnType.FullName} {flowResult} = await {ApiMethodName}({flowContext}, {token}, {invokeParamSignature}); // 调用目标方法");
|
sb.AppendCode(3, $"try");
|
||||||
sb.AppendCode(3, $"{flowContext}.{nameof(IDynamicContext.Reset)}(); ");
|
sb.AppendCode(3, $"{{");
|
||||||
sb.AppendCode(3, $"return {flowResult};");
|
sb.AppendCode(4, $"{ReturnType.FullName} {flowResult} = await {ApiMethodName}({flowContext}, {token}, {invokeParamSignature}); // 调用目标方法");
|
||||||
|
sb.AppendCode(4, $"return {flowResult};");
|
||||||
|
sb.AppendCode(3, $"}}");
|
||||||
|
sb.AppendCode(3, $"catch (Exception)");
|
||||||
|
sb.AppendCode(3, $"{{");
|
||||||
|
sb.AppendCode(4, $"throw;");
|
||||||
|
sb.AppendCode(3, $"}}");
|
||||||
|
sb.AppendCode(3, $"finally");
|
||||||
|
sb.AppendCode(3, $"{{");
|
||||||
|
sb.AppendCode(4, $"{flowContext}.{nameof(IDynamicContext.Reset)}(); ");
|
||||||
|
sb.AppendCode(4, $"{flowContextPoolName}.{nameof(LightweightFlowControl.FlowContextPool)}.{nameof(LightweightFlowControl.FlowContextPool.Free)}({flowContext}); // 释放上下文");
|
||||||
|
sb.AppendCode(3, $"}}");
|
||||||
sb.AppendCode(2, $"}}");
|
sb.AppendCode(2, $"}}");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
else if (type == ParamType.HasContextAndToken)
|
else if (type == ParamType.HasContextAndToken)
|
||||||
{
|
{
|
||||||
var paramSignature = string.Join(", ", ParamInfos.Select(p => $"global::{p.Type.FullName} {p.ParamName}"));
|
var paramSignature = string.Join(", ", ParamInfos.Select(p => $"global::{p.Type.FullName} {p.ParamName}"));
|
||||||
var invokeParamSignature = string.Join(", ", ParamInfos.Select(p => p.ParamName));
|
var invokeParamSignature = string.Join(", ", ParamInfos.Select(p => p.ParamName));
|
||||||
sb.AppendCode(2, $"public async {returnTypeContext} {ApiMethodName}({contextApiFullName} {flowContext}, {tokenFullName} token, {paramSignature})");
|
sb.AppendCode(2, $"public async {returnTypeContext} {ApiMethodName}({contextApiFullName} {flowContext}, {tokenFullName} token, {paramSignature})");
|
||||||
sb.AppendCode(2, $"{{");
|
sb.AppendCode(2, $"{{");
|
||||||
sb.AppendCode(3, $"token.ThrowIfCancellationRequested(); // 检查任务是否取消");
|
sb.AppendCode(3, $"token.ThrowIfCancellationRequested(); // 检查任务是否取消");
|
||||||
// 生成参数类实例化代码
|
sb.AppendCode(3, $"global::{ParamTypeName} data = {ObjPoolName}.Get(); // 从对象池获取一个对象");
|
||||||
/*sb.AppendCode(3, $"global::{ParamTypeName} data = new global::{ParamTypeName}");
|
|
||||||
sb.AppendCode(3, $"{{");
|
|
||||||
for (int index = 0; index < ParamInfos.Count; index++)
|
for (int index = 0; index < ParamInfos.Count; index++)
|
||||||
{
|
{
|
||||||
ParamInfo? info = ParamInfos[index];
|
ParamInfo? info = ParamInfos[index];
|
||||||
sb.AppendCode(4, $"{info.ParamName.ToPascalCase()} = {info.ParamName}; // [{index}] {info.Comments}");
|
sb.AppendCode(4, $"data.{info.ParamName.ToPascalCase()} = {info.ParamName}; // [{index}] {info.Comments}"); // 进行赋值
|
||||||
}
|
}
|
||||||
sb.AppendCode(3, $"}}");*/
|
sb.AppendCode(3, $"{flowContext}.{nameof(IDynamicContext.AddOrUpdate)}(\"{ApiMethodName}\", data);");
|
||||||
sb.AppendCode(3, $"global::{ParamTypeName} data = {ObjPoolName}.Get(); // 从对象池获取一个对象");
|
sb.AppendCode(3, $"{flowContext}.{nameof(IDynamicContext.SetPreviousNode)}(\"{NodeModel.Guid}\", \"{ApiMethodName}\");");
|
||||||
for (int index = 0; index < ParamInfos.Count; index++)
|
sb.AppendCode(3, $"global::{typeof(CallNode).FullName} node = Get(\"{NodeModel.Guid}\");");
|
||||||
{
|
sb.AppendCode(3, $"global::{typeof(FlowResult).FullName} {flowResult} = await node.{nameof(CallNode.StartFlowAsync)}({flowContext}, {token}); // 调用目标方法");
|
||||||
ParamInfo? info = ParamInfos[index];
|
sb.AppendCode(3, $"if ({flowResult}.{nameof(FlowResult.Value)} is global::{ReturnType.FullName} result)");
|
||||||
sb.AppendCode(4, $"data.{info.ParamName.ToPascalCase()} = {info.ParamName}; // [{index}] {info.Comments}");
|
sb.AppendCode(3, $"{{");
|
||||||
}
|
sb.AppendCode(4, $"return result;");
|
||||||
|
sb.AppendCode(3, $"}}");
|
||||||
sb.AppendCode(3, $"{flowContext}.{nameof(IDynamicContext.AddOrUpdate)}(\"{ApiMethodName}\", data);");
|
sb.AppendCode(3, $"else");
|
||||||
sb.AppendCode(3, $"{flowContext}.{nameof(IDynamicContext.SetPreviousNode)}(\"{NodeModel.Guid}\", \"{ApiMethodName}\");");
|
sb.AppendCode(3, $"{{");
|
||||||
sb.AppendCode(3, $"global::{typeof(CallNode).FullName} node = Get(\"{NodeModel.Guid}\");");
|
sb.AppendCode(4, $"throw new ArgumentNullException($\"类型转换失败,{{(flowResult.Value is null ? \"返回数据为 null\" : $\"返回数据与需求类型不匹配,当前返回类型为[{{flowResult.Value.GetType().FullName}}。\")}}\");");
|
||||||
sb.AppendCode(3, $"global::{typeof(FlowResult).FullName} {flowResult} = await node.{nameof(CallNode.StartFlowAsync)}({flowContext}, {token}); // 调用目标方法");
|
sb.AppendCode(3, $"}}");
|
||||||
sb.AppendCode(3, $"if ({flowResult}.{nameof(FlowResult.Value)} is global::{ReturnType.FullName} result)");
|
sb.AppendCode(3, $"return {flowResult};");
|
||||||
sb.AppendCode(3, $"{{");
|
|
||||||
sb.AppendCode(4, $"return result;");
|
|
||||||
sb.AppendCode(3, $"}}");
|
|
||||||
sb.AppendCode(3, $"else");
|
|
||||||
sb.AppendCode(3, $"{{");
|
|
||||||
sb.AppendCode(4, $"throw new ArgumentNullException($\"类型转换失败,{{(flowResult.Value is null ? \"返回数据为 null\" : $\"返回数据与需求类型不匹配,当前返回类型为[{{flowResult.Value.GetType().FullName}}。\")}}\");");
|
|
||||||
sb.AppendCode(3, $"}}");
|
|
||||||
sb.AppendCode(3, $"return {flowResult};");
|
|
||||||
sb.AppendCode(2, $"}}");
|
sb.AppendCode(2, $"}}");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
// throw new ArgumentNullException($"类型转换失败,{(flowResult.Value is null ? "返回数据为 null" : $"返回数据与需求类型不匹配,当前返回类型为[{flowResult.Value.GetType().FullName}。")}");
|
// throw new ArgumentNullException($"类型转换失败,{(flowResult.Value is null ? "返回数据为 null" : $"返回数据与需求类型不匹配,当前返回类型为[{flowResult.Value.GetType().FullName}。")}");
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace Serein.Workbench.Converters
|
|||||||
{
|
{
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
Debug.WriteLine($"targetType:{targetType} value:{targetType} parameter:{parameter}");
|
//Debug.WriteLine($"targetType:{targetType} value:{targetType} parameter:{parameter}");
|
||||||
if (value is bool b)
|
if (value is bool b)
|
||||||
{
|
{
|
||||||
return b ? Visibility.Visible : Visibility.Collapsed;
|
return b ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
|||||||
Reference in New Issue
Block a user