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