using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Serein.Library;
using Serein.Library.Api;
using Serein.Library.Core;
using Serein.Library.FlowNode;
using Serein.Library.Utils;
using Serein.Library.Utils.SereinExpression;
using Serein.NodeFlow.Model;
using Serein.NodeFlow.Tool;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Numerics;
using System.Reflection;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.Loader;
using System.Security.AccessControl;
using System.Text;
using System.Xml.Linq;
using static Serein.Library.Utils.ChannelFlowInterrupt;
namespace Serein.NodeFlow.Env
{
///
/// 运行环境
///
public class FlowEnvironment : IFlowEnvironment, ISereinIOC
{
///
/// 节点的命名空间
///
public const string SpaceName = $"{nameof(Serein)}.{nameof(NodeFlow)}.{nameof(Model)}";
public const string ThemeKey = "theme";
public const string DataKey = "data";
public const string MsgIdKey = "msgid";
///
/// 流程运行环境
///
public FlowEnvironment(UIContextOperation uiContextOperation)
{
this.sereinIOC = new SereinIOC();
this.ChannelFlowInterrupt = new ChannelFlowInterrupt();
this.IsGlobalInterrupt = false;
this.flowStarter = null;
this.sereinIOC.OnIOCMembersChanged += e =>
{
if (OperatingSystem.IsWindows())
{
UIContextOperation?.Invoke(() => this?.OnIOCMembersChanged?.Invoke(e)); // 监听IOC容器的注册
}
};
this.UIContextOperation = uiContextOperation; // 为加载的类库提供在UI线程上执行某些操作的封装工具类
this.FlowLibraryManagement = new FlowLibraryManagement(this); // 实例化类库管理
#region 注册基本节点类型
NodeMVVMManagement.RegisterModel(NodeControlType.Action, typeof(SingleActionNode)); // 动作节点
NodeMVVMManagement.RegisterModel(NodeControlType.Flipflop, typeof(SingleFlipflopNode)); // 触发器节点
NodeMVVMManagement.RegisterModel(NodeControlType.ExpOp, typeof(SingleExpOpNode)); // 表达式节点
NodeMVVMManagement.RegisterModel(NodeControlType.ExpCondition, typeof(SingleConditionNode)); // 条件表达式节点
NodeMVVMManagement.RegisterModel(NodeControlType.ConditionRegion, typeof(CompositeConditionNode)); // 条件区域
NodeMVVMManagement.RegisterModel(NodeControlType.GlobalData, typeof(SingleGlobalDataNode)); // 全局数据节点
#endregion
}
#region 远程管理
private MsgControllerOfServer clientMsgManage;
///
/// 表示是否正在控制远程
/// Local control remote env
///
public bool IsControlRemoteEnv { get; set; }
///
/// 打开远程管理
///
///
public async Task StartRemoteServerAsync(int port = 7525)
{
if (clientMsgManage is null)
{
clientMsgManage = new MsgControllerOfServer(this);
//clientMsgManage = new MsgControllerOfServer(this,"123456");
}
_ = clientMsgManage.StartRemoteServerAsync(port);
}
///
/// 结束远程管理
///
public void StopRemoteServer()
{
try
{
clientMsgManage.StopRemoteServer();
}
catch (Exception ex)
{
SereinEnv.WriteLine(InfoType.ERROR, "结束远程管理异常:" + ex);
}
}
#endregion
#region 环境运行事件
///
/// 加载Dll
///
public event LoadDllHandler? OnDllLoad;
///
/// 移除DLL
///
public event RemoteDllHandler? OnDllRemote;
///
/// 项目加载完成
///
public event ProjectLoadedHandler? OnProjectLoaded;
///
/// 项目准备保存
///
public event ProjectSavingHandler? OnProjectSaving;
///
/// 节点连接属性改变事件
///
public event NodeConnectChangeHandler? OnNodeConnectChange;
///
/// 节点创建事件
///
public event NodeCreateHandler? OnNodeCreate;
///
/// 移除节点事件
///
public event NodeRemoveHandler? OnNodeRemove;
///
/// 起始节点变化事件
///
public event StartNodeChangeHandler? OnStartNodeChange;
///
/// 流程运行完成事件
///
public event FlowRunCompleteHandler? OnFlowRunComplete;
///
/// 被监视的对象改变事件
///
public event MonitorObjectChangeHandler? OnMonitorObjectChange;
///
/// 节点中断状态改变事件
///
public event NodeInterruptStateChangeHandler? OnNodeInterruptStateChange;
///
/// 节点触发了中断
///
public event ExpInterruptTriggerHandler? OnInterruptTrigger;
///
/// 容器改变
///
public event IOCMembersChangedHandler? OnIOCMembersChanged;
///
/// 节点需要定位
///
public event NodeLocatedHandler? OnNodeLocated;
///
/// 节点移动了(远程插件)
///
public event NodeMovedHandler? OnNodeMoved;
///
/// 运行环境输出
///
public event EnvOutHandler? OnEnvOut;
#endregion
#region 属性
///
/// 当前环境
///
public IFlowEnvironment CurrentEnv { get => this; }
///
/// UI线程操作类
///
public UIContextOperation UIContextOperation { get; set; }
///
/// 信息输出等级
///
public InfoClass InfoClass { get ; set ; } = InfoClass.Trivial;
///
/// 如果没有全局触发器,且没有循环分支,流程执行完成后自动为 Completion 。
///
public RunState FlowState { get; set; } = RunState.NoStart;
///
/// 如果全局触发器还在运行,则为 Running 。
///
public RunState FlipFlopState { get; set; } = RunState.NoStart;
///
/// 环境名称
///
public string EnvName { get; set; } = SpaceName;
///
/// 是否全局中断
///
public bool IsGlobalInterrupt { get; set; }
///
/// 流程中断器
///
public ChannelFlowInterrupt ChannelFlowInterrupt { get; set; }
///
/// 单例模式IOC容器,内部维护了一个实例字典,默认使用类型的FullName作为Key,如果以“接口-实现类”的方式注册,那么将使用接口类型的FullName作为Key。
/// 当某个类型注册绑定成功后,将不会因为其它地方尝试注册相同类型的行为导致类型被重新创建。
///
public ISereinIOC IOC { get => this; }
#endregion
#region 私有变量
///
/// 通过程序集名称管理动态加载的程序集,用于节点创建提供方法描述,流程运行时提供Emit委托
///
private readonly FlowLibraryManagement FlowLibraryManagement;
#if false
///
/// Library 与 MethodDetailss的依赖关系
///
public ConcurrentDictionary> MethodDetailsOfLibraryInfos { get; } = [];
///
/// 存储已加载的程序集
/// Key:程序集的FullName
/// Value:构造的方法信息
///
public ConcurrentDictionary LibraryInfos { get; } = [];
///
/// 存储已加载的方法信息。描述所有DLL中NodeAction特性的方法的原始副本
/// Key:反射时获取的MethodInfo.MehtodName
/// Value:构造的方法信息
///
public ConcurrentDictionary MethodDetailss { get; } = [];
///
/// 从dll中加载的类的注册类型
///
private Dictionary> AutoRegisterTypes { get; } = [];
///
/// 存放所有通过Emit加载的委托
/// md.Methodname - delegate
///
private ConcurrentDictionary MethodDelegates { get; } = [];
#endif
///
/// IOC对象容器管理
///
private readonly SereinIOC sereinIOC;
///
/// 环境加载的节点集合
/// Node Guid - Node Model
///
private Dictionary NodeModels { get; } = [];
///
/// 存放触发器节点(运行时全部调用)
///
private List FlipflopNodes { get; } = [];
///
/// 起始节点私有属性
///
private NodeModelBase? _startNode = null;
///
/// 起始节点
///
private NodeModelBase? StartNode
{
get
{
return _startNode;
}
set
{
if (value is null)
{
return;
}
if (_startNode is not null)
{
_startNode.IsStart = false;
}
value.IsStart = true;
_startNode = value;
}
}
///
/// 流程启动器(每次运行时都会重新new一个)
///
private FlowStarter? flowStarter;
#endregion
#region 环境对外接口
/////
///// 重定向Console输出
/////
//public void SetConsoleOut()
//{
// var logTextWriter = new LogTextWriter(msg => Output(msg));
// Console.SetOut(logTextWriter);
//}
///
/// 输出信息
///
/// 日志内容
/// 日志类别
/// 日志级别
public void WriteLine(InfoType type, string message, InfoClass @class = InfoClass.Trivial)
{
if (@class >= this.InfoClass)
{
OnEnvOut?.Invoke(type, message);
}
//Console.WriteLine($"{DateTime.UtcNow} [{type}] : {message}{Environment.NewLine}");
}
/////
///// 使用JSON处理库输出对象信息
/////
/////
//public void WriteLineObjToJson(object obj)
//{
// var msg = JsonConvert.SerializeObject(obj);
// if (OperatingSystem.IsWindows())
// {
// UIContextOperation?.Invoke(() => OnEnvOut?.Invoke(msg + Environment.NewLine));
// }
//}
///
/// 异步运行
///
///
public async Task StartAsync()
{
ChannelFlowInterrupt?.CancelAllTasks();
flowStarter = new FlowStarter();
var nodes = NodeModels.Values.ToList();
List initMethods = this.FlowLibraryManagement.GetMdsOnFlowStart(NodeType.Init);
List loadMethods = this.FlowLibraryManagement.GetMdsOnFlowStart(NodeType.Loading);
List exitMethods = this.FlowLibraryManagement.GetMdsOnFlowStart(NodeType.Exit);
Dictionary> autoRegisterTypes = this.FlowLibraryManagement.GetaAutoRegisterType();
IOC.Reset(); // 开始运行时清空ioc中注册的实例
IOC.CustomRegisterInstance(typeof(IFlowEnvironment).FullName, this);
if (this.UIContextOperation is not null)
IOC.CustomRegisterInstance(typeof(UIContextOperation).FullName, this.UIContextOperation, false);
await flowStarter.RunAsync(this, nodes, autoRegisterTypes, initMethods, loadMethods, exitMethods);
if (FlipFlopState == RunState.Completion)
{
ExitFlow(); // 未运行触发器时,才会调用结束方法
}
}
///
/// 从选定节点开始运行
///
///
///
public async Task StartAsyncInSelectNode(string startNodeGuid)
{
if (flowStarter is null)
{
SereinEnv.WriteLine(InfoType.ERROR, "没有启动流程,无法运行单个节点");
return;
}
if (true || FlowState == RunState.Running || FlipFlopState == RunState.Running)
{
NodeModelBase? nodeModel = GuidToModel(startNodeGuid);
if (nodeModel is null || nodeModel is SingleFlipflopNode)
{
return;
}
//var getExp = "@get .DebugSetting.IsEnable";
//var getExpResult1 = SerinExpressionEvaluator.Evaluate(getExp, nodeModel,out _);
//var setExp = "@set .DebugSetting.IsEnable = false";
//SerinExpressionEvaluator.Evaluate(setExp, nodeModel,out _);
//var getExpResult2 = SerinExpressionEvaluator.Evaluate(getExp, nodeModel, out _);
await flowStarter.StartFlowInSelectNodeAsync(this, nodeModel);
}
else
{
return;
}
}
///
/// 单独运行一个节点
///
///
///
public async Task