取消使用流程上下文自定义的字典数据;更改流程环境接口的输出方式

This commit is contained in:
fengjiayi
2024-11-08 17:30:51 +08:00
parent dff9a00fb6
commit 8c54b9a014
41 changed files with 448 additions and 505 deletions

View File

@@ -96,7 +96,7 @@ namespace Serein.NodeFlow.Env
}
catch (Exception ex)
{
Console.WriteLine("结束远程管理异常:" + ex);
SereinEnv.WriteLine(InfoType.ERROR, "结束远程管理异常:" + ex);
}
}
@@ -192,6 +192,10 @@ namespace Serein.NodeFlow.Env
/// </summary>
public UIContextOperation UIContextOperation { get; set; }
/// <summary>
/// 信息输出等级
/// </summary>
public InfoClass InfoClass { get ; set ; } = InfoClass.General;
/// <summary>
/// 如果没有全局触发器,且没有循环分支,流程执行完成后自动为 Completion 。
@@ -325,29 +329,44 @@ namespace Serein.NodeFlow.Env
#region
/// <summary>
/// 重定向Console输出
/// </summary>
public void SetConsoleOut()
{
var logTextWriter = new LogTextWriter(msg => Output(msg));
Console.SetOut(logTextWriter);
}
///// <summary>
///// 重定向Console输出
///// </summary>
//public void SetConsoleOut()
//{
// var logTextWriter = new LogTextWriter(msg => Output(msg));
// Console.SetOut(logTextWriter);
//}
/// <summary>
/// 使用JSON处理库输出对象信息
/// 输出信息
/// </summary>
/// <param name="obj"></param>
public void WriteLineObjToJson(object obj)
/// <param name="message">日志内容</param>
/// <param name="type">日志类别</param>
/// <param name="class">日志级别</param>
public void WriteLine(InfoType type, string message, InfoClass @class = InfoClass.Trivial)
{
var msg = JsonConvert.SerializeObject(obj);
if (OperatingSystem.IsWindows())
if (@class >= this.InfoClass)
{
UIContextOperation?.Invoke(() => OnEnvOut?.Invoke(msg + Environment.NewLine));
}
OnEnvOut?.Invoke(type, message);
}
///// <summary>
///// 使用JSON处理库输出对象信息
///// </summary>
///// <param name="obj"></param>
//public void WriteLineObjToJson(object obj)
//{
// var msg = JsonConvert.SerializeObject(obj);
// if (OperatingSystem.IsWindows())
// {
// UIContextOperation?.Invoke(() => OnEnvOut?.Invoke(msg + Environment.NewLine));
// }
//}
/// <summary>
/// 异步运行
/// </summary>
@@ -391,7 +410,7 @@ namespace Serein.NodeFlow.Env
if (flowStarter is null)
{
Console.WriteLine("没有启动流程,无法运行单个节点");
SereinEnv.WriteLine(InfoType.ERROR, "没有启动流程,无法运行单个节点");
return;
}
if (true || FlowState == RunState.Running || FlipFlopState == RunState.Running)
@@ -488,7 +507,7 @@ namespace Serein.NodeFlow.Env
var libraryMdss = this.FlowLibraryManagement.GetAllLibraryMds().ToArray();
// 获取当前项目的信息(节点相关的数据)
var project = await GetProjectInfoAsync();
Console.WriteLine("已将当前环境信息发送到远程客户端");
SereinEnv.WriteLine(InfoType.INFO, "已将当前环境信息发送到远程客户端");
return new FlowEnvInfo
{
Project = project, // 项目信息
@@ -747,7 +766,7 @@ namespace Serein.NodeFlow.Env
}
catch (Exception ex)
{
Console.WriteLine($"{ex}");
SereinEnv.WriteLine(InfoType.ERROR, $"无法加载DLL文件{ex}");
}
}
@@ -775,7 +794,7 @@ namespace Serein.NodeFlow.Env
NodeModelBase? node = groupedNodes[i];
sb.AppendLine($"{i} => {node.Guid}");
}
Console.WriteLine($"无法卸载[{assemblyName}]程序集,因为这些节点依赖于此程序集:{sb.ToString()}");
SereinEnv.WriteLine(InfoType.ERROR, $"无法卸载[{assemblyName}]程序集,因为这些节点依赖于此程序集:{sb.ToString()}");
return false;
}
@@ -964,7 +983,7 @@ namespace Serein.NodeFlow.Env
(var type, var state) = CheckConnect(fromNode, toNode, fromNodeJunctionType, toNodeJunctionType);
if (!state)
{
Console.WriteLine("出现非预期的连接行为");
SereinEnv.WriteLine(InfoType.WARN, "出现非预期的连接行为");
return false; // 出现不符预期的连接行为,忽略此次连接行为
}
@@ -1026,7 +1045,7 @@ namespace Serein.NodeFlow.Env
(var type, var state) = CheckConnect(fromNode, toNode, fromNodeJunctionType, toNodeJunctionType);
if (!state)
{
Console.WriteLine("出现非预期的连接行为");
SereinEnv.WriteLine(InfoType.WARN, "出现非预期的连接行为");
return false; // 出现不符预期的连接行为,忽略此次连接行为
}
@@ -1585,99 +1604,6 @@ namespace Serein.NodeFlow.Env
return true;
}
#region
/*/// <summary>
/// 动态加载程序集
/// </summary>
/// <param name="assembly">程序集本身</param>
/// <returns></returns>
private (Dictionary<RegisterSequence, List<Type>>, List<MethodDetails>) LoadAssembly(Assembly assembly)
{
try
{
List<Type> types = assembly.GetTypes().ToList(); // 获取程序集中的所有类型
#region 获取所有需要注册的类型
Dictionary<RegisterSequence, List<Type>> autoRegisterTypes = new Dictionary<RegisterSequence, List<Type>>();
foreach (Type type in types)
{
var autoRegisterAttribute = type.GetCustomAttribute<AutoRegisterAttribute>();
if (autoRegisterAttribute is not null)
{
if (!autoRegisterTypes.TryGetValue(autoRegisterAttribute.Class, out var valus))
{
valus = new List<Type>();
autoRegisterTypes.Add(autoRegisterAttribute.Class, valus);
}
valus.Add(type);
}
}
#endregion
#region 获取 DynamicFlow 特性的流程控制器,如果没有返回空
List<(Type, string)> scanTypes = types.Select(t =>
{
if (t.GetCustomAttribute<DynamicFlowAttribute>() is DynamicFlowAttribute dynamicFlowAttribute
&& dynamicFlowAttribute.Scan == true)
{
return (t, dynamicFlowAttribute.Name);
}
else
{
return (null, null);
}
}).Where(it => it.t is not null).ToList();
if (scanTypes.Count == 0)
{
return ([], []);
}
#endregion
#region 创建对应的方法元数据
List<MethodDetails> methodDetails = new List<MethodDetails>();
// 遍历扫描的类型
foreach ((var type, var flowName) in scanTypes)
{
// 加载DLL创建 MethodDetails、实例作用对象、委托方法
var assemblyName = type.Assembly.GetName().Name;
if (string.IsNullOrEmpty(assemblyName))
{
continue;
}
var methods = NodeMethodDetailsHelper.GetMethodsToProcess(type);
foreach (var method in methods)
{
(var md, var del) = NodeMethodDetailsHelper.CreateMethodDetails(type, method, assemblyName);
if (md is null || del is null)
{
Console.WriteLine($"无法加载方法信息:{assemblyName}-{type}-{method}");
continue;
}
md.MethodAnotherName = flowName + md.MethodAnotherName;
if (MethodDelegates.TryAdd(md.MethodName, del))
{
methodDetails.Add(md);
}
else
{
Console.WriteLine($"节点委托创建失败:{md.MethodName}");
}
}
}
#endregion
return (autoRegisterTypes, methodDetails);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return ([], []);
}
}*/
#endregion
/// <summary>
/// 创建节点
@@ -1801,7 +1727,7 @@ namespace Serein.NodeFlow.Env
FromExistInTo = ToOnF.Length > 0;
if (ToExistOnFrom && FromExistInTo)
{
Console.WriteLine("起始节点已与目标节点存在连接");
SereinEnv.WriteLine(InfoType.WARN, "起始节点已与目标节点存在连接");
isPass = false;
}
else
@@ -1809,13 +1735,13 @@ namespace Serein.NodeFlow.Env
// 检查是否可能存在异常
if (!ToExistOnFrom && FromExistInTo)
{
Console.WriteLine("目标节点不是起始节点的子节点,起始节点却是目标节点的父节点");
SereinEnv.WriteLine(InfoType.WARN, "目标节点不是起始节点的子节点,起始节点却是目标节点的父节点");
isPass = false;
}
else if (ToExistOnFrom && !FromExistInTo)
{
//
Console.WriteLine(" 起始节点不是目标节点的父节点,目标节点却是起始节点的子节点");
SereinEnv.WriteLine(InfoType.WARN, " 起始节点不是目标节点的父节点,目标节点却是起始节点的子节点");
isPass = false;
}
else
@@ -1871,16 +1797,6 @@ namespace Serein.NodeFlow.Env
if (!string.IsNullOrEmpty(toNodeArgSourceGuid))
{
await RemoteConnectAsync(fromNode, toNode, argIndex);
//Console.WriteLine("目标入参已确定参数来源,不可连接");
//return false;
//if (toNodeArgSourceGuid.Equals(fromNode.Guid))
//{
// //await RemoteConnectAsync(fromNode, toNode, argIndex); // 相同起始节点不同控制点已经连接,将其移除
//}
//else
//{
//}
}
toNode.MethodDetails.ParameterDetailss[argIndex].ArgDataSourceNodeGuid = fromNode.Guid;
toNode.MethodDetails.ParameterDetailss[argIndex].ArgDataSourceType = connectionArgSourceType;
@@ -1914,18 +1830,18 @@ namespace Serein.NodeFlow.Env
}
/// <summary>
/// 输出内容
/// </summary>
/// <param name="msg"></param>
private void Output(string msg)
{
if (OperatingSystem.IsWindows())
{
UIContextOperation?.Invoke(() => OnEnvOut?.Invoke(msg));
}
///// <summary>
///// 输出内容
///// </summary>
///// <param name="msg"></param>
//private void Output(string msg)
//{
// if (OperatingSystem.IsWindows())
// {
// UIContextOperation?.Invoke(() => OnEnvOut?.Invoke(msg));
// }
}
//}
#endregion

