From b6ed0b69dcd721e8939f1a5f0ef405a0581e4d4c Mon Sep 17 00:00:00 2001 From: fengjiayi <12821976+ning_xi@user.noreply.gitee.com> Date: Tue, 29 Jul 2025 14:51:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=86=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=99=A8=E7=9A=84=E7=94=9F=E6=88=90=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E3=80=82=20=E4=BF=AE=E5=A4=8D=E4=BA=86Emit=E5=AF=B9?= =?UTF-8?q?=E4=BA=8E=E9=9B=86=E5=90=88=E7=B1=BB=E5=9E=8B=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E5=A7=94=E6=89=98=E6=97=B6=EF=BC=8C=E7=B1=BB=E5=9E=8B=E6=8C=87?= =?UTF-8?q?=E5=AE=9ABug=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Library/Api/IFlowNode.cs | 4 -- Library/Extension/FlowModelExtension.cs | 5 +- Library/FlowNode/DelegateDetails.cs | 4 +- Library/FlowNode/ParameterDetails.cs | 26 ++++++++- Serein.Library.MyGenerator/Attribute.cs | 6 +- .../ParameterDetailsPropertyGenerator.cs | 58 ++++++++++--------- 6 files changed, 62 insertions(+), 41 deletions(-) diff --git a/Library/Api/IFlowNode.cs b/Library/Api/IFlowNode.cs index 8247a2a..69dcef7 100644 --- a/Library/Api/IFlowNode.cs +++ b/Library/Api/IFlowNode.cs @@ -99,10 +99,6 @@ namespace Serein.Library.Api /// 节点创建时的行为 /// void OnCreating(); - /*/// - /// 节点移除时的行为 - /// - void Remove();*/ /// /// 节点保存时如若需要保存自定义数据,可通过该方法进行控制保存逻辑 diff --git a/Library/Extension/FlowModelExtension.cs b/Library/Extension/FlowModelExtension.cs index c630517..983f4a0 100644 --- a/Library/Extension/FlowModelExtension.cs +++ b/Library/Extension/FlowModelExtension.cs @@ -197,9 +197,8 @@ namespace Serein.Library } } - private static ObjectPool> flowStackPool = new ObjectPool>(()=> new Stack()); - //private static ObjectPool> processedNodesPool = new ObjectPool>(()=> new HashSet()); - private static ObjectPool> checkpoints = new ObjectPool>(()=> new HashSet()); + private readonly static ObjectPool> flowStackPool = new ObjectPool>(()=> new Stack()); + private readonly static ObjectPool> checkpoints = new ObjectPool>(()=> new HashSet()); /// /// 开始执行 diff --git a/Library/FlowNode/DelegateDetails.cs b/Library/FlowNode/DelegateDetails.cs index 65e1dbb..a352218 100644 --- a/Library/FlowNode/DelegateDetails.cs +++ b/Library/FlowNode/DelegateDetails.cs @@ -154,13 +154,13 @@ namespace Serein.Library { if (emitType == EmitType.CollectionSetter) { - emitType = EmitType.CollectionSetter; + this.emitType = EmitType.CollectionSetter; collectionSetter = EmitHelper.CreateCollectionSetter(type); } else if (emitType == EmitType.CollectionGetter) { - emitType = EmitType.CollectionGetter; + this.emitType = EmitType.CollectionGetter; collectionGetter = EmitHelper.CreateCollectionGetter(type); } else diff --git a/Library/FlowNode/ParameterDetails.cs b/Library/FlowNode/ParameterDetails.cs index eae280a..056c089 100644 --- a/Library/FlowNode/ParameterDetails.cs +++ b/Library/FlowNode/ParameterDetails.cs @@ -1,6 +1,7 @@ using Serein.Library.Api; using Serein.Library.Utils; using System; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Reflection; using System.Threading; @@ -145,6 +146,8 @@ namespace Serein.Library this.Name = pdInfo.ArgName; } + + /// /// 通过参数信息加载实体,用于加载项目文件、远程连接的场景 /// @@ -160,6 +163,15 @@ namespace Serein.Library IsParams = info.IsParams; } + + partial void OnIsExplicitDataChanged(bool oldValue, bool newValue) + { + if(DataType == typeof(IFlowContext)) + { + + } + } + /// /// 转为描述 /// @@ -209,9 +221,9 @@ namespace Serein.Library return data; // 2. 特定快捷类型 - if (typeof(IFlowEnvironment).IsAssignableFrom(DataType)) return NodeModel.Env; if (typeof(IFlowContext).IsAssignableFrom(DataType)) return context; - if (typeof(IFlowNode).IsAssignableFrom(DataType)) return NodeModel; + //if (typeof(IFlowEnvironment).IsAssignableFrom(DataType)) return NodeModel.Env; + //if (typeof(IFlowNode).IsAssignableFrom(DataType)) return NodeModel; // 3. 显式常量参数 if (IsExplicitData && !DataValue.StartsWith("@", StringComparison.OrdinalIgnoreCase)) @@ -224,7 +236,15 @@ namespace Serein.Library if (ArgDataSourceType == ConnectionArgSourceType.GetPreviousNodeData) { var prevNodeGuid = context.GetPreviousNode(NodeModel.Guid); - inputParameter = prevNodeGuid != null ? context.GetFlowData(prevNodeGuid)?.Value : null; + if(prevNodeGuid is null) + { + inputParameter = null; + } + else + { + var prevNodeData = context.GetFlowData(prevNodeGuid); + inputParameter = prevNodeData.Value; + } } else { diff --git a/Serein.Library.MyGenerator/Attribute.cs b/Serein.Library.MyGenerator/Attribute.cs index 13c260e..0d47c83 100644 --- a/Serein.Library.MyGenerator/Attribute.cs +++ b/Serein.Library.MyGenerator/Attribute.cs @@ -69,16 +69,18 @@ namespace Serein.Library /// 是否禁止参数进行修改(初始化后不能再通过 Setter 修改) /// public bool IsProtection = false; - +/* /// /// 自定义代码(属性变更前) /// + [Obsolete("此属性已经过时,可能在下一个版本中移除", false)] public string CustomCodeAtStart = null; /// /// 自定义代码(属性变更后) /// - public string CustomCodeAtEnd = null; + [Obsolete("此属性已经过时,可能在下一个版本中移除", false)] + public string CustomCodeAtEnd = null;*/ } diff --git a/Serein.Library.MyGenerator/ParameterDetailsPropertyGenerator.cs b/Serein.Library.MyGenerator/ParameterDetailsPropertyGenerator.cs index c28a902..8e550f5 100644 --- a/Serein.Library.MyGenerator/ParameterDetailsPropertyGenerator.cs +++ b/Serein.Library.MyGenerator/ParameterDetailsPropertyGenerator.cs @@ -14,7 +14,6 @@ using System.Threading; namespace Serein.Library.NodeGenerator { - /// /// 一个增量源生成器,用于为带有自定义 MyClassAttribute 特性的类中的字段生成带有自定义 set 行为的属性。 /// @@ -33,7 +32,7 @@ namespace Serein.Library.NodeGenerator /* CreateSyntaxProvider : 第一个参数用于筛选特定语法节点,第二个参数则用于转换筛选出来的节点。 SemanticModel : 通过 语义模型 (SemanticModel) 来解析代码中的符号信息,获取类、方法、属性等更具体的类型和特性信息。例如某个特性属于哪个类型。 - AddSource : 生成器的最终目标是生成代码。使用 AddSource 将生成的代码以字符串形式注入到编译过程当中。通常会通过字符串拼接或 StringBuilder 来构建生成的 C# 代码。 + AddSource : 生成器的最终目标是生成代码。使用 AddSource 将生成的代码以字符串形式注入到编译过程当中。 */ // 通过 SyntaxProvider 查找所有带有任意特性修饰的类声明语法节点 var classDeclarations = context.SyntaxProvider @@ -87,19 +86,6 @@ namespace Serein.Library.NodeGenerator } }); } - private int myProperty; - - public int MyProperty { get => myProperty; set - { - if(myProperty == null) - { - - myProperty = value; - } - } } - - - /// /// 为给定的类生成带有自定义 set 行为的属性。 @@ -163,6 +149,11 @@ namespace Serein.Library.NodeGenerator //sb.AppendLine(leadingTrivia); sb.AppendLine($" partial void On{propertyName}Changed({fieldType} oldValue, {fieldType} newValue);"); sb.AppendLine($" partial void On{propertyName}Changed({fieldType} value);"); + if (isProtection) + { + sb.AppendLine($" private bool __{propertyName}ProtectionField = false;"); + } + sb.AppendLine(); // 生成 getter / setter sb.AppendLine($" /// "); @@ -172,10 +163,22 @@ namespace Serein.Library.NodeGenerator sb.AppendLine($" get => {fieldName};"); // getter方法 sb.AppendLine( " set"); sb.AppendLine( " {"); - sb.AppendLine($" if ({fieldName} {(isProtection ? "== default" : "!= value")})"); // 非保护的Setter - sb.AppendLine( " {"); - sb.AppendLine($" var __oldValue = {fieldName};"); - sb.AppendLine($" SetProperty<{fieldType}>(ref {fieldName}, value); // 通知UI属性发生改变了"); + //sb.AppendLine($" if ({fieldName} {(isProtection ? "== default" : "!= value")})"); // 非保护的Setter + + sb.AppendLine($" var __oldValue = {fieldName};"); + if (isProtection) + { + sb.AppendLine($" if (!__{propertyName}ProtectionField && SetProperty<{fieldType}>(ref {fieldName}, value))"); // 非保护的Setter + sb.AppendLine($" {{"); + sb.AppendLine($" __{propertyName}ProtectionField = true;"); + } + else + { + sb.AppendLine($" if (SetProperty<{fieldType}>(ref {fieldName}, value))"); // 非保护的Setter + sb.AppendLine($" {{"); + } + + //sb.AppendLine($" SetProperty<{fieldType}>(ref {fieldName}, value); "); sb.AppendLine($" On{propertyName}Changed(value);"); sb.AppendLine($" On{propertyName}Changed(__oldValue, value);"); if (attributeInfo.Search(nameof(PropertyInfo), nameof(PropertyInfo.IsPrint), value => bool.Parse(value))) @@ -240,21 +243,22 @@ namespace Serein.Library.NodeGenerator sb.AppendLine(" /// "); sb.AppendLine(" public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;"); - sb.AppendLine(" protected void SetProperty(ref T storage, T value, [System.Runtime.CompilerServices.CallerMemberName] string propertyName = null) "); + sb.AppendLine(" protected bool SetProperty(ref T storage, T value, [System.Runtime.CompilerServices.CallerMemberName] string propertyName = null) "); sb.AppendLine(" { "); - sb.AppendLine(" //if (Equals(storage, value)) "); - sb.AppendLine(" //{ "); - sb.AppendLine(" // return; "); - sb.AppendLine(" //} "); + sb.AppendLine(" if (Equals(storage, value)) "); + sb.AppendLine(" { "); + sb.AppendLine(" return false; "); + sb.AppendLine(" } "); sb.AppendLine(" "); sb.AppendLine(" storage = value; "); sb.AppendLine(" PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); "); + sb.AppendLine(" return true; "); sb.AppendLine(" } "); - sb.AppendLine(" public void OnPropertyChanged(string propertyName) => "); - sb.AppendLine(" PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); "); + sb.AppendLine(" public void OnPropertyChanged(string propertyName) => "); + sb.AppendLine(" PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); "); + sb.AppendLine(" "); sb.AppendLine(" "); - sb.AppendLine(" "); sb.AppendLine(" "); // 生成变量修改