添加了@Dtc(数据类型转换)、@Data(获取全局数据)表达式

This commit is contained in:
fengjiayi
2024-12-09 22:57:06 +08:00
parent 8c54b9a014
commit 0f46b7ef63
27 changed files with 628 additions and 97 deletions

View File

@@ -917,7 +917,30 @@ namespace Serein.Library.Api
#endregion
#region
#region
#region /
/// <summary>
/// 添加或更新全局数据
/// </summary>
/// <param name="keyName">数据名称</param>
/// <param name="data">数据集</param>
/// <returns></returns>
object AddOrUpdateGlobalData(string keyName, object data);
/// <summary>
/// 获取全局数据
/// </summary>
/// <param name="keyName">数据名称</param>
/// <returns></returns>
object GetGlobalData(string keyName);
#endregion
#region
/// <summary>
/// 运行时加载
@@ -933,6 +956,7 @@ namespace Serein.Library.Api
/// <param name="isRecurrence">是否递归加载</param>
void LoadAllNativeLibraryOfRuning(string path, bool isRecurrence = true);
#endregion
#endregion
#region UI视觉

View File

@@ -78,30 +78,34 @@ namespace Serein.Library
args = Array.Empty<object>();
}
object result = null;
try
if (_emitMethodType == EmitMethodType.HasResultTask && _emitDelegate is Func<object, object[], Task<object>> hasResultTask)
{
if (_emitMethodType == EmitMethodType.HasResultTask && _emitDelegate is Func<object, object[], Task<object>> hasResultTask)
{
result = await hasResultTask(instance, args);
}
else if (_emitMethodType == EmitMethodType.Task && _emitDelegate is Func<object, object[], Task> task)
{
await task.Invoke(instance, args);
}
else if (_emitMethodType == EmitMethodType.Func && _emitDelegate is Func<object, object[], object> func)
{
result = func.Invoke(instance, args);
}
else
{
throw new NotImplementedException("创建了非预期委托(应该不会出现)");
}
return result;
result = await hasResultTask(instance, args);
}
catch
else if (_emitMethodType == EmitMethodType.Task && _emitDelegate is Func<object, object[], Task> task)
{
throw;
await task.Invoke(instance, args);
}
else if (_emitMethodType == EmitMethodType.Func && _emitDelegate is Func<object, object[], object> func)
{
result = func.Invoke(instance, args);
}
else
{
throw new NotImplementedException("创建了非预期委托(应该不会出现)");
}
//
return result;
//try
//{
//}
//catch
//{
// throw;
//}
}
}
}

View File

@@ -262,8 +262,9 @@ namespace Serein.Library
catch (Exception ex)
{
newFlowData = null;
await Console.Out.WriteLineAsync($"节点[{this.MethodDetails?.MethodName}]异常:" + ex);
context.Env.WriteLine(InfoType.ERROR,$"节点[{this.Guid}]异常:" + ex);
context.NextOrientation = ConnectionInvokeType.IsError;
context.ExceptionOfRuning = ex;
}
@@ -455,16 +456,31 @@ namespace Serein.Library
}
#endregion
#region Get表达式
if (pd.IsExplicitData // 输入了表达式
&& pd.DataValue.StartsWith("@get", StringComparison.OrdinalIgnoreCase) // Get表达式
)
#region @Get / @DTC Data type conversion / @Data ()
if (pd.IsExplicitData)
{
//var previousNode = context.GetPreviousNode(nodeModel);
//var previousFlowData = context.GetFlowData(previousNode.Guid); // 当前传递的数据
// 执行表达式从上一节点获取对象
inputParameter = SerinExpressionEvaluator.Evaluate(pd.DataValue, inputParameter, out _);
// @Get 表达式 (从上一节点获取对象)
if (pd.DataValue.StartsWith("@get", StringComparison.OrdinalIgnoreCase))
{
inputParameter = SerinExpressionEvaluator.Evaluate(pd.DataValue, inputParameter, out _);
}
// @DTC 表达式 Data type conversion
if (pd.DataValue.StartsWith("@dtc", StringComparison.OrdinalIgnoreCase))
{
inputParameter = SerinExpressionEvaluator.Evaluate(pd.DataValue, inputParameter, out _);
}
// @Data 表达式 (获取全局数据)
if (pd.DataValue.StartsWith("@data", StringComparison.OrdinalIgnoreCase))
{
inputParameter = SerinExpressionEvaluator.Evaluate(pd.DataValue, inputParameter, out _);
}
}
#endregion
#endregion

View File

@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
namespace Serein.Library
{
@@ -88,21 +89,57 @@ namespace Serein.Library
return value;
}
[NodeAction(NodeType.Action, "文本拼接")]
private string SereinTextJoin(params object[] value)
{
StringBuilder sb = new StringBuilder();
foreach (var item in value)
{
var tmp = item.ToString();
if (tmp == "\\n")
{
sb.Append(Environment.NewLine);
}
else if (tmp == "\\t")
{
sb.Append('\t');
}
else
{
sb.Append(tmp);
}
}
return sb.ToString();
}
/* if (!DynamicObjectHelper.TryResolve(dict, className, out var result))
{
Console.WriteLine("赋值过程中有错误,请检查属性名和类型!");
}
else
{
DynamicObjectHelper.PrintObjectProperties(result);
}
//if (!ObjDynamicCreateHelper.TryResolve(externalData, "RootType", out var result))
//{
// Console.WriteLine("赋值过程中有错误,请检查属性名和类型!");
//}
//ObjDynamicCreateHelper.PrintObjectProperties(result!);
return result;*/
[NodeAction(NodeType.Action, "键值对动态构建对象")]
private object SereinKvDataToObject(Dictionary<string, object> dict,
string classTypeName = "newClass_dynamic",
bool IsPrint = false)
{
if (!DynamicObjectHelper.TryResolve(dict, classTypeName, out var result))
{
Console.WriteLine("赋值过程中有错误,请检查属性名和类型!");
}
else
{
if (IsPrint)
{
Console.WriteLine("创建完成,正在打印结果");
DynamicObjectHelper.PrintObjectProperties(result);
}
}
return result;
}
[NodeAction(NodeType.Action, "设置/更新全局数据")]
private object SereinAddOrUpdateFlowGlobalData(string name,object data)
{
SereinEnv.EnvGlobalData.AddOrUpdate(name, data,(k,o)=> data);
return data;
}
}
}