View File

@@ -16,6 +16,8 @@ namespace Serein.NodeFlow.Env
flowEnvironment = new FlowEnvironment(uiContextOperation);
// 默认使用本地环境
currentFlowEnvironment = flowEnvironment;
SereinEnv.SetEnv(currentFlowEnvironment);
}
/// <summary>
@@ -65,14 +67,18 @@ namespace Serein.NodeFlow.Env
public UIContextOperation UIContextOperation => currentFlowEnvironment.UIContextOperation;
public ISereinIOC IOC => (ISereinIOC)currentFlowEnvironment;
public string EnvName => currentFlowEnvironment.EnvName;
public bool IsGlobalInterrupt => currentFlowEnvironment.IsGlobalInterrupt;
public bool IsControlRemoteEnv => currentFlowEnvironment.IsControlRemoteEnv;
/// <summary>
/// 信息输出等级
/// </summary>
public InfoClass InfoClass { get => currentFlowEnvironment.InfoClass; set => currentFlowEnvironment.InfoClass = value; }
public RunState FlowState { get => currentFlowEnvironment.FlowState; set => currentFlowEnvironment.FlowState = value; }
public RunState FlipFlopState { get => currentFlowEnvironment.FlipFlopState; set => currentFlowEnvironment.FlipFlopState = value; }
@@ -335,9 +341,20 @@ namespace Serein.NodeFlow.Env
}
public void SetConsoleOut()
//public void SetConsoleOut()
//{
// currentFlowEnvironment.SetConsoleOut();
//}
/// <summary>
/// 输出信息
/// </summary>
/// <param name="message">日志内容</param>
/// <param name="type">日志类别</param>
/// <param name="class">日志级别</param>
public void WriteLine(InfoType type, string message, InfoClass @class = InfoClass.Trivial)
{
currentFlowEnvironment.SetConsoleOut();
currentFlowEnvironment.WriteLine(type, message, @class);
}
public void SetMonitorObjState(string key, bool isMonitor)
@@ -400,10 +417,10 @@ namespace Serein.NodeFlow.Env
return currentFlowEnvironment.TryGetMethodDetailsInfo(libraryName, methodName, out mdInfo);
}
public void WriteLineObjToJson(object obj)
{
currentFlowEnvironment.WriteLineObjToJson(obj);
}
//public void WriteLineObjToJson(object obj)
//{
// currentFlowEnvironment.WriteLineObjToJson(obj);
//}
/// <summary>
/// (用于远程)通知节点属性变更

