为Script提供了SereinScript.ExecuteAsync执行脚本文本内容的静态方法。

This commit is contained in:
fengjiayi
2025-07-18 23:17:28 +08:00
parent fc05cd662b
commit afe0783de1
4 changed files with 56 additions and 16 deletions

View File

@@ -4,10 +4,21 @@ namespace Serein.Script
{
public class ScriptInvokeContext : IScriptInvokeContext
{
/// <summary>
/// 脚本使用流程上下文
/// </summary>
/// <param name="dynamicContext"></param>
public ScriptInvokeContext(IDynamicContext dynamicContext)
{
FlowContext = dynamicContext;
}
/// <summary>
/// 不使用流程上下文
/// </summary>
public ScriptInvokeContext()
{
}
public IDynamicContext FlowContext{ get; }

View File

@@ -1,4 +1,5 @@
using Serein.Library;
using Serein.Library.Api;
using Serein.Script.Node;
using Serein.Script.Node.FlowControl;
using System;
@@ -15,6 +16,9 @@ namespace Serein.Script
public class SereinScript
{
/// <summary>
/// 类型分析
/// </summary>
@@ -24,6 +28,21 @@ namespace Serein.Script
private ProgramNode? programNode;
public static Task<object?> ExecuteAsync(string script, Dictionary<string, Type>? argTypes = null)
{
SereinScriptParser parser = new SereinScriptParser();
SereinScriptTypeAnalysis analysis = new SereinScriptTypeAnalysis();
var programNode = parser.Parse(script);
analysis.NodeSymbolInfos.Clear(); // 清空符号表
if (argTypes is not null) analysis.LoadSymbol(argTypes); // 提前加载脚本节点定义的符号
analysis.Analysis(programNode); // 分析节点类型
SereinScriptInterpreter Interpreter = new SereinScriptInterpreter(analysis.NodeSymbolInfos);
IScriptInvokeContext context = new ScriptInvokeContext();
var task = Interpreter.InterpreterAsync(context, programNode);
return task; // 脚本返回类型
}
/// <summary>
/// 解析脚本
/// </summary>

View File

@@ -295,7 +295,7 @@ namespace Serein.Script
async Task<object?> InterpreterFunctionCallNodeAsync(IScriptInvokeContext context, FunctionCallNode functionCallNode)
{
// 获取流程上下文
if (functionCallNode.FunctionName.Equals("getFlowApi", StringComparison.OrdinalIgnoreCase))
if (context.FlowContext != null && functionCallNode.FunctionName.Equals("getFlowApi", StringComparison.OrdinalIgnoreCase))
{
return context.FlowContext;
}

View File

@@ -5,6 +5,7 @@ using Serein.Library.Api;
using Serein.Library.Utils;
using Serein.NodeFlow.Env;
using Serein.NodeFlow.Services;
using Serein.Script;
using Serein.Workbench.Api;
using Serein.Workbench.Services;
using Serein.Workbench.ViewModels;
@@ -56,22 +57,31 @@ namespace Serein.Workbench
// 这里是测试代码,可以删除
private async Task LoadLocalProjectAsync()
{
var properties = new Dictionary<string, Type>
{
{ "Id", typeof(int) },
{ "Name", typeof(string) },
{ "CreateTime", typeof(DateTime) }
};
var script = """
x = 114514;
x = (x * 100000000000) + x;
value = "调用";
value = value + "委托";
return value + x;
""";
var result = await SereinScript.ExecuteAsync(script);
var type = DynamicObjectHelper.CreateTypeWithINotifyPropertyChanged(properties, "MyDynamicClass");
dynamic? obj = Activator.CreateInstance(type);
if(obj is null) return;
if (obj is INotifyPropertyChanged npc)
{
npc.PropertyChanged += (s, e) => Debug.WriteLine($"属性改变: {e.PropertyName}");
}
obj.Name = "下北泽";
obj.Id = 114514;
/* var properties = new Dictionary<string, Type>
{
{ "Id", typeof(int) },
{ "Name", typeof(string) },
{ "CreateTime", typeof(DateTime) }
};
var type = DynamicObjectHelper.CreateTypeWithINotifyPropertyChanged(properties, "MyDynamicClass");
dynamic? obj = Activator.CreateInstance(type);
if(obj is null) return;
if (obj is INotifyPropertyChanged npc)
{
npc.PropertyChanged += (s, e) => Debug.WriteLine($"属性改变: {e.PropertyName}");
}
obj.Name = "下北泽";
obj.Id = 114514;*/
if (1 == 11)