通过Emit优化Script脚本的解释执行;出于后期更新的方向,暂时隐藏表达式节点、条件表达式节点、全局数据节点;流程图转c#代码新增对于Script脚本的支持,Script脚本现在可以原生导出为C#代码。

This commit is contained in:
fengjiayi
2025-07-26 19:36:54 +08:00
parent 9a8de6b571
commit 29f2be5c80
32 changed files with 2175 additions and 432 deletions

View File

@@ -11,41 +11,81 @@ using static Serein.Library.Utils.EmitHelper;
namespace Serein.Library
{
/// <summary>
/// Emit创建委托描述用于WebApi、WebSocket、NodeFlow动态调用方法的场景
/// 通过 Emit 创建委托,代替反射调用方法,实现高性能的动态调用
/// 一般情况下你无须内部细节,只需要调用 Invoke() 方法即可。
/// </summary>
public class DelegateDetails
{
private readonly EmitType emitType = EmitType.None;
/// <summary>
/// 创建的委托类型
/// </summary>
public enum EmitType
{
/// <summary>
/// 默认
/// </summary>
None,
/// <summary>
/// 方法调用
/// </summary>
MethodInvoke,
/// <summary>
/// 字段赋值
/// </summary>
FieldSetter,
/// <summary>
/// 字段取值
/// </summary>
FieldGetter,
/// <summary>
/// 属性赋值
/// </summary>
PropertySetter,
/// <summary>
/// 属性取值
/// </summary>
PropertyGetter,
/// <summary>
/// 集合取值
/// </summary>
CollectionGetter,
/// <summary>
/// 集合赋值
/// </summary>
CollectionSetter
}
public enum GSType
{
Get,
Set,
}
/// <summary>
/// 根据方法信息构建Emit委托
/// </summary>
/// <param name="methodInfo"></param>
public DelegateDetails(MethodInfo methodInfo)
{
emitType = EmitType.MethodInvoke;
var emitMethodType = EmitHelper.CreateDynamicMethod(methodInfo, out var emitDelegate);
_emitMethodInfo = emitMethodType;
_emitDelegate = emitDelegate;
SetFunc();
}
private void SetFunc()
{
methodType = _emitMethodInfo.EmitMethodType;
if (_emitDelegate is Func<object, object[], Task<object>> hasResultTask)
{
this.hasResultTask = hasResultTask;
funcType = 2;
this.methodHasResultTask = hasResultTask;
}
else if (_emitDelegate is Func<object, object[], Task> task)
{
this.task = task;
funcType = 1;
this.methodTask = task;
}
else if (_emitDelegate is Func<object, object[], object> func)
{
this.func = func;
funcType = 0;
this.methodInvoke = func;
}
else
{
@@ -54,9 +94,97 @@ namespace Serein.Library
}
public Func<object, object[], Task<object>> hasResultTask;
public Func<object, object[], Task> task;
public Func<object, object[], object> func;
/// <summary>
/// 根据字段信息构建Emit取/赋值委托
/// </summary>
/// <param name="fieldInfo">字段信息</param>
/// <param name="gsType">是否为 get如果不是则为 set</param>
public DelegateDetails(FieldInfo fieldInfo, GSType gsType)
{
if (gsType == GSType.Get)
{
emitType = EmitType.FieldGetter;
getter = EmitHelper.CreateFieldGetter(fieldInfo);
}
else if (gsType == GSType.Set)
{
emitType = EmitType.FieldSetter;
setter = EmitHelper.CreateFieldSetter(fieldInfo);
}
else
{
throw new NotSupportedException("错误的构建类型");
}
}
/// <summary>
/// 根据字段信息构建Emit取/赋值委托
/// </summary>
/// <param name="propertyInfo">字段信息</param>
/// <param name="gsType">是否为 get如果不是则为 set</param>
public DelegateDetails(PropertyInfo propertyInfo, GSType gsType)
{
if (gsType == GSType.Get)
{
emitType = EmitType.PropertyGetter;
getter = EmitHelper.CreatePropertyGetter(propertyInfo);
}
else if (gsType == GSType.Set)
{
emitType = EmitType.PropertySetter;
setter = EmitHelper.CreatePropertySetter(propertyInfo);
}
else
{
throw new NotSupportedException("错误的构建类型");
}
}
/// <summary>
/// 目前提供了创建集合取值/赋值委托
/// </summary>
/// <param name="type">类型信息</param>
/// <param name="gsType">操作类型</param>
public DelegateDetails(Type type, EmitType emitType)
{
if (emitType == EmitType.CollectionSetter)
{
emitType = EmitType.CollectionSetter;
collectionSetter = EmitHelper.CreateCollectionSetter(type);
}
else if (emitType == EmitType.CollectionGetter)
{
emitType = EmitType.CollectionGetter;
collectionGetter = EmitHelper.CreateCollectionGetter(type);
}
else
{
throw new NotSupportedException("错误的构建类型");
}
}
private Func<object,object, object> collectionGetter= null;
private Action<object,object, object> collectionSetter = null;
private Func<object, object> getter = null;
private Action<object, object> setter = null;
private Func<object, object[], Task<object>> methodHasResultTask = null;
private Func<object, object[], Task> methodTask = null;
private Func<object, object[], object> methodInvoke = null;
/*/// <summary>
@@ -72,12 +200,9 @@ namespace Serein.Library
private Delegate _emitDelegate;
private EmitMethodInfo _emitMethodInfo;
/// <summary>
/// 0是普通
/// 1是异步无返回值
/// 2是异步有返回值
/// </summary>
private int funcType;
private EmitMethodType methodType;
/// <summary>
/// 该Emit委托的相应信息
@@ -96,50 +221,65 @@ namespace Serein.Library
//public EmitMethodType EmitMethodType { get => _emitMethodType; }
public async Task<object> AutoInvokeAsync(object[] args)
{
if (_emitMethodInfo.IsStatic)
{
return await InvokeAsync(null, args);
}
else
{
var obj = Activator.CreateInstance(_emitMethodInfo.DeclaringType);
return await InvokeAsync(obj, args);
}
throw new Exception("Not static method");
}
/// <summary>
/// <para>使用的实例必须能够正确调用该委托,传入的参数也必须符合方法入参信息。</para>
/// </summary>
/// <param name="instance">拥有符合委托签名的方法信息的实例</param>
/// <param name="args">如果方法没有入参,也需要传入一个空数组</param>
/// <returns>void方法自动返回null</returns>
/// <param name="instance">拥有符合委托签名的实例</param>
/// <param name="args">如果不需要入参,也需要传入一个空数组,而不能为 null</param>
/// <returns>void方法、setter自动返回null</returns>
public async Task<object> InvokeAsync(object instance, object[] args)
{
if (emitType == EmitType.MethodInvoke)
{
return await MethodInvoke(instance, args);
}
else if (emitType == EmitType.PropertyGetter || emitType == EmitType.FieldGetter)
{
return getter(instance);
}
else if (emitType == EmitType.PropertySetter || emitType == EmitType.FieldSetter)
{
setter(instance, args[0]);
return null;
}
else if (emitType == EmitType.CollectionGetter)
{
return collectionGetter(instance, args[0]);
}
else if (emitType == EmitType.CollectionSetter)
{
collectionSetter(instance, args[0], args[1]);
return null;
}
else
{
throw new NotSupportedException("当前委托类型不支持 InvokeAsync 方法。请使用其他方法调用。");
}
}
private async Task<object> MethodInvoke(object instance, object[] args)
{
if (args is null)
{
args = Array.Empty<object>();
}
if(_emitMethodInfo.IsStatic)
if (_emitMethodInfo.IsStatic)
{
instance = null;
}
object result = null;
if(funcType == 0)
if (methodType == EmitMethodType.Func)
{
result = func.Invoke(instance, args);
result = methodInvoke.Invoke(instance, args);
}
else if (funcType == 2)
else if (methodType == EmitMethodType.TaskHasResult)
{
result = await hasResultTask(instance, args);
}
else if (funcType == 1)
result = await methodHasResultTask(instance, args);
}
else if (methodType == EmitMethodType.Task)
{
await task(instance, args);
await methodTask(instance, args);
result = null;
}
else
@@ -148,5 +288,6 @@ namespace Serein.Library
}
return result;
}
}
}