View File

@@ -50,7 +50,7 @@ namespace Serein.NodeFlow.Env
{
var msgId = MsgIdHelper.GenerateId().ToString();
Console.WriteLine($"[{msgId}] => {theme}");
SereinEnv.WriteLine(InfoType.INFO, $"[{msgId}] => {theme}");
await SendCommandAsync(msgId, theme, data); // 客户端发送消息
}

View File

@@ -61,7 +61,7 @@ namespace Serein.NodeFlow.Env
{
if (string.IsNullOrEmpty(token))
{
Console.WriteLine("当前没有设置token但使用了token验证的服务端");
SereinEnv.WriteLine(InfoType.WARN, "当前没有设置token但使用了token验证的服务端");
}
this.environment = environment;
@@ -96,7 +96,7 @@ namespace Serein.NodeFlow.Env
catch (Exception ex)
{
FlowEnvRemoteWebSocket.MsgHandleHelper.RemoveModule(this);
Console.WriteLine("打开远程管理异常:" + ex);
SereinEnv.WriteLine(InfoType.ERROR, "打开远程管理异常:" + ex);
}
}
@@ -112,7 +112,7 @@ namespace Serein.NodeFlow.Env
}
catch (Exception ex)
{
Console.WriteLine("结束远程管理异常:" + ex);
SereinEnv.WriteLine(InfoType.ERROR, "结束远程管理异常:" + ex);
}
}
@@ -263,7 +263,7 @@ namespace Serein.NodeFlow.Env
// [AutoSocketHandle]
public void ExitRemoteEnv()
{
Console.WriteLine("暂未实现远程退出远程环境");
SereinEnv.WriteLine(InfoType.ERROR, "暂未实现远程退出远程环境");
IsLcR = false;
}
@@ -385,10 +385,9 @@ namespace Serein.NodeFlow.Env
{
return new { state = false }; // 非预期的控制点连接
}
Console.WriteLine();
Console.WriteLine($"起始节点:{fromNodeGuid}");
Console.WriteLine($"目标节点:{toNodeGuid}");
Console.WriteLine($"链接请求:{(tmpFromJunctionType, tmpToJunctionType)}");
SereinEnv.WriteLine(InfoType.INFO, $"起始节点:{fromNodeGuid}");
SereinEnv.WriteLine(InfoType.INFO, $"目标节点:{toNodeGuid}");
SereinEnv.WriteLine(InfoType.INFO, $"链接请求:{(tmpFromJunctionType, tmpToJunctionType)}");
var result = await environment.ConnectInvokeNodeAsync(fromNodeGuid, toNodeGuid, tmpFromJunctionType, tmpToJunctionType, tmpConnectionType);
return new { state = result };
@@ -477,10 +476,7 @@ namespace Serein.NodeFlow.Env
{
return new { state = false }; // 非预期的控制点连接
}
//Console.WriteLine();
//Console.WriteLine($"起始节点:{fromNodeGuid}");
//Console.WriteLine($"目标节点:{toNodeGuid}");
//Console.WriteLine($"链接请求:{(tmpFromJunctionType, tmpToJunctionType)}");
// 调用环境接口进行连接
var result = await environment.ConnectArgSourceNodeAsync(fromNodeGuid, toNodeGuid, tmpFromJunctionType, tmpToJunctionType, tmpArgSourceType, argIndex);
return new { state = result };