View File

@@ -201,6 +201,10 @@ namespace Serein.Library.Utils
result = nuint.Parse(valueStr, CultureInfo.InvariantCulture);
}
#endif
else if(type == typeof(DateTime))
{
return DateTime.Parse(valueStr);
}
else
{
throw new ArgumentException("非预期值类型");

View File

@@ -1,5 +1,6 @@
using Serein.Library.Api;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
@@ -11,6 +12,39 @@ namespace Serein.Library.Utils
public static class SereinEnv
{
private static IFlowEnvironment environment;
/// <summary>
/// 记录全局数据
/// </summary>
public static ConcurrentDictionary<string, object> EnvGlobalData { get; } = new ConcurrentDictionary<string, object>();
/// <summary>
/// 清空全局数据
/// </summary>
public static void ClearGlobalData()
{
foreach (var nodeObj in EnvGlobalData.Values)
{
if (nodeObj != null)
{
if (typeof(IDisposable).IsAssignableFrom(nodeObj?.GetType()) && nodeObj is IDisposable disposable)
{
disposable?.Dispose();
}
}
else
{
}
}
EnvGlobalData.Clear();
}
/// <summary>
/// 设置运行流程
/// </summary>
/// <param name="environment"></param>
public static void SetEnv(IFlowEnvironment environment)
{
if (environment != null)
@@ -18,10 +52,22 @@ namespace Serein.Library.Utils
SereinEnv.environment = environment;
}
}
public static void WriteLine(InfoType type, string message, InfoClass @class = InfoClass.Trivial)
/// <summary>
/// 输出内容
/// </summary>
/// <param name="type">类型</param>
/// <param name="message">内容</param>
/// <param name="class">级别</param>
public static void WriteLine(InfoType type, string message, InfoClass @class = InfoClass.General)
{
SereinEnv.environment.WriteLine(type,message,@class);
}
}
}

View File

@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
@@ -83,6 +84,16 @@ namespace Serein.Library.Utils.SereinExpression
isChange = true;
result = SetMember(targetObJ, operand);
}
else if (operation == "@dtc")
{
isChange = true;
result = DataTypeConversion(targetObJ, operand);
}
else if (operation == "@data")
{
isChange = true;
result = GetGlobleData(targetObJ, operand);
}
else
{
throw new NotSupportedException($"Operation {operation} is not supported.");
@@ -402,11 +413,106 @@ namespace Serein.Library.Utils.SereinExpression
{
return ComputedNumber<decimal>(value, expression);
}
private static T ComputedNumber<T>(object value, string expression) where T : struct, IComparable<T>
{
T result = value.ToConvert<T>();
return SerinArithmeticExpressionEvaluator<T>.Evaluate(expression, result);
}
/// <summary>
/// 数据类型转换
/// </summary>
/// <param name="value"></param>
/// <param name="expression"></param>
/// <returns></returns>
private static object DataTypeConversion(object value, string expression)
{
Type tempType;
int typeStartIndex = expression.IndexOf('<');
int typeEndIndex = expression.IndexOf('>');
string typeStr = expression.Substring(typeStartIndex + 1, typeEndIndex - typeStartIndex - 1)
.Trim().ToLower(); // 手动置顶的类型
string valueStr = expression.Substring(typeEndIndex + 1, expression.Length - typeEndIndex - 1);
switch (typeStr)
{
case "bool":
tempType = typeof(bool);
break;
case "float":
tempType = typeof(float);
break;
case "decimal":
tempType = typeof(decimal);
break;
case "double":
tempType = typeof(double);
break;
case "sbyte":
tempType = typeof(sbyte);
break;
case "byte":
tempType = typeof(byte);
break;
case "short":
tempType = typeof(short);
break;
case "ushort":
tempType = typeof(ushort);
break;
case "int":
tempType = typeof(int);
break;
case "uint":
tempType = typeof(uint);
break;
case "long":
tempType = typeof(long);
break;
case "ulong":
tempType = typeof(ulong);
break;
// 如果需要支持 nint 和 nuint
// case "nint":
// tempType = typeof(nint);
// break;
// case "nuint":
// tempType = typeof(nuint);
// break;
case "string":
tempType = typeof(string);
break;
case "datetime":
tempType = typeof(DateTime);
break;
default:
tempType = Type.GetType(typeStr);
break;
}
if (tempType.IsValueType)
{
return valueStr.ToValueData(tempType);
}
else
{
return null;
}
}
/// <summary>
/// 获取全局数据
/// </summary>
/// <param name="value"></param>
/// <param name="expression"></param>
/// <returns></returns>
private static object GetGlobleData(object value, string expression)
{
var keyName = expression;
SereinEnv.EnvGlobalData.TryGetValue(keyName, out var data);
return data;
}
}
}