diff --git a/Library/Enums/ParameterValueInputType.cs b/Library/Enums/ParameterValueInputType.cs
new file mode 100644
index 0000000..7cee072
--- /dev/null
+++ b/Library/Enums/ParameterValueInputType.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Serein.Library
+{
+ public enum ParameterValueInputType
+ {
+ Input,
+ Select,
+ }
+}
diff --git a/Library/FlowNode/NodeModelBaseFunc.cs b/Library/FlowNode/NodeModelBaseFunc.cs
index e7a8020..6e63eb2 100644
--- a/Library/FlowNode/NodeModelBaseFunc.cs
+++ b/Library/FlowNode/NodeModelBaseFunc.cs
@@ -74,7 +74,7 @@ namespace Serein.Library
pd.DataType = null;
pd.Name = null;
pd.ArgDataSourceNodeGuid = null;
- pd.ExplicitTypeName = null;
+ pd.InputType = ParameterValueInputType.Input;
}
this.MethodDetails.ParameterDetailss = null;
this.MethodDetails.ActingInstance = null;
diff --git a/Library/FlowNode/ParameterDetails.cs b/Library/FlowNode/ParameterDetails.cs
index 9978424..95b7044 100644
--- a/Library/FlowNode/ParameterDetails.cs
+++ b/Library/FlowNode/ParameterDetails.cs
@@ -10,6 +10,8 @@ using System.Threading.Tasks;
namespace Serein.Library
{
+
+
///
/// 节点入参参数详情
///
@@ -57,7 +59,7 @@ namespace Serein.Library
/// Value :除以上类型之外的任意参数
///
[PropertyInfo]
- private string _explicitTypeName ;
+ private ParameterValueInputType _inputType ;
///
/// 入参数据来源。默认使用上一节点作为入参数据。
@@ -91,7 +93,7 @@ namespace Serein.Library
private string _dataValue;
///
- /// 只有当ExplicitTypeName 为 Select 时,才会需要该成员。
+ /// 只有当 InputType 为 Select 时,才会需要该成员。
///
[PropertyInfo(IsNotification = true)]
private string[] _items ;
@@ -104,6 +106,8 @@ namespace Serein.Library
}
+
+
public partial class ParameterDetails
{
@@ -133,7 +137,7 @@ namespace Serein.Library
Name = info.Name;
DataType = Type.GetType(info.DataTypeFullName);
ExplicitType = Type.GetType(info.ExplicitTypeFullName);
- ExplicitTypeName = info.ExplicitTypeName;
+ InputType = info.InputType.ConvertEnum();
Items = info.Items;
IsParams = info.IsParams;
}
@@ -151,7 +155,7 @@ namespace Serein.Library
DataTypeFullName = this.DataType.FullName,
Name = this.Name,
ExplicitTypeFullName = this.ExplicitType.FullName,
- ExplicitTypeName = this.ExplicitTypeName,
+ InputType = this.InputType.ToString(),
Items = this.Items.Select(it => it).ToArray(),
};
}
@@ -168,7 +172,7 @@ namespace Serein.Library
Index = this.Index,
IsExplicitData = this.IsExplicitData,
ExplicitType = this.ExplicitType,
- ExplicitTypeName = this.ExplicitTypeName,
+ InputType = this.InputType,
//Convertor = this.Convertor,
DataType = this.DataType,
Name = this.Name,
@@ -199,6 +203,11 @@ namespace Serein.Library
{
return context;
}
+ // 返回流程上下文
+ if (typeof(NodeModelBase).IsAssignableFrom(DataType))
+ {
+ return NodeModel;
+ }
// 显式设置的参数
if (IsExplicitData && !DataValue.StartsWith("@", StringComparison.OrdinalIgnoreCase))
{
diff --git a/Library/FlowNode/ParameterDetailsInfo.cs b/Library/FlowNode/ParameterDetailsInfo.cs
index 4fc6905..869b7a7 100644
--- a/Library/FlowNode/ParameterDetailsInfo.cs
+++ b/Library/FlowNode/ParameterDetailsInfo.cs
@@ -43,7 +43,7 @@ namespace Serein.Library
/// Bool : 布尔类型
/// Value : 除以上类型之外的任意参数
///
- public string ExplicitTypeName { get; set; }
+ public string InputType { get; set; }
///
/// 参数选择器
diff --git a/NodeFlow/Model/SingleConditionNode.cs b/NodeFlow/Model/SingleConditionNode.cs
index d5836e7..ae41a6f 100644
--- a/NodeFlow/Model/SingleConditionNode.cs
+++ b/NodeFlow/Model/SingleConditionNode.cs
@@ -71,7 +71,7 @@ namespace Serein.NodeFlow.Model
ArgDataSourceType = ConnectionArgSourceType.GetPreviousNodeData,
NodeModel = this,
//Convertor = null,
- ExplicitTypeName = "Value",
+ InputType = ParameterValueInputType.Input,
Items = null,
};
this.MethodDetails.ParameterDetailss = [..pd];
diff --git a/NodeFlow/Model/SingleExpOpNode.cs b/NodeFlow/Model/SingleExpOpNode.cs
index 2098862..302cd79 100644
--- a/NodeFlow/Model/SingleExpOpNode.cs
+++ b/NodeFlow/Model/SingleExpOpNode.cs
@@ -60,7 +60,7 @@ namespace Serein.NodeFlow.Model
ArgDataSourceType = ConnectionArgSourceType.GetPreviousNodeData,
NodeModel = this,
//Convertor = null,
- ExplicitTypeName = "Value",
+ InputType = ParameterValueInputType.Input,
Items = null,
};
this.MethodDetails.ParameterDetailss = [.. pd];
diff --git a/NodeFlow/Model/SingleScriptNode.cs b/NodeFlow/Model/SingleScriptNode.cs
index 38b72a2..4af4159 100644
--- a/NodeFlow/Model/SingleScriptNode.cs
+++ b/NodeFlow/Model/SingleScriptNode.cs
@@ -89,7 +89,7 @@ namespace Serein.NodeFlow.Model
ArgDataSourceNodeGuid = string.Empty,
ArgDataSourceType = ConnectionArgSourceType.GetPreviousNodeData,
NodeModel = this,
- ExplicitTypeName = "Value",
+ InputType = ParameterValueInputType.Input,
Items = null,
IsParams = true,
};
diff --git a/NodeFlow/Tool/FlowLibrary.cs b/NodeFlow/Tool/FlowLibrary.cs
index e27ed58..35c4bb9 100644
--- a/NodeFlow/Tool/FlowLibrary.cs
+++ b/NodeFlow/Tool/FlowLibrary.cs
@@ -5,13 +5,21 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
+using static System.Runtime.InteropServices.JavaScript.JSType;
namespace Serein.NodeFlow
{
+ public class LibraryMdDd (MethodDetails methodDetails,DelegateDetails delegateDetails)
+ {
+ public MethodDetails MethodDetails { get; } = methodDetails;
+ public DelegateDetails DelegateDetails { get; } = delegateDetails;
+ }
+
///
/// 加载在流程中的程序集依赖
@@ -111,7 +119,7 @@ namespace Serein.NodeFlow
var loaderExceptions = ex.LoaderExceptions;
foreach (var loaderException in loaderExceptions)
{
- SereinEnv.WriteLine(InfoType.ERROR, loaderException.Message);
+ SereinEnv.WriteLine(InfoType.ERROR, loaderException?.Message);
}
return false;
}
@@ -149,7 +157,7 @@ namespace Serein.NodeFlow
// 从 scanTypes.Type 创建的方法信息
// Md : 方法描述
// Dd :方法对应的Emit委托
- List<(MethodDetails Md, DelegateDetails Dd)> detailss = new List<(MethodDetails Md, DelegateDetails Dd)>();
+ List detailss = new List();
// 遍历扫描的类型
foreach ((var type, var flowName) in scanTypes)
@@ -165,7 +173,7 @@ namespace Serein.NodeFlow
continue;
}
md.MethodAnotherName = flowName + md.MethodAnotherName; // 方法别名
- detailss.Add((md, dd));
+ detailss.Add(new LibraryMdDd(md, dd));
}
}
@@ -176,11 +184,26 @@ namespace Serein.NodeFlow
{
return false;
}
- #region 加载成功,缓存所有方法、委托的信息
- foreach ((var md, var dd) in detailss)
+ // 简单排序一下
+ //detailss = detailss.OrderBy(k => k.MethodDetails.MethodName,).ToList();
+
+
+
+ detailss.Sort((a, b) => string.Compare(a.MethodDetails.MethodName, b.MethodDetails.MethodName, StringComparison.OrdinalIgnoreCase));
+ foreach (var item in detailss)
{
- MethodDetailss.TryAdd(md.MethodName, md);
- DelegateDetailss.TryAdd(md.MethodName, dd);
+ SereinEnv.WriteLine(InfoType.INFO, "loading method : " + item.MethodDetails.MethodName);
+
+ }
+
+ //detailss.Sort((a, b) => string.Compare());
+
+ #region 加载成功,缓存所有方法、委托的信息
+ foreach (var item in detailss)
+ {
+ var key = item.MethodDetails.MethodName;
+ MethodDetailss.TryAdd(key, item.MethodDetails);
+ DelegateDetailss.TryAdd(key, item.DelegateDetails);
}
#endregion
diff --git a/NodeFlow/Tool/FlowLibraryManagement.cs b/NodeFlow/Tool/FlowLibraryManagement.cs
index c78e21e..6326c9d 100644
--- a/NodeFlow/Tool/FlowLibraryManagement.cs
+++ b/NodeFlow/Tool/FlowLibraryManagement.cs
@@ -229,7 +229,8 @@ namespace Serein.NodeFlow.Tool
GC.WaitForPendingFinalizers();
};
var assembly = flowAlc.LoadFromAssemblyPath(dllFilePath); // 加载指定路径的程序集
- return LoadAssembly(assembly, actionUnload);
+ var assembly_result = LoadAssembly(assembly, actionUnload);
+ return assembly_result;
}
/* var dir = Path.GetDirectoryName(dllFilePath); // 获取目录路径
@@ -272,15 +273,26 @@ namespace Serein.NodeFlow.Tool
}
FlowLibrary flowLibrary = new FlowLibrary(assembly, actionUnload);
- if (flowLibrary.LoadAssembly(assembly))
+ var loadResult = flowLibrary.LoadAssembly(assembly); // 加载程序集
+ if (loadResult)
{
- _myFlowLibrarys.TryAdd(assembly.GetName().Name, flowLibrary);
- (NodeLibraryInfo, List) result = (flowLibrary.ToInfo(),
- flowLibrary.MethodDetailss.Values.Select(md => md.ToInfo()).ToList());
+ var assemblyName = assembly.GetName().Name;
+ if (string.IsNullOrEmpty(assemblyName))
+ {
+ actionUnload.Invoke();
+ throw new Exception($"程序集[{assembly.GetName().FullName}]加载失败,没有程序集名称");
+ }
+ _myFlowLibrarys.TryAdd(assemblyName, flowLibrary);
+
+ List mdInfos = flowLibrary.MethodDetailss.Values.Select(md => md.ToInfo()).ToList();
+ mdInfos.Sort((a, b) => string.Compare(a.MethodName, b.MethodName, StringComparison.OrdinalIgnoreCase));
+
+ (NodeLibraryInfo, List) result = (flowLibrary.ToInfo(), mdInfos);
return result;
}
else
{
+ actionUnload.Invoke();
throw new Exception($"程序集[{assembly.GetName().FullName}]加载失败");
}
}
diff --git a/NodeFlow/Tool/NodeMethodDetailsHelper.cs b/NodeFlow/Tool/NodeMethodDetailsHelper.cs
index 8dcf030..646d3ac 100644
--- a/NodeFlow/Tool/NodeMethodDetailsHelper.cs
+++ b/NodeFlow/Tool/NodeMethodDetailsHelper.cs
@@ -6,6 +6,7 @@ using System.Reflection;
using Serein.Library.FlowNode;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+using System.ComponentModel.DataAnnotations;
namespace Serein.NodeFlow.Tool;
@@ -47,13 +48,10 @@ public static class NodeMethodDetailsHelper
}
var methodName = $"{assemblyName}.{type.Name}.{methodInfo.Name}";
- SereinEnv.WriteLine(InfoType.INFO, "loading method : " + methodName);
-
+
// 创建参数信息
var explicitDataOfParameters = GetExplicitDataOfParameters(methodInfo.GetParameters());
-
-
//// 通过表达式树生成委托
//var methodDelegate = GenerateMethodDelegate(type, // 方法所在的对象类型
// method, // 方法信息
@@ -65,6 +63,34 @@ public static class NodeMethodDetailsHelper
Type? returnType;
bool isTask = IsGenericTask(methodInfo.ReturnType, out var taskResult);
+
+ if (attribute.MethodDynamicType == Library.NodeType.UI)
+ {
+ if (isTask)
+ {
+ var innerType = methodInfo.ReturnType.GetGenericArguments()[0];
+ if (innerType.IsGenericType && innerType != typeof(IEmbeddedContent))
+ {
+ SereinEnv.WriteLine(InfoType.WARN, $"[{methodName}]跳过创建,因为UI方法的返回值并非IEmbeddedContent,流程工作台将无法正确显示自定义控件界面以及传递数据。");
+ methodDetails = null;
+ delegateDetails = null;
+ return false;
+ }
+ }
+ else
+ {
+ if (methodInfo.ReturnType != typeof(IEmbeddedContent))
+ {
+ SereinEnv.WriteLine(InfoType.WARN, $"[{methodName}]跳过创建,因为UI方法的返回值并非IEmbeddedContent,流程工作台将无法正确显示自定义控件界面以及传递数据。");
+ methodDetails = null;
+ delegateDetails = null;
+ return false;
+ }
+ }
+
+ }
+
+ // 对于触发器
if (attribute.MethodDynamicType == Library.NodeType.Flipflop)
{
if (methodInfo.ReturnType.IsGenericType && methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(Task<>))
@@ -91,13 +117,8 @@ public static class NodeMethodDetailsHelper
delegateDetails = null;
return false;
}
-
- //if (!isTask || taskResult != typeof(IFlipflopContext
///
///
- private static string GetExplicitTypeName(Type type)
+ private static ParameterValueInputType GetInputType(Type type)
{
return type switch
{
- Type t when t.IsEnum => "Select",
- Type t when t == typeof(bool) => "Bool",
- Type t when t == typeof(string) => "Value",
- Type t when t == typeof(int) => "Value",
- Type t when t == typeof(double) => "Value",
- _ => "Value"
+ Type t when t.IsEnum => ParameterValueInputType.Select,
+ Type t when t == typeof(bool) => ParameterValueInputType.Select,
+ Type t when t == typeof(string) => ParameterValueInputType.Input,
+ Type t when t == typeof(int) => ParameterValueInputType.Input,
+ Type t when t == typeof(double) => ParameterValueInputType.Input,
+ _ => ParameterValueInputType.Input
};
}
@@ -305,14 +355,14 @@ public static class NodeMethodDetailsHelper
/// 获取参数列表选项
///
///
- ///
+ ///
///
- private static IEnumerable GetExplicitItems(Type type, string explicitTypeName)
+ private static IEnumerable GetExplicitItems(Type type, ParameterValueInputType InputType)
{
- IEnumerable items = explicitTypeName switch
+ IEnumerable items = InputType switch
{
- "Select" => Enum.GetNames(type),
- "Bool" => ["True", "False"],
+ ParameterValueInputType.Select when type == typeof(bool) => ["True", "False"],
+ ParameterValueInputType.Select => Enum.GetNames(type),
_ => []
};
return items;
diff --git a/Serein.Workbench.Avalonia/Converters/IsVisibleOfParameterConverter.cs b/Serein.Workbench.Avalonia/Converters/IsVisibleOfParameterConverter.cs
index f6e7309..47d20a8 100644
--- a/Serein.Workbench.Avalonia/Converters/IsVisibleOfParameterConverter.cs
+++ b/Serein.Workbench.Avalonia/Converters/IsVisibleOfParameterConverter.cs
@@ -17,8 +17,8 @@ namespace Serein.Workbench.Avalonia.Converters
if(value is ParameterDetails pd)
{
-
- if (pd.ExplicitTypeName == "Value")
+
+ if (pd.InputType == ParameterValueInputType.Input)
{
return false;
diff --git a/Serein.Workbench.Avalonia/Custom/ViewModels/ParameterDetailsViewModel.cs b/Serein.Workbench.Avalonia/Custom/ViewModels/ParameterDetailsViewModel.cs
index 779caab..571b5c9 100644
--- a/Serein.Workbench.Avalonia/Custom/ViewModels/ParameterDetailsViewModel.cs
+++ b/Serein.Workbench.Avalonia/Custom/ViewModels/ParameterDetailsViewModel.cs
@@ -48,7 +48,7 @@ namespace Serein.Workbench.Avalonia.Custom.ViewModels
return;
}
- if ("Value".Equals(ParameterDetails.ExplicitTypeName))
+ if (ParameterDetails.InputType == ParameterValueInputType.Input )
{
// 值类型
IsVisibleA = false;
diff --git a/Workbench/Node/View/ScriptNodeControl.xaml.cs b/Workbench/Node/View/ScriptNodeControl.xaml.cs
index f16decf..7a3f1d0 100644
--- a/Workbench/Node/View/ScriptNodeControl.xaml.cs
+++ b/Workbench/Node/View/ScriptNodeControl.xaml.cs
@@ -72,7 +72,7 @@ namespace Serein.Workbench.Node.View
// 获取 MethodDetailsControl 实例
var methodDetailsControl = this.MethodDetailsControl;
var itemsControl = FindVisualChild(methodDetailsControl); // 查找 ItemsControl
- if (itemsControl != null)
+ if (itemsControl != null && base.ViewModel.NodeModel.MethodDetails.ParameterDetailss != null)
{
var argDataJunction = new JunctionControlBase[base.ViewModel.NodeModel.MethodDetails.ParameterDetailss.Length];
var controls = new List();
diff --git a/Workbench/Themes/MethodDetailsControl.xaml b/Workbench/Themes/MethodDetailsControl.xaml
index ce11b2a..9fda70f 100644
--- a/Workbench/Themes/MethodDetailsControl.xaml
+++ b/Workbench/Themes/MethodDetailsControl.xaml
@@ -137,7 +137,7 @@
-
+
@@ -160,7 +160,7 @@
-
+