View File

@@ -66,6 +66,10 @@ namespace Serein.NodeFlow.Env
public bool IsControlRemoteEnv => true;
/// <summary>
/// 信息输出等级
/// </summary>
public InfoClass InfoClass { get; set; }
public RunState FlowState { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public RunState FlipFlopState { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
@@ -82,28 +86,40 @@ namespace Serein.NodeFlow.Env
/// </summary>
private bool IsLoadingNode = false;
public void SetConsoleOut()
//public void SetConsoleOut()
//{
// var logTextWriter = new LogTextWriter(msg =>
// {
// OnEnvOut?.Invoke(msg);
// });
// Console.SetOut(logTextWriter);
//}
/// <summary>
/// 输出信息
/// </summary>
/// <param name="message">日志内容</param>
/// <param name="type">日志类别</param>
/// <param name="class">日志级别</param>
public void WriteLine(InfoType type, string message, InfoClass @class = InfoClass.Trivial)
{
var logTextWriter = new LogTextWriter(msg =>
{
OnEnvOut?.Invoke(msg);
});
Console.SetOut(logTextWriter);
OnEnvOut?.Invoke(type, message);
}
public void WriteLineObjToJson(object obj)
{
Console.WriteLine("远程环境尚未实现的接口WriteLineObjToJson");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口WriteLineObjToJson");
}
public async Task StartRemoteServerAsync(int port = 7525)
{
await Console.Out.WriteLineAsync("远程环境尚未实现的接口StartRemoteServerAsync");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口StartRemoteServerAsync");
await Task.CompletedTask;
}
public void StopRemoteServer()
{
Console.WriteLine("远程环境尚未实现的接口StopRemoteServer");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口StopRemoteServer");
}
public async Task<SereinProjectData> GetProjectInfoAsync()
@@ -119,7 +135,7 @@ namespace Serein.NodeFlow.Env
/// <param name="filePath"></param>
public void LoadProject(FlowEnvInfo flowEnvInfo, string filePath)
{
Console.WriteLine("加载远程环境");
this.WriteLine(InfoType.INFO, "加载远程环境");
IsLoadingProject = true;
#region DLL功能区创建
var libmds = flowEnvInfo.LibraryMds;
@@ -339,7 +355,7 @@ namespace Serein.NodeFlow.Env
FromExistInTo = ToOnF.Length > 0;
if (ToExistOnFrom && FromExistInTo)
{
Console.WriteLine("起始节点已与目标节点存在连接");
this.WriteLine(InfoType.ERROR, "起始节点已与目标节点存在连接");
//return;
}
@@ -348,13 +364,13 @@ namespace Serein.NodeFlow.Env
// 检查是否可能存在异常
if (!ToExistOnFrom && FromExistInTo)
{
Console.WriteLine("目标节点不是起始节点的子节点,起始节点却是目标节点的父节点");
this.WriteLine(InfoType.ERROR, "目标节点不是起始节点的子节点,起始节点却是目标节点的父节点");
return;
}
else if (ToExistOnFrom && !FromExistInTo)
{
//
Console.WriteLine(" 起始节点不是目标节点的父节点,目标节点却是起始节点的子节点");
this.WriteLine(InfoType.ERROR, " 起始节点不是目标节点的父节点,目标节点却是起始节点的子节点");
return;
}
else // if (!ToExistOnFrom && !FromExistInTo)
@@ -394,25 +410,25 @@ namespace Serein.NodeFlow.Env
public void ExitRemoteEnv()
{
Console.WriteLine("远程环境尚未实现的接口ExitRemoteEnv");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口ExitRemoteEnv");
}
public void LoadLibrary(string dllPath)
{
// 将dll文件发送到远程环境由远程环境进行加载
Console.WriteLine("远程环境尚未实现的接口LoadDll");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口LoadDll");
}
public bool UnloadLibrary(string assemblyName)
{
// 尝试移除远程环境中的加载了的依赖
Console.WriteLine("远程环境尚未实现的接口RemoteDll");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口RemoteDll");
return false;
}
public void ClearAll()
{
Console.WriteLine("远程环境尚未实现的接口ClearAll");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口ClearAll");
}
public async Task StartAsync()
@@ -467,7 +483,7 @@ namespace Serein.NodeFlow.Env
public async Task<object> InvokeNodeAsync(IDynamicContext context, string nodeGuid)
{
Console.WriteLine("远程环境尚未实现接口 InvokeNodeAsync");
this.WriteLine(InfoType.INFO, "远程环境尚未实现接口 InvokeNodeAsync");
_ = msgClient.SendAsync(EnvMsgTheme.SetStartNode, new
{
nodeGuid
@@ -717,7 +733,7 @@ namespace Serein.NodeFlow.Env
}
else
{
Console.WriteLine("删除失败");
this.WriteLine(InfoType.ERROR, "删除失败");
}
return result;
}
@@ -763,7 +779,7 @@ namespace Serein.NodeFlow.Env
public void SetMonitorObjState(string key, bool isMonitor)
{
Console.WriteLine("远程环境尚未实现的接口SetMonitorObjState");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口SetMonitorObjState");
}
public async Task<(bool, string[])> CheckObjMonitorStateAsync(string key)
@@ -788,20 +804,20 @@ namespace Serein.NodeFlow.Env
public async Task<ChannelFlowInterrupt.CancelType> GetOrCreateGlobalInterruptAsync()
{
await Console.Out.WriteLineAsync("远程环境尚未实现的接口GetOrCreateGlobalInterruptAsync");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口GetOrCreateGlobalInterruptAsync");
return ChannelFlowInterrupt.CancelType.Error;
}
public bool TryGetMethodDetailsInfo(string libraryName, string methodName, out MethodDetailsInfo mdInfo)
{
Console.WriteLine("远程环境尚未实现的接口TryGetMethodDetailsInfo");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口TryGetMethodDetailsInfo");
mdInfo = null;
return false;
}
public bool TryGetDelegateDetails(string libraryName, string methodName, out DelegateDetails del)
{
Console.WriteLine("远程环境尚未实现的接口TryGetDelegateDetails");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口TryGetDelegateDetails");
del = null;
return false;
}
@@ -810,13 +826,13 @@ namespace Serein.NodeFlow.Env
public void MonitorObjectNotification(string nodeGuid, object monitorData, MonitorObjectEventArgs.ObjSourceType sourceType)
{
Console.WriteLine("远程环境尚未实现的接口MonitorObjectNotification");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口MonitorObjectNotification");
}
public void TriggerInterrupt(string nodeGuid, string expression, InterruptTriggerEventArgs.InterruptTriggerType type)
{
Console.WriteLine("远程环境尚未实现的接口TriggerInterrupt");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口TriggerInterrupt");
}
public void NodeLocated(string nodeGuid)
@@ -832,7 +848,7 @@ namespace Serein.NodeFlow.Env
{
return;
}
Console.WriteLine($"通知远程环境修改节点数据:{nodeGuid},name:{path},value:{value}");
this.WriteLine(InfoType.INFO, $"通知远程环境修改节点数据:{nodeGuid},name:{path},value:{value}");
_ = msgClient.SendAsync(EnvMsgTheme.ValueNotification, new
{
@@ -852,7 +868,7 @@ namespace Serein.NodeFlow.Env
/// <returns></returns>
public async Task<bool> ChangeParameter(string nodeGuid, bool isAdd, int paramIndex)
{
Console.WriteLine("远程环境尚未实现的接口ChangeParameter");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口ChangeParameter");
return false;
}
@@ -865,7 +881,7 @@ namespace Serein.NodeFlow.Env
/// <returns></returns>
public bool LoadNativeLibraryOfRuning(string file)
{
Console.WriteLine("远程环境尚未实现的接口LoadNativeLibraryOfRuning");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口LoadNativeLibraryOfRuning");
return false;
}
@@ -876,7 +892,7 @@ namespace Serein.NodeFlow.Env
/// <param name="isRecurrence">是否递归加载</param>
public void LoadAllNativeLibraryOfRuning(string path, bool isRecurrence = true)
{
Console.WriteLine("远程环境尚未实现的接口LoadAllNativeLibraryOfRuning");
this.WriteLine(InfoType.INFO, "远程环境尚未实现的接口LoadAllNativeLibraryOfRuning");
}
#endregion

View File

@@ -290,7 +290,7 @@ namespace Serein.NodeFlow
finally
{
env.FlowState = RunState.Completion;
Console.WriteLine($"流程运行完毕{Environment.NewLine}");;
SereinEnv.WriteLine(InfoType.INFO, $"流程运行完毕{Environment.NewLine}");;
}
#endregion
}
@@ -355,14 +355,15 @@ namespace Serein.NodeFlow
{
if(_flipFlopCts is null)
{
Console.WriteLine("flowStarter -> FlipflopExecuteAsync -> _flipFlopCts is null");
SereinEnv.WriteLine(InfoType.INFO, "流程尚未启动flowStarter尚未创建无法启动该节点");
return;
}
while (!_flipFlopCts.IsCancellationRequested && !cts.IsCancellationRequested)
{
var context = new DynamicContext(env); // 启动全局触发器时新建上下文
try
{
var context = new DynamicContext(env); // 启动全局触发器时新建上下文
var newFlowData = await singleFlipFlopNode.ExecutingAsync(context); // 获取触发器等待Task
context.AddOrUpdate(singleFlipFlopNode.Guid, newFlowData);
await NodeModelBase.RefreshFlowDataAndExpInterrupt(context, singleFlipFlopNode, newFlowData); // 全局触发器触发后刷新该触发器的节点数据

View File

@@ -1,5 +1,6 @@
using Serein.Library;
using Serein.Library.Api;
using Serein.Library.Utils;
namespace Serein.NodeFlow.Model
@@ -34,7 +35,7 @@ namespace Serein.NodeFlow.Model
/// </summary>
public override void OnCreating()
{
Console.WriteLine("CompositeConditionNode 暂未实现 OnLoading");
SereinEnv.WriteLine(InfoType.WARN, "CompositeConditionNode 暂未实现 OnLoading");
}
public void AddNode(SingleConditionNode node)
@@ -72,7 +73,7 @@ namespace Serein.NodeFlow.Model
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
SereinEnv.WriteLine(InfoType.WARN, ex.Message);
context.NextOrientation = ConnectionInvokeType.IsError;
context.ExceptionOfRuning = ex;
return context.TransmissionData(this); // 条件区域透传上一节点的数据

View File

@@ -19,7 +19,6 @@ namespace Serein.NodeFlow.Model
/// </summary>
public override void OnCreating()
{
// Console.WriteLine("SingleActionNode 暂未实现 OnLoading");
}
public override ParameterData[] GetParameterdatas()

View File

@@ -110,8 +110,8 @@ namespace Serein.NodeFlow.Model
context.NextOrientation = ConnectionInvokeType.IsError;
context.ExceptionOfRuning = ex;
}
Console.WriteLine($"{result} {Expression} -> " + context.NextOrientation);
SereinEnv.WriteLine(InfoType.INFO, $"{result} {Expression} -> " + context.NextOrientation);
return result;
}

View File

@@ -81,7 +81,6 @@ namespace Serein.NodeFlow.Model
try
{
var newData = SerinExpressionEvaluator.Evaluate(Expression, parameter, out bool isChange);
Console.WriteLine(newData);
object? result = null;
if (isChange)
{

View File

@@ -21,7 +21,6 @@ namespace Serein.NodeFlow.Model
/// </summary>
public override void OnCreating()
{
// Console.WriteLine("SingleFlipflopNode 暂未实现 OnLoading");
}

View File

@@ -1,4 +1,5 @@
using Serein.Library;
using Serein.Library.Utils;
using Serein.NodeFlow.Tool;
using System;
using System.Collections.Concurrent;
@@ -104,109 +105,97 @@ namespace Serein.NodeFlow
var loaderExceptions = ex.LoaderExceptions;
foreach (var loaderException in loaderExceptions)
{
Console.WriteLine(loaderException.Message);
SereinEnv.WriteLine(InfoType.ERROR, loaderException.Message);
}
return false;
}
#endregion
try
#region DynamicFlow 退
// Type 具有 DynamicFlowAttribute 标记的类型
// string 类型元数据 DynamicFlowAttribute 特性中的 Name 属性 (用于生成方法描述时,添加在方法别名中提高可读性)
List<(Type Type, string Name)> scanTypes = new List<(Type Type, string Name)>();
// (Type, string)
// Type 具有 DynamicFlowAttribute 标记的类型
// string 类型元数据 DynamicFlowAttribute 特性中的 Name 属性
types = types.Where(type => type.GetCustomAttribute<DynamicFlowAttribute>() is DynamicFlowAttribute dynamicFlowAttribute
&& dynamicFlowAttribute.Scan).ToList();
foreach (var type in types)
{
#region DynamicFlow 退
// Type 具有 DynamicFlowAttribute 标记的类型
// string 类型元数据 DynamicFlowAttribute 特性中的 Name 属性 (用于生成方法描述时,添加在方法别名中提高可读性)
List<(Type Type, string Name)> scanTypes = new List<(Type Type, string Name)>();
// (Type, string)
// Type 具有 DynamicFlowAttribute 标记的类型
// string 类型元数据 DynamicFlowAttribute 特性中的 Name 属性
types = types.Where(type => type.GetCustomAttribute<DynamicFlowAttribute>() is DynamicFlowAttribute dynamicFlowAttribute
&& dynamicFlowAttribute.Scan).ToList();
foreach (var type in types)
if (type.GetCustomAttribute<DynamicFlowAttribute>() is DynamicFlowAttribute dynamicFlowAttribute)
{
if (type.GetCustomAttribute<DynamicFlowAttribute>() is DynamicFlowAttribute dynamicFlowAttribute)
{
scanTypes.Add((type, dynamicFlowAttribute.Name));
}
scanTypes.Add((type, dynamicFlowAttribute.Name));
}
if (scanTypes.Count == 0)
{
// 类型没有流程控制器
return false;
}
#endregion
#region
// 从 scanTypes.Type 创建的方法信息
// Md : 方法描述
// Dd 方法对应的Emit委托
List<(MethodDetails Md, DelegateDetails Dd)> detailss = new List<(MethodDetails Md, DelegateDetails Dd)>();
// 遍历扫描的类型
foreach ((var type, var flowName) in scanTypes)
{
var methodInfos = NodeMethodDetailsHelper.GetMethodsToProcess(type);
foreach (var methodInfo in methodInfos) // 遍历流程控制器类型中的方法信息
{
// 尝试创建
if (!NodeMethodDetailsHelper.TryCreateDetails(type, methodInfo, assemblyName,
out var md, out var dd)) // 返回的描述
{
Console.WriteLine($"无法加载方法信息:{assemblyName}-{type}-{methodInfo}");
continue;
}
md.MethodAnotherName = flowName + md.MethodAnotherName; // 方法别名
detailss.Add((md, dd));
}
}
#endregion
#region
if(detailss.Count == 0)
{
return false;
}
#region
foreach((var md,var dd) in detailss)
{
MethodDetailss.TryAdd(md.MethodName, md);
DelegateDetailss.TryAdd(md.MethodName, dd);
}
#endregion
#region
foreach (Type type in types)
{
if (type.GetCustomAttribute<AutoRegisterAttribute>() is AutoRegisterAttribute attribute)
{
if (!RegisterTypes.TryGetValue(attribute.Class, out var valus))
{
valus = new List<Type>();
RegisterTypes.TryAdd(attribute.Class, valus);
}
valus.Add(type);
}
}
#endregion
#endregion
return true;
}
catch (Exception ex)
if (scanTypes.Count == 0)
{
Console.WriteLine(ex.ToString());
// 类型没有流程控制器
return false;
}
#endregion
#region
// 从 scanTypes.Type 创建的方法信息
// Md : 方法描述
// Dd 方法对应的Emit委托
List<(MethodDetails Md, DelegateDetails Dd)> detailss = new List<(MethodDetails Md, DelegateDetails Dd)>();
// 遍历扫描的类型
foreach ((var type, var flowName) in scanTypes)
{
var methodInfos = NodeMethodDetailsHelper.GetMethodsToProcess(type);
foreach (var methodInfo in methodInfos) // 遍历流程控制器类型中的方法信息
{
// 尝试创建
if (!NodeMethodDetailsHelper.TryCreateDetails(type, methodInfo, assemblyName,
out var md, out var dd)) // 返回的描述
{
SereinEnv.WriteLine(InfoType.ERROR, $"无法加载方法信息:{assemblyName}-{type}-{methodInfo}");
continue;
}
md.MethodAnotherName = flowName + md.MethodAnotherName; // 方法别名
detailss.Add((md, dd));
}
}
#endregion
#region
if (detailss.Count == 0)
{
return false;
}
#region
foreach ((var md, var dd) in detailss)
{
MethodDetailss.TryAdd(md.MethodName, md);
DelegateDetailss.TryAdd(md.MethodName, dd);
}
#endregion
#region
foreach (Type type in types)
{
if (type.GetCustomAttribute<AutoRegisterAttribute>() is AutoRegisterAttribute attribute)
{
if (!RegisterTypes.TryGetValue(attribute.Class, out var valus))
{
valus = new List<Type>();
RegisterTypes.TryAdd(attribute.Class, valus);
}
valus.Add(type);
}
}
#endregion
#endregion
return true;
}

View File

@@ -1,6 +1,7 @@
using Serein.Library;
using Serein.Library.Api;
using Serein.Library.FlowNode;
using Serein.Library.Utils;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -58,7 +59,7 @@ namespace Serein.NodeFlow.Tool
}
catch (Exception ex)
{
Console.WriteLine($"尝试卸载程序集[{assemblyName}]发生错误:{ex}");
SereinEnv.WriteLine(InfoType.ERROR, $"尝试卸载程序集[{assemblyName}]发生错误:{ex}");
return false;
}
@@ -210,7 +211,7 @@ namespace Serein.NodeFlow.Tool
{
return LoadAssembly(typeof(IFlowEnvironment).Assembly, () => {
//Console.WriteLine("基础模块不能卸载");
//SereinEnv.PrintInfo(InfoType.WRAN, "基础模块不能卸载");
});
}
else

View File

@@ -1,4 +1,6 @@
using System;
using Serein.Library;
using Serein.Library.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -58,7 +60,7 @@ namespace Serein.NodeFlow.Tool
}
else
{
Console.WriteLine("Unsupported OS.");
SereinEnv.WriteLine(InfoType.ERROR, "非预期的OS系统");
return false;
}
}
@@ -82,7 +84,7 @@ namespace Serein.NodeFlow.Tool
}
else
{
Console.WriteLine("Unsupported OS.");
SereinEnv.WriteLine(InfoType.ERROR, "非预期的OS系统");
}
foreach (var dir in Directory.GetDirectories(path))
@@ -108,18 +110,18 @@ namespace Serein.NodeFlow.Tool
if (hModule != IntPtr.Zero)
{
Nints.Add(hModule);
Console.WriteLine($"Loaded: {file}");
SereinEnv.WriteLine(InfoType.INFO, $"Loaded: {file}");
return true;
}
else
{
Console.WriteLine($"Failed to load {file}: {Marshal.GetLastWin32Error()}");
SereinEnv.WriteLine(InfoType.INFO, $"Failed to load {file}: {Marshal.GetLastWin32Error()}");
return false;
}
}
catch (Exception ex)
{
Console.WriteLine($"Error loading {file}: {ex.Message}");
SereinEnv.WriteLine(InfoType.ERROR, $"Error loading {file}: {ex.Message}");
return false;
}
}
@@ -140,20 +142,20 @@ namespace Serein.NodeFlow.Tool
if (handle != IntPtr.Zero)
{
Nints.Add(handle);
Console.WriteLine($"Loaded: {file}");
SereinEnv.WriteLine(InfoType.INFO, $"Loaded: {file}");
return true;
// 可以调用共享库中的函数
// IntPtr procAddress = dlsym(handle, "my_function");
}
else
{
Console.WriteLine($"Failed to load {file}: {Marshal.GetLastWin32Error()}");
SereinEnv.WriteLine(InfoType.INFO, $"Failed to load {file}: {Marshal.GetLastWin32Error()}");
return false;
}
}
catch (Exception ex)
{
Console.WriteLine($"Error loading {file}: {ex.Message}");
SereinEnv.WriteLine(InfoType.ERROR, $"Error loading {file}: {ex.Message}");
return false;
}

