From 88de5a21f542c8b7fc410c338e4aa7ed5fae48ed Mon Sep 17 00:00:00 2001
From: fengjiayi <12821976+ning_xi@user.noreply.gitee.com>
Date: Thu, 17 Jul 2025 22:46:40 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BA=86SereinEnv.WriteLine(?=
=?UTF-8?q?Exception,=20InfoClass)=E8=BE=93=E5=87=BA=EF=BC=8C=E5=8F=AF?=
=?UTF-8?q?=E4=BB=A5=E9=80=9A=E8=BF=87=E6=9B=B4=E6=94=B9InfoClass=E6=8E=A7?=
=?UTF-8?q?=E5=88=B6=E6=98=AF=E5=90=A6=E8=BE=93=E5=87=BA=E5=BC=82=E5=B8=B8?=
=?UTF-8?q?=E5=A0=86=E6=A0=88=E4=BF=A1=E6=81=AF=E3=80=82=20=E4=BC=98?=
=?UTF-8?q?=E5=8C=96=E4=BA=86=E6=89=B9=E9=87=8F=E5=8A=A0=E8=BD=BD=E8=8A=82?=
=?UTF-8?q?=E7=82=B9=E6=97=B6=EF=BC=8C=E8=84=9A=E6=9C=AC=E8=8A=82=E7=82=B9?=
=?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=88=86=E6=9E=90=E5=BC=82=E5=B8=B8=E7=9A=84?=
=?UTF-8?q?=E9=97=AE=E9=A2=98=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Library/Network/Http/Router.cs | 2 +-
Library/Network/Http/WebApiServer.cs | 2 +-
Library/Utils/SereinEnv.cs | 11 +++-
NodeFlow/Env/FlowEdit.cs | 54 +++++++++++++++++--
NodeFlow/Env/LocalFlowEnvironment.cs | 4 +-
NodeFlow/Model/Node/SingleScriptNode.cs | 44 ++++++++-------
.../ChangeNodeConnectionOperation.cs | 4 +-
NodeFlow/Services/FlowLibraryService.cs | 2 +-
Serein.Script/SereinScript.cs | 10 +++-
Serein.Script/SereinScriptParser.cs | 6 +++
.../ViewModel/ScriptNodeControlViewModel.cs | 4 +-
Workbench/ViewModels/FlowLibrarysViewModel.cs | 2 +-
Workbench/Views/FlowCanvasView.xaml.cs | 4 +-
13 files changed, 113 insertions(+), 36 deletions(-)
diff --git a/Library/Network/Http/Router.cs b/Library/Network/Http/Router.cs
index c7c4ce8..515189e 100644
--- a/Library/Network/Http/Router.cs
+++ b/Library/Network/Http/Router.cs
@@ -248,7 +248,7 @@ namespace Serein.Library.Web
catch (Exception ex1)
{
- SereinEnv.WriteLine(InfoType.ERROR, ex1.ToString());
+ SereinEnv.WriteLine(ex1);
}
}
diff --git a/Library/Network/Http/WebApiServer.cs b/Library/Network/Http/WebApiServer.cs
index 75b6ce9..24e70ed 100644
--- a/Library/Network/Http/WebApiServer.cs
+++ b/Library/Network/Http/WebApiServer.cs
@@ -135,7 +135,7 @@ namespace Serein.Library.Web
}
catch (Exception ex)
{
- SereinEnv.WriteLine(InfoType.ERROR, ex.ToString());
+ SereinEnv.WriteLine(ex);
}
}
diff --git a/Library/Utils/SereinEnv.cs b/Library/Utils/SereinEnv.cs
index 7b7f2ee..e79c007 100644
--- a/Library/Utils/SereinEnv.cs
+++ b/Library/Utils/SereinEnv.cs
@@ -132,7 +132,16 @@ namespace Serein.Library
///
public static void WriteLine(Exception ex, InfoClass @class = InfoClass.General)
{
- SereinEnv.environment.WriteLine(InfoType.ERROR, ex.ToString(), @class);
+ if(@class == InfoClass.Trivial)
+ {
+
+ SereinEnv.environment.WriteLine(InfoType.ERROR, ex.ToString(), @class);
+ }
+ else
+ {
+
+ SereinEnv.environment.WriteLine(InfoType.ERROR, ex.Message, @class);
+ }
}
diff --git a/NodeFlow/Env/FlowEdit.cs b/NodeFlow/Env/FlowEdit.cs
index 992af53..6b32046 100644
--- a/NodeFlow/Env/FlowEdit.cs
+++ b/NodeFlow/Env/FlowEdit.cs
@@ -393,8 +393,8 @@ namespace Serein.NodeFlow.Env
public async Task LoadNodeInfosAsync(List nodeInfos)
{
#region 从NodeInfo创建NodeModel
- // 流程接口节点最后才创建
-
+
+ // 加载节点,与画布Model进行绑定
async Task AddNodeAsync(NodeInfo nodeInfo, IFlowNode nodeModel)
{
if (!TryGetCanvasModel(nodeInfo.CanvasGuid, out var canvasModel))
@@ -403,6 +403,8 @@ namespace Serein.NodeFlow.Env
}
else
{
+
+
// 节点与画布互相绑定
// 需要在UI线程上进行添加,否则会报 “不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改”异常
nodeModel.CanvasDetails = canvasModel;
@@ -431,7 +433,6 @@ namespace Serein.NodeFlow.Env
}
-
}
@@ -469,6 +470,53 @@ namespace Serein.NodeFlow.Env
}
#endregion
+ #region 脚本节点初始化
+ HashSet nodeIds = new HashSet();
+ void ReloadScript(SingleScriptNode scriptNode)
+ {
+ if (nodeIds.Contains(scriptNode.Guid))
+ {
+ nodeIds.Add(scriptNode.Guid);
+ return;
+ }
+
+ var pds = scriptNode.MethodDetails?.ParameterDetailss;
+ if (pds is null || pds.Length == 0)
+ {
+ nodeIds.Add(scriptNode.Guid);
+ return;
+ }
+
+ foreach (var pd in pds)
+ {
+ //if (pd.ArgDataSourceType == ConnectionArgSourceType.GetPreviousNodeData) continue;
+ var argSourceNodeGuid = pd.ArgDataSourceNodeGuid;
+ if (!string.IsNullOrWhiteSpace(argSourceNodeGuid)
+ && flowModelService.TryGetNodeModel(argSourceNodeGuid, out var flowNode) && flowNode is SingleScriptNode argSourceNode)
+ {
+ ReloadScript(argSourceNode);
+ }
+ }
+
+ scriptNode.ReloadScript(); // 如果是流程接口节点,则需要重新加载脚本
+ nodeIds.Add(scriptNode.Guid);
+ }
+
+ var scriptNodes = nodeInfos.Where(info => info.Type == nameof(NodeControlType.Script))
+ .Select(info => flowModelService.TryGetNodeModel(info.Guid, out var node) ? node : null)
+ .OfType()
+ .ToList();
+
+
+
+ foreach (SingleScriptNode scriptNode in scriptNodes)
+ {
+ ReloadScript(scriptNode);
+ }
+
+
+ #endregion
+
#region 重新放置节点
List needPlaceNodeInfos = [];
diff --git a/NodeFlow/Env/LocalFlowEnvironment.cs b/NodeFlow/Env/LocalFlowEnvironment.cs
index c782538..36f2136 100644
--- a/NodeFlow/Env/LocalFlowEnvironment.cs
+++ b/NodeFlow/Env/LocalFlowEnvironment.cs
@@ -481,7 +481,7 @@ namespace Serein.NodeFlow.Env
}
catch (Exception ex)
{
- SereinEnv.WriteLine(InfoType.ERROR, $"无法加载DLL文件:{ex}");
+ SereinEnv.WriteLine(InfoType.ERROR, $"无法加载DLL文件:{ex.Message}");
}
}
@@ -501,7 +501,7 @@ namespace Serein.NodeFlow.Env
}
catch (Exception ex)
{
- SereinEnv.WriteLine(InfoType.ERROR, $"无法加载DLL文件:{ex}");
+ SereinEnv.WriteLine(InfoType.ERROR, $"无法加载DLL文件:{ex.Message}");
}
}
diff --git a/NodeFlow/Model/Node/SingleScriptNode.cs b/NodeFlow/Model/Node/SingleScriptNode.cs
index e0ecb69..143f1b3 100644
--- a/NodeFlow/Model/Node/SingleScriptNode.cs
+++ b/NodeFlow/Model/Node/SingleScriptNode.cs
@@ -80,23 +80,17 @@ namespace Serein.NodeFlow.Model
///
public override void OnCreating()
{
- /* MethodInfo? method = this.GetType().GetMethod(nameof(GetFlowApi));
- if (method != null)
- {
- ScriptInterpreter.AddFunction(nameof(GetFlowApi), method, () => this); // 挂载获取流程接口
- }*/
-
var md = MethodDetails;
var pd = md.ParameterDetailss ??= new ParameterDetails[1];
md.ParamsArgIndex = 0;
pd[0] = new ParameterDetails
{
Index = 0,
- Name = "object",
+ Name = "string",
IsExplicitData = true,
DataValue = string.Empty,
- DataType = typeof(object),
- ExplicitType = typeof(object),
+ DataType = typeof(string),
+ ExplicitType = typeof(string),
ArgDataSourceNodeGuid = string.Empty,
ArgDataSourceType = ConnectionArgSourceType.GetPreviousNodeData,
NodeModel = this,
@@ -105,7 +99,7 @@ namespace Serein.NodeFlow.Model
IsParams = true,
//Description = "脚本节点入参"
};
- md.ReturnType = typeof(object); // 默认返回 object
+ md.ReturnType = typeof(void); // 默认无返回
}
@@ -136,7 +130,7 @@ namespace Serein.NodeFlow.Model
this.MethodDetails.ParameterDetailss[i].Name = nodeInfo.ParameterData[i].ArgName;
}
- ReloadScript();// 加载时重新解析
+ //ReloadScript();// 加载时重新解析
IsScriptChanged = false; // 重置脚本改变标志
}
@@ -144,7 +138,7 @@ namespace Serein.NodeFlow.Model
///
/// 重新加载脚本代码
///
- public void ReloadScript()
+ public bool ReloadScript()
{
try
{
@@ -158,16 +152,30 @@ namespace Serein.NodeFlow.Model
varNames.Add(pd.Name);
}
- Dictionary dict = MethodDetails.ParameterDetailss.ToDictionary(pd => pd.Name, pd => pd.DataType); // 准备预定义类型
- var returnType = sereinScript.ParserScript(dict, Script); // 开始解析获取程序主节点
+ var argTypes = MethodDetails.ParameterDetailss
+ .Select(pd =>
+ {
+ if (Env.TryGetNodeModel(pd.ArgDataSourceNodeGuid, out var node) &&
+ node.MethodDetails?.ReturnType is not null)
+ {
+ pd.DataType = node.MethodDetails.ReturnType;
+ return (pd.Name, node.MethodDetails.ReturnType);
+ }
+ return default;
+ })
+ .Where(x => x != default)
+ .ToDictionary(x => x.Name, x => x.ReturnType); // 准备预定义类型
+
+
+ var returnType = sereinScript.ParserScript(Script, argTypes); // 开始解析获取程序主节点
MethodDetails.ReturnType = returnType;
-
+ return true;
}
catch (Exception ex)
{
- SereinEnv.WriteLine(InfoType.ERROR, ex.ToString());
-
+ SereinEnv.WriteLine(ex);
+ return false; // 解析失败
}
}
@@ -202,7 +210,7 @@ namespace Serein.NodeFlow.Model
lock (@params) {
if (IsScriptChanged)
{
- ReloadScript();// 每次都重新解析
+ ReloadScript();// 执行时检查是否需要重新解析
IsScriptChanged = false;
context.Env.WriteLine(InfoType.INFO, $"[{Guid}]脚本解析完成");
}
diff --git a/NodeFlow/Model/Operation/ChangeNodeConnectionOperation.cs b/NodeFlow/Model/Operation/ChangeNodeConnectionOperation.cs
index a47f4d1..49a8c77 100644
--- a/NodeFlow/Model/Operation/ChangeNodeConnectionOperation.cs
+++ b/NodeFlow/Model/Operation/ChangeNodeConnectionOperation.cs
@@ -378,7 +378,7 @@ namespace Serein.NodeFlow.Model.Operation
if (FromNode.MethodDetails.ReturnType == typeof(void))
{
- SereinEnv.WriteLine(InfoType.WARN, $"连接失败,节点参数入参不允许接收 void 返回值");
+ SereinEnv.WriteLine(InfoType.WARN, $"连接失败,节点参数入参不允许接收 void 返回值。起始节点[{FromNode.Guid}],目标节点[{FromNode.Guid}]。");
return false;
}
@@ -388,7 +388,7 @@ namespace Serein.NodeFlow.Model.Operation
if (false && string.IsNullOrWhiteSpace(toNodeArgSourceGuid) && flowModelService.ContainsNodeModel(toNodeArgSourceGuid))
{
- SereinEnv.WriteLine(InfoType.WARN, $"连接失败,节点参数入参不允许接收多个节点返回值");
+ SereinEnv.WriteLine(InfoType.WARN, $"连接失败,节点参数入参不允许接收多个节点返回值。起始节点[{FromNode.Guid}],目标节点[{FromNode.Guid}]。");
return false;
}
diff --git a/NodeFlow/Services/FlowLibraryService.cs b/NodeFlow/Services/FlowLibraryService.cs
index c114c1a..a9d4b2f 100644
--- a/NodeFlow/Services/FlowLibraryService.cs
+++ b/NodeFlow/Services/FlowLibraryService.cs
@@ -93,7 +93,7 @@ namespace Serein.NodeFlow.Services
}
catch (Exception ex)
{
- SereinEnv.WriteLine(InfoType.ERROR, $"尝试卸载程序集[{assemblyName}]发生错误:{ex}");
+ SereinEnv.WriteLine(InfoType.ERROR, $"尝试卸载程序集[{assemblyName}]发生错误:{ex.Message}");
return false;
}
diff --git a/Serein.Script/SereinScript.cs b/Serein.Script/SereinScript.cs
index 352c9c4..5bd5644 100644
--- a/Serein.Script/SereinScript.cs
+++ b/Serein.Script/SereinScript.cs
@@ -21,12 +21,18 @@ namespace Serein.Script
private ProgramNode? programNode;
- public Type ParserScript(Dictionary argTypes, string script)
+ ///
+ /// 解析脚本
+ ///
+ /// 脚本
+ /// 挂载的变量
+ ///
+ public Type ParserScript(string script, Dictionary? argTypes = null)
{
SereinScriptParser parser = new SereinScriptParser();
var programNode = parser.Parse(script);
TypeAnalysis.NodeSymbolInfos.Clear(); // 清空符号表
- TypeAnalysis.LoadSymbol(argTypes); // 提前加载脚本节点定义的符号
+ if(argTypes is not null) TypeAnalysis.LoadSymbol(argTypes); // 提前加载脚本节点定义的符号
TypeAnalysis.Analysis(programNode); // 分析节点类型
var returnType = TypeAnalysis.NodeSymbolInfos[programNode]; // 获取返回类型
this.programNode = programNode;
diff --git a/Serein.Script/SereinScriptParser.cs b/Serein.Script/SereinScriptParser.cs
index 86e9a4e..31ea8b1 100644
--- a/Serein.Script/SereinScriptParser.cs
+++ b/Serein.Script/SereinScriptParser.cs
@@ -623,7 +623,13 @@ namespace Serein.Script
NextToken(); // 消耗 ")"
break;
}
+ else if (peekToken.Type == TokenType.BraceLeft)
+ {
+ NextToken(); // 消耗 类型名称
+ break;
+ }
}
+
TypeNode typeNode = new TypeNode(typeName);
typeNode.SetTokenInfo(typeToken);
ObjectInstantiationNode objectInstantiationNode = new ObjectInstantiationNode(typeNode, ctorArguments);
diff --git a/Workbench/Node/ViewModel/ScriptNodeControlViewModel.cs b/Workbench/Node/ViewModel/ScriptNodeControlViewModel.cs
index bc85343..4026e07 100644
--- a/Workbench/Node/ViewModel/ScriptNodeControlViewModel.cs
+++ b/Workbench/Node/ViewModel/ScriptNodeControlViewModel.cs
@@ -37,13 +37,13 @@ namespace Serein.Workbench.Node.ViewModel
}
catch (Exception ex)
{
- SereinEnv.WriteLine(InfoType.ERROR, ex.ToString());
+ SereinEnv.WriteLine(ex);
}
});
CommandLoadScript = new RelayCommand( o =>
{
- NodeModel.ReloadScript();
+ NodeModel.ReloadScript(); // 工作台重新加载脚本
});
}
diff --git a/Workbench/ViewModels/FlowLibrarysViewModel.cs b/Workbench/ViewModels/FlowLibrarysViewModel.cs
index 805f9fc..da30038 100644
--- a/Workbench/ViewModels/FlowLibrarysViewModel.cs
+++ b/Workbench/ViewModels/FlowLibrarysViewModel.cs
@@ -40,7 +40,7 @@ namespace Serein.Workbench.ViewModels
}
catch (Exception ex)
{
- flowEnvironment.WriteLine(Library.InfoType.ERROR, ex.ToString());
+ SereinEnv.WriteLine(ex);
return;
}
}
diff --git a/Workbench/Views/FlowCanvasView.xaml.cs b/Workbench/Views/FlowCanvasView.xaml.cs
index ca61021..5a8d95a 100644
--- a/Workbench/Views/FlowCanvasView.xaml.cs
+++ b/Workbench/Views/FlowCanvasView.xaml.cs
@@ -804,7 +804,7 @@ namespace Serein.Workbench.Views
}
catch (Exception ex)
{
- SereinEnv.WriteLine(InfoType.ERROR, ex.ToString());
+ SereinEnv.WriteLine(ex);
}
}
@@ -1578,7 +1578,7 @@ namespace Serein.Workbench.Views
}
catch (Exception ex)
{
- SereinEnv.WriteLine(InfoType.ERROR, ex.ToString());
+ SereinEnv.WriteLine(ex);
}
}
#endregion