diff --git a/Library/FlowNode/MethodDetails.cs b/Library/FlowNode/MethodDetails.cs index 402490b..dfe09ab 100644 --- a/Library/FlowNode/MethodDetails.cs +++ b/Library/FlowNode/MethodDetails.cs @@ -109,7 +109,7 @@ namespace Serein.Library var newPd = ParameterDetailss[index].CloneOfModel(this.NodeModel); // 复制出属于本身节点的参数描述 newPd.Index = ParameterDetailss.Length; // 更新索引 newPd.IsParams = true; - ParameterDetailss = AddToArray(ParameterDetailss, newPd); // 新增 + ParameterDetailss = ArrayHelper.AddToArray(ParameterDetailss, newPd); // 新增 return true; } else @@ -129,7 +129,7 @@ namespace Serein.Library && index < ParameterDetailss.Length) // 防止下标越界 { ParameterDetailss[index] = null; // 释放对象引用 - var tmp = RemoteToArray(ParameterDetailss, index); // 新增; + var tmp = ArrayHelper.RemoteToArray(ParameterDetailss, index); // 新增; UpdateParamIndex(ref tmp); ParameterDetailss = tmp; // 新增 return true; @@ -155,41 +155,7 @@ namespace Serein.Library } - public static T[] AddToArray(T[] original, T newObject) - { - // 创建一个新数组,比原数组大1 - T[] newArray = new T[original.Length + 1]; - - // 复制原数组的元素 - for (int i = 0; i < original.Length; i++) - { - newArray[i] = original[i]; - } - - // 将新对象放在最后一位 - newArray[newArray.Length - 1] = newObject; - - return newArray; - } - public static T[] RemoteToArray(T[] original, int index) - { - if(index == 0) - { - return new T[0]; - } - // 创建一个新数组,比原数组小1 - T[] newArray = new T[original.Length - 1]; - - for (int i = 0; i < index; i++) - { - newArray[i] = original[i]; - } - for (int i = index; i < newArray.Length; i++) - { - newArray[i] = original[i+1]; - } - return newArray; - } + #endregion diff --git a/Library/FlowNode/NodeModelBaseFunc.cs b/Library/FlowNode/NodeModelBaseFunc.cs index db95286..7422210 100644 --- a/Library/FlowNode/NodeModelBaseFunc.cs +++ b/Library/FlowNode/NodeModelBaseFunc.cs @@ -102,15 +102,36 @@ namespace Serein.Library } else { + var md = this.MethodDetails; // 当前节点的方法说明 + var pds = md.ParameterDetailss; // 当前节点的入参描述数组 + if (nodeInfo.ParameterData.Length > pds.Length && md.HasParamsArg) + { + // 保存的参数信息项数量大于方法本身的方法入参数量(可能存在可变入参) + var length = nodeInfo.ParameterData.Length - pds.Length; // 需要扩容的长度 + this.MethodDetails.ParameterDetailss = ArrayHelper.ArrayExpansion(pds, length); // 扩容入参描述数组 + pds = this.MethodDetails.ParameterDetailss; + var startParmsPd = pds[md.ParamsArgIndex]; // 获取可变入参参数描述 + for(int i = md.ParamsArgIndex + 1; i <= md.ParamsArgIndex + length; i++) + { + pds[i] = startParmsPd.CloneOfModel(this); + pds[i].Index = pds[i-1].Index + 1; + pds[i].IsParams = true; + } + } for (int i = 0; i < nodeInfo.ParameterData.Length; i++) { - var mdPd = this.MethodDetails.ParameterDetailss[i]; - ParameterData pd = nodeInfo.ParameterData[i]; - mdPd.IsExplicitData = pd.State; - mdPd.DataValue = pd.Value; - mdPd.ArgDataSourceType = EnumHelper.ConvertEnum(pd.SourceType); - mdPd.ArgDataSourceNodeGuid = pd.SourceNodeGuid; - + if(i >= pds.Length) + { + Console.WriteLine($"保存的参数数量大于方法此时的入参参数数量:[{nodeInfo.Guid}][{nodeInfo.MethodName}]"); + break; + } + var pd = pds[i]; + ParameterData pdInfo = nodeInfo.ParameterData[i]; + pd.IsExplicitData = pdInfo.State; + pd.DataValue = pdInfo.Value; + pd.ArgDataSourceType = EnumHelper.ConvertEnum(pdInfo.SourceType); + pd.ArgDataSourceNodeGuid = pdInfo.SourceNodeGuid; + } } @@ -327,14 +348,13 @@ namespace Serein.Library Array paramsArgs = null; // 初始化可选参数 int paramsArgIndex = 0; // 可选参数下标,与 object[] paramsArgs 一起使用 - Type paramsArgType = null; // 可变参数的参数类型 + if (md.ParamsArgIndex >= 0) { // 存在可变入参参数 - paramsArgType = md.ParameterDetailss[md.ParamsArgIndex].DataType.GetElementType(); // 获取可变参数的参数类型 + var paramsArgType = md.ParameterDetailss[md.ParamsArgIndex].DataType; // 获取可变参数的参数类型 // 可变参数数组长度 = 方法参数个数 - ( 可选入参下标 + 1 ) int paramsLength = md.ParameterDetailss.Length - md.ParamsArgIndex; - //paramsArgs = paramsArgType.MakeArrayType(paramsLength); paramsArgs = Array.CreateInstance(paramsArgType, paramsLength);// 可变参数 parameters = new object[md.ParamsArgIndex+1]; // 调用方法的入参数组 parameters[md.ParamsArgIndex] = paramsArgs; // 如果存在可选参数,入参参数最后一项则为可变参数 @@ -349,9 +369,10 @@ namespace Serein.Library for (int i = 0; i < md.ParameterDetailss.Length; i++) { var pd = md.ParameterDetailss[i]; // 方法入参描述 + var argDataType = pd.DataType; // 入参参数下标循环到可选参数时,开始写入到可选参数数组 - if(paramsArgs != null && i >= md.ParamsArgIndex) + if (paramsArgs != null && i >= md.ParamsArgIndex) { // 控制参数赋值方向: // true => paramsArgs @@ -359,10 +380,6 @@ namespace Serein.Library hasParams = true; } - // 可选参数为 Array 类型,所以需要获取子项类型 - // 如果 hasParams 为 true ,说明一定存在可选参数,所以 paramsArgType 一定不为 null - Type argDataType = hasParams ? paramsArgType : pd.DataType; - #region 获取基础的上下文数据 if (argDataType == typeof(IFlowEnvironment)) // 获取流程上下文 { diff --git a/Library/Utils/ArrayHelper.cs b/Library/Utils/ArrayHelper.cs new file mode 100644 index 0000000..2fab977 --- /dev/null +++ b/Library/Utils/ArrayHelper.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Serein.Library.Utils +{ + public class ArrayHelper + { + + + + /// + /// 数组尾部扩容 + /// + /// + /// + /// 扩容长度 + /// 新的数组 + /// length 传入负值 + public static T[] ArrayExpansion(T[] original, int length) + { + if(length == 0) + { + return original; + } + else if (length > 0) + { + // 创建一个新数组,比原数组大1 + T[] newArray = new T[original.Length + length]; + + // 复制原数组的元素 + for (int i = 0; i < original.Length; i++) + { + newArray[i] = original[i]; + } + + // 将新对象放在最后一位 + return newArray; + } + else + { + throw new Exception("不能减少数组长度"); + } + + } + + + + /// + /// 为数组添加新的元素 + /// + /// + /// + /// + /// 新的数组 + public static T[] AddToArray(T[] original, T newObject) + { + // 创建一个新数组,比原数组大1 + T[] newArray = ArrayHelper.ArrayExpansion(original, 1); + // 将新对象放在最后一位 + newArray[newArray.Length - 1] = newObject; + return newArray; + } + + /// + /// 移除数组某个元素 + /// + /// + /// + /// + /// 新的数组 + public static T[] RemoteToArray(T[] original, int index) + { + if (index == 0) + { + return new T[0]; + } + // 创建一个新数组,比原数组小1 + T[] newArray = new T[original.Length - 1]; + + for (int i = 0; i < index; i++) + { + newArray[i] = original[i]; + } + for (int i = index; i < newArray.Length; i++) + { + newArray[i] = original[i + 1]; + } + return newArray; + } + } +} diff --git a/NodeFlow/Tool/NodeMethodDetailsHelper.cs b/NodeFlow/Tool/NodeMethodDetailsHelper.cs index 18c61e4..58c53e3 100644 --- a/NodeFlow/Tool/NodeMethodDetailsHelper.cs +++ b/NodeFlow/Tool/NodeMethodDetailsHelper.cs @@ -214,28 +214,58 @@ public static class NodeMethodDetailsHelper private static ParameterDetails GetExplicitDataOfParameter(ParameterInfo parameterInfo, int index, - Type paremType, + Type explicitParemType, bool isExplicitData, Func func = null) { bool hasParams = parameterInfo.IsDefined(typeof(ParamArrayAttribute)); // 判断是否为可变参数 - string explicitTypeName = GetExplicitTypeName(paremType); - var items = GetExplicitItems(paremType, explicitTypeName); + Type dataType; + if (hasParams && parameterInfo.ParameterType.GetElementType() is Type paramsArgType) // 获取可变参数的子项类型 + { + // 可选参数为 Array 类型,所以需要获取子项类型 + // 如果 hasParams 为 true ,说明一定存在可选参数,所以 paramsArgType 一定不为 null + dataType = paramsArgType; + explicitParemType = paramsArgType; + } + else + { + dataType = parameterInfo.ParameterType; + } + + string explicitTypeName = GetExplicitTypeName(explicitParemType); + var items = GetExplicitItems(explicitParemType, explicitTypeName); if ("Bool".Equals(explicitTypeName)) explicitTypeName = "Select"; // 布尔值 转为 可选类型 return new ParameterDetails { IsExplicitData = isExplicitData, //attribute is null ? parameterInfo.HasDefaultValue : true, Index = index, // 索引 ExplicitTypeName = explicitTypeName, // Select/Bool/Value - ExplicitType = paremType,// 显示的入参类型 + ExplicitType = explicitParemType,// 显示的入参类型 Convertor = func, // 转换器 - DataType = parameterInfo.ParameterType, // 实际的入参类型 + DataType = dataType, // 实际的入参类型 Name = parameterInfo.Name, DataValue = parameterInfo.HasDefaultValue ? parameterInfo?.DefaultValue?.ToString() : "", // 如果存在默认值,则使用默认值 Items = items.ToArray(), // 如果是枚举值入参,则获取枚举类型的字面量 IsParams = hasParams, // 判断是否为可变参数 }; + + //string explicitTypeName = GetExplicitTypeName(explicitParemType); + //var items = GetExplicitItems(explicitParemType, explicitTypeName); + //if ("Bool".Equals(explicitTypeName)) explicitTypeName = "Select"; // 布尔值 转为 可选类型 + //return new ParameterDetails + //{ + // IsExplicitData = isExplicitData, //attribute is null ? parameterInfo.HasDefaultValue : true, + // Index = index, // 索引 + // ExplicitTypeName = explicitTypeName, // Select/Bool/Value + // ExplicitType = explicitParemType,// 显示的入参类型 + // Convertor = func, // 转换器 + // DataType = dataType, // 实际的入参类型 + // Name = parameterInfo.Name, + // DataValue = parameterInfo.HasDefaultValue ? parameterInfo?.DefaultValue?.ToString() : "", // 如果存在默认值,则使用默认值 + // Items = items.ToArray(), // 如果是枚举值入参,则获取枚举类型的字面量 + // IsParams = hasParams, // 判断是否为可变参数 + //}; } diff --git a/WorkBench/App.xaml.cs b/WorkBench/App.xaml.cs index 335851a..3888d28 100644 --- a/WorkBench/App.xaml.cs +++ b/WorkBench/App.xaml.cs @@ -15,7 +15,7 @@ namespace Serein.Workbench { #if DEBUG - if (1 == 11) + if (1 == 1) { string filePath; filePath = @"F:\临时\project\linux\project.dnf";