View File

@@ -46,8 +46,8 @@ public static class NodeMethodDetailsHelper
return false;
}
var methodName = $"{assemblyName}.{type.Name}.{methodInfo.Name}";
Console.WriteLine("loading method : " + methodName);
var methodName = $"{assemblyName}.{type.Name}.{methodInfo.Name}";
SereinEnv.WriteLine(InfoType.INFO, "loading method : " + methodName);
// 创建参数信息
var explicitDataOfParameters = GetExplicitDataOfParameters(methodInfo.GetParameters());
@@ -78,7 +78,7 @@ public static class NodeMethodDetailsHelper
}
else
{
Console.WriteLine($"[{methodName}]跳过创建返回类型非预期的Task<IFlipflopContext<TResult>>。");
SereinEnv.WriteLine(InfoType.WARN, $"[{methodName}]跳过创建返回类型非预期的Task<IFlipflopContext<TResult>>。");
methodDetails = null;
delegateDetails = null;
return false;
@@ -86,7 +86,7 @@ public static class NodeMethodDetailsHelper
}
else
{
Console.WriteLine($"[{methodName}]跳过创建因为触发器方法的返回值并非Task<>,将无法等待。");
SereinEnv.WriteLine(InfoType.WARN, $"[{methodName}]跳过创建因为触发器方法的返回值并非Task<>,将无法等待。");
methodDetails = null;
delegateDetails = null;
return false;

View File

@@ -1,4 +1,6 @@
using System.Reflection;
using Serein.Library;
using Serein.Library.Utils;
using System.Reflection;
using System.Reflection.Emit;
@@ -31,31 +33,31 @@ namespace Serein.NodeFlow.Tool
foreach (var prop in objType.GetProperties())
{
var value = prop.GetValue(obj);
Console.WriteLine($"{indent}{prop.Name} (Type: {prop.PropertyType.Name}): {value}");
SereinEnv.WriteLine(InfoType.INFO, $"{indent}{prop.Name} (Type: {prop.PropertyType.Name}): {value}");
if (value != null)
{
if (prop.PropertyType.IsArray) // 处理数组类型
{
var array = (Array)value;
Console.WriteLine($"{indent}{prop.Name} is an array with {array.Length} elements:");
SereinEnv.WriteLine(InfoType.INFO, $"{indent}{prop.Name} is an array with {array.Length} elements:");
for (int i = 0; i < array.Length; i++)
{
var element = array.GetValue(i);
if (element != null && element.GetType().IsClass && !(element is string))
{
Console.WriteLine($"{indent}\tArray[{i}] (Type: {element.GetType().Name}) contains a nested object:");
SereinEnv.WriteLine(InfoType.INFO, $"{indent}\tArray[{i}] (Type: {element.GetType().Name}) contains a nested object:");
PrintObjectProperties(element, indent + "\t\t");
}
else
{
Console.WriteLine($"{indent}\tArray[{i}] (Type: {element?.GetType().Name}): {element}");
SereinEnv.WriteLine(InfoType.INFO, $"{indent}\tArray[{i}] (Type: {element?.GetType().Name}): {element}");
}
}
}
else if (value.GetType().IsClass && !(value is string)) // 处理嵌套对象
{
Console.WriteLine($"{indent}{prop.Name} contains a nested object:");
SereinEnv.WriteLine(InfoType.INFO, $"{indent}{prop.Name} contains a nested object:");
PrintObjectProperties(value, indent + "\t");
}
}
@@ -193,7 +195,7 @@ namespace Serein.NodeFlow.Tool
if (propInfo == null)
{
// 属性不存在,打印警告并标记失败
Console.WriteLine($"Warning: 属性 '{propName}' 不存在于类型 '{objType.Name}' 中,跳过赋值。");
SereinEnv.WriteLine(InfoType.WARN, $"属性 '{propName}' 不存在于类型 '{objType.Name}' 中,跳过赋值。");
allSuccessful = false;
continue;
}
@@ -203,7 +205,7 @@ namespace Serein.NodeFlow.Tool
if (!IsCompatibleType(targetType, propValue))
{
// 如果类型不兼容,打印错误并标记失败
Console.WriteLine($"Error: 无法将类型 '{propValue?.GetType().Name}' 赋值给属性 '{propName}' (Type: {targetType.Name}),跳过赋值。");
SereinEnv.WriteLine(InfoType.WARN, $"无法将类型 '{propValue?.GetType().Name}' 赋值给属性 '{propName}' (Type: {targetType.Name}),跳过赋值。");
allSuccessful = false;
continue;
}
@@ -254,7 +256,7 @@ namespace Serein.NodeFlow.Tool
}
catch (Exception ex)
{
Console.WriteLine($"Error: 为属性 '{propName}' 赋值时发生异常:{ex.Message}");
SereinEnv.WriteLine(InfoType.ERROR, $"为属性 '{propName}' 赋值时发生异常:{ex.Message}");
allSuccessful = false;
}
}