mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-04-11 10:26:34 +08:00
1. 重新设计了Generate项目及相关特性的命名,避免与其他类型混淆。
2. 补充了部分注释。 3. 修改了删除容器节点时,容器内子节点未正确删除的问题。
This commit is contained in:
@@ -54,11 +54,12 @@ namespace Serein.NodeFlow.Env
|
||||
|
||||
|
||||
|
||||
private FlowWorkManagement flowWorkManagement;
|
||||
private ISereinIOC externalIOC;
|
||||
private Action<ISereinIOC> setDefultMemberOnReset;
|
||||
private FlowWorkManagement? flowWorkManagement;
|
||||
private ISereinIOC? externalIOC;
|
||||
private Action<ISereinIOC>? setDefultMemberOnReset;
|
||||
private bool IsUseExternalIOC = false;
|
||||
private object lockObj = new object();
|
||||
private readonly object lockObj = new object();
|
||||
|
||||
/// <summary>
|
||||
/// 如果全局触发器还在运行,则为 Running 。
|
||||
/// </summary>
|
||||
@@ -313,7 +314,7 @@ namespace Serein.NodeFlow.Env
|
||||
}*/
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void UseExternalIOC(ISereinIOC ioc, Action<ISereinIOC> setDefultMemberOnReset = null)
|
||||
public void UseExternalIOC(ISereinIOC ioc, Action<ISereinIOC>? setDefultMemberOnReset = null)
|
||||
{
|
||||
IOC = ioc; // 设置IOC容器
|
||||
this.setDefultMemberOnReset = setDefultMemberOnReset;
|
||||
|
||||
@@ -4,12 +4,13 @@ using Serein.Library.Api;
|
||||
using Serein.Library.Utils;
|
||||
using Serein.NodeFlow.Model;
|
||||
using Serein.NodeFlow.Model.Nodes;
|
||||
using Serein.NodeFlow.Model.Operation;
|
||||
using Serein.NodeFlow.Model.Operations;
|
||||
using Serein.NodeFlow.Services;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Threading.Tasks;
|
||||
using static Serein.Library.Api.IFlowEnvironment;
|
||||
using IOperation = Serein.NodeFlow.Model.Operation.IOperation;
|
||||
using IOperation = Serein.NodeFlow.Model.Operations.IOperation;
|
||||
|
||||
namespace Serein.NodeFlow.Env
|
||||
{
|
||||
@@ -47,7 +48,7 @@ namespace Serein.NodeFlow.Env
|
||||
private readonly FlowLibraryService flowLibraryManagement;
|
||||
private readonly FlowOperationService flowOperationService;
|
||||
private readonly FlowModelService flowModelService;
|
||||
private readonly NodeMVVMService nodeMVVMService;
|
||||
//private readonly NodeMVVMService nodeMVVMService;
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -74,17 +75,23 @@ namespace Serein.NodeFlow.Env
|
||||
/// <summary>
|
||||
/// 从Guid获取画布
|
||||
/// </summary>
|
||||
/// <param name="nodeGuid">节点Guid</param>
|
||||
/// <returns>节点Model</returns>
|
||||
/// <exception cref="ArgumentNullException">无法获取节点、Guid/节点为null时报错</exception>
|
||||
public bool TryGetCanvasModel(string nodeGuid, out FlowCanvasDetails canvasDetails)
|
||||
/// <param name="nodeGuid">画布Guid</param>
|
||||
/// <param name="canvasDetails">画布model</param>
|
||||
/// <returns>是否获取成功</returns>
|
||||
public bool TryGetCanvasModel(string nodeGuid, [NotNullWhen(true)] out FlowCanvasDetails? canvasDetails)
|
||||
{
|
||||
if (string.IsNullOrEmpty(nodeGuid))
|
||||
{
|
||||
canvasDetails = null;
|
||||
canvasDetails = default;
|
||||
return false;
|
||||
}
|
||||
return flowModelService.TryGetCanvasModel(nodeGuid, out canvasDetails);
|
||||
if(flowModelService.TryGetCanvasModel(nodeGuid, out var flowCanvas))
|
||||
{
|
||||
canvasDetails = flowCanvas;
|
||||
return true;
|
||||
}
|
||||
canvasDetails = default;
|
||||
return false ;
|
||||
|
||||
}
|
||||
|
||||
@@ -92,9 +99,9 @@ namespace Serein.NodeFlow.Env
|
||||
/// 从Guid获取节点
|
||||
/// </summary>
|
||||
/// <param name="nodeGuid">节点Guid</param>
|
||||
/// <returns>节点Model</returns>
|
||||
/// <exception cref="ArgumentNullException">无法获取节点、Guid/节点为null时报错</exception>
|
||||
public bool TryGetNodeModel(string nodeGuid, out IFlowNode nodeModel)
|
||||
/// <param name="nodeModel">节点Model</param>
|
||||
/// <returns>是否获取成功</returns>
|
||||
public bool TryGetNodeModel(string nodeGuid, [NotNullWhen(true)]out IFlowNode? nodeModel)
|
||||
{
|
||||
if (string.IsNullOrEmpty(nodeGuid))
|
||||
{
|
||||
@@ -176,7 +183,7 @@ namespace Serein.NodeFlow.Env
|
||||
/// <summary>
|
||||
/// 创建节点
|
||||
/// </summary>
|
||||
/// <param name="nodeBase"></param>
|
||||
/// <param name="nodeModel"></param>
|
||||
private bool TryAddNode(IFlowNode nodeModel)
|
||||
{
|
||||
nodeModel.Guid ??= Guid.NewGuid().ToString();
|
||||
@@ -218,7 +225,7 @@ namespace Serein.NodeFlow.Env
|
||||
}
|
||||
};
|
||||
|
||||
flowOperationService.Execute(operation);
|
||||
_ = flowOperationService.Execute(operation);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void RemoveCanvas(string canvasGuid)
|
||||
@@ -227,7 +234,7 @@ namespace Serein.NodeFlow.Env
|
||||
{
|
||||
CanvasGuid = canvasGuid
|
||||
};
|
||||
flowOperationService.Execute(operation);
|
||||
_ = flowOperationService.Execute(operation);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void ConnectInvokeNode(string canvasGuid, string fromNodeGuid, string toNodeGuid, JunctionType fromNodeJunctionType, JunctionType toNodeJunctionType, ConnectionInvokeType invokeType)
|
||||
@@ -244,7 +251,7 @@ namespace Serein.NodeFlow.Env
|
||||
JunctionOfConnectionType = JunctionOfConnectionType.Invoke,
|
||||
};
|
||||
|
||||
flowOperationService.Execute(operation);
|
||||
_ = flowOperationService.Execute(operation);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void ConnectArgSourceNode(string canvasGuid, string fromNodeGuid, string toNodeGuid, JunctionType fromNodeJunctionType, JunctionType toNodeJunctionType, ConnectionArgSourceType argSourceType, int argIndex)
|
||||
@@ -261,7 +268,7 @@ namespace Serein.NodeFlow.Env
|
||||
ChangeType = NodeConnectChangeEventArgs.ConnectChangeType.Create,
|
||||
JunctionOfConnectionType = JunctionOfConnectionType.Arg,
|
||||
};
|
||||
flowOperationService.Execute(operation);
|
||||
_ = flowOperationService.Execute(operation);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void RemoveInvokeConnect(string canvasGuid, string fromNodeGuid, string toNodeGuid, ConnectionInvokeType connectionType)
|
||||
@@ -275,7 +282,7 @@ namespace Serein.NodeFlow.Env
|
||||
ChangeType = NodeConnectChangeEventArgs.ConnectChangeType.Remove,
|
||||
JunctionOfConnectionType = JunctionOfConnectionType.Invoke,
|
||||
};
|
||||
flowOperationService.Execute(operation);
|
||||
_ = flowOperationService.Execute(operation);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void RemoveArgSourceConnect(string canvasGuid, string fromNodeGuid, string toNodeGuid, int argIndex)
|
||||
@@ -289,10 +296,10 @@ namespace Serein.NodeFlow.Env
|
||||
ChangeType = NodeConnectChangeEventArgs.ConnectChangeType.Remove,
|
||||
JunctionOfConnectionType = JunctionOfConnectionType.Arg,
|
||||
};
|
||||
flowOperationService.Execute(operation);
|
||||
_ = flowOperationService.Execute(operation);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void CreateNode(string canvasGuid, NodeControlType nodeType, PositionOfUI position, MethodDetailsInfo methodDetailsInfo = null)
|
||||
public void CreateNode(string canvasGuid, NodeControlType nodeType, PositionOfUI position, MethodDetailsInfo? methodDetailsInfo = null)
|
||||
{
|
||||
IOperation operation = new CreateNodeOperation
|
||||
{
|
||||
@@ -301,7 +308,7 @@ namespace Serein.NodeFlow.Env
|
||||
Position = position,
|
||||
MethodDetailsInfo = methodDetailsInfo
|
||||
};
|
||||
flowOperationService.Execute(operation);
|
||||
_ = flowOperationService.Execute(operation);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void RemoveNode(string canvasGuid, string nodeGuid)
|
||||
@@ -311,7 +318,7 @@ namespace Serein.NodeFlow.Env
|
||||
CanvasGuid = canvasGuid,
|
||||
NodeGuid = nodeGuid
|
||||
};
|
||||
flowOperationService.Execute(operation);
|
||||
_ = flowOperationService.Execute(operation);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void PlaceNodeToContainer(string canvasGuid, string nodeGuid, string containerNodeGuid)
|
||||
@@ -322,7 +329,7 @@ namespace Serein.NodeFlow.Env
|
||||
NodeGuid = nodeGuid,
|
||||
ContainerNodeGuid = containerNodeGuid
|
||||
};
|
||||
flowOperationService.Execute(operation);
|
||||
_ = flowOperationService.Execute(operation);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void TakeOutNodeToContainer(string canvasGuid, string nodeGuid)
|
||||
@@ -332,36 +339,17 @@ namespace Serein.NodeFlow.Env
|
||||
CanvasGuid = canvasGuid,
|
||||
NodeGuid = nodeGuid,
|
||||
};
|
||||
flowOperationService.Execute(operation);
|
||||
_ = flowOperationService.Execute(operation);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void SetStartNode(string canvasGuid, string nodeGuid)
|
||||
{
|
||||
|
||||
IOperation operation = new SetStartNodeOperation
|
||||
{
|
||||
CanvasGuid = canvasGuid,
|
||||
NewNodeGuid = nodeGuid,
|
||||
};
|
||||
_ = flowOperationService.Execute(operation);
|
||||
|
||||
return;
|
||||
if (!TryGetCanvasModel(canvasGuid, out var canvasModel) || !TryGetNodeModel(nodeGuid, out var newStartNodeModel))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var oldNodeGuid = canvasModel.StartNode?.Guid;
|
||||
/*if(TryGetNodeModel(oldNodeGuid, out var newStartNodeModel))
|
||||
{
|
||||
newStartNode.IsStart = false;
|
||||
}*/
|
||||
canvasModel.StartNode = newStartNodeModel;
|
||||
//newStartNode.IsStart = true;
|
||||
|
||||
_ = SereinEnv.TriggerEvent(() =>
|
||||
flowEnvironmentEvent.OnStartNodeChanged(
|
||||
new StartNodeChangeEventArgs(canvasGuid, oldNodeGuid, newStartNodeModel.Guid)
|
||||
));
|
||||
return;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
@@ -376,7 +364,7 @@ namespace Serein.NodeFlow.Env
|
||||
ConnectionInvokeType = connectionType,
|
||||
ChangeType = NodeConnectChangeEventArgs.ConnectChangeType.Create
|
||||
};
|
||||
flowOperationService.Execute(operation);
|
||||
_ = flowOperationService.Execute(operation);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void ChangeParameter(string nodeGuid, bool isAdd, int paramIndex)
|
||||
@@ -387,7 +375,7 @@ namespace Serein.NodeFlow.Env
|
||||
IsAdd = isAdd,
|
||||
ParamIndex = paramIndex
|
||||
};
|
||||
flowOperationService.Execute(operation);
|
||||
_ = flowOperationService.Execute(operation);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -170,7 +170,6 @@ namespace Serein.NodeFlow.Env
|
||||
return (isConnect, remoteMsgUtil);
|
||||
}*/
|
||||
|
||||
/// <inheritdoc/>
|
||||
/* public async Task<bool> ExitFlowAsync()
|
||||
{
|
||||
return await currentFlowEnvironment.FlowControl.ExitFlowAsync();
|
||||
@@ -190,9 +189,9 @@ namespace Serein.NodeFlow.Env
|
||||
}*/
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<SereinProjectData> GetProjectInfoAsync()
|
||||
public SereinProjectData GetProjectInfoAsync()
|
||||
{
|
||||
return await currentFlowEnvironment.GetProjectInfoAsync();
|
||||
return currentFlowEnvironment.GetProjectInfoAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -3,112 +3,150 @@ using Serein.Library.Api;
|
||||
|
||||
namespace Serein.NodeFlow.Env
|
||||
{
|
||||
/// <summary>
|
||||
/// 流程环境事件类
|
||||
/// </summary>
|
||||
public class FlowEnvironmentEvent : IFlowEnvironmentEvent
|
||||
{
|
||||
public event LoadDllHandler DllLoad;
|
||||
public event ProjectLoadedHandler ProjectLoaded;
|
||||
public event ProjectSavingHandler ProjectSaving;
|
||||
public event NodeConnectChangeHandler NodeConnectChanged;
|
||||
public event CanvasCreateHandler CanvasCreated;
|
||||
public event CanvasRemoveHandler CanvasRemoved;
|
||||
public event NodeCreateHandler NodeCreated;
|
||||
public event NodeRemoveHandler NodeRemoved;
|
||||
public event NodePlaceHandler NodePlace;
|
||||
public event NodeTakeOutHandler NodeTakeOut;
|
||||
public event StartNodeChangeHandler StartNodeChanged;
|
||||
public event FlowRunCompleteHandler FlowRunComplete;
|
||||
public event MonitorObjectChangeHandler MonitorObjectChanged;
|
||||
public event NodeInterruptStateChangeHandler NodeInterruptStateChanged;
|
||||
public event ExpInterruptTriggerHandler InterruptTriggered;
|
||||
public event IOCMembersChangedHandler IOCMembersChanged;
|
||||
public event NodeLocatedHandler NodeLocated;
|
||||
public event EnvOutHandler EnvOutput;
|
||||
/// <inheritdoc/>
|
||||
public event LoadDllHandler? DllLoad;
|
||||
/// <inheritdoc/>
|
||||
public event ProjectLoadedHandler? ProjectLoaded;
|
||||
/// <inheritdoc/>
|
||||
public event ProjectSavingHandler? ProjectSaving;
|
||||
/// <inheritdoc/>
|
||||
public event NodeConnectChangeHandler? NodeConnectChanged;
|
||||
/// <inheritdoc/>
|
||||
public event CanvasCreateHandler? CanvasCreated;
|
||||
/// <inheritdoc/>
|
||||
public event CanvasRemoveHandler? CanvasRemoved;
|
||||
/// <inheritdoc/>
|
||||
public event NodeCreateHandler? NodeCreated;
|
||||
/// <inheritdoc/>
|
||||
public event NodeRemoveHandler? NodeRemoved;
|
||||
/// <inheritdoc/>
|
||||
public event NodePlaceHandler? NodePlace;
|
||||
/// <inheritdoc/>
|
||||
public event NodeTakeOutHandler? NodeTakeOut;
|
||||
/// <inheritdoc/>
|
||||
public event StartNodeChangeHandler? StartNodeChanged;
|
||||
/// <inheritdoc/>
|
||||
public event FlowRunCompleteHandler? FlowRunComplete;
|
||||
/// <inheritdoc/>
|
||||
public event MonitorObjectChangeHandler? MonitorObjectChanged;
|
||||
/// <inheritdoc/>
|
||||
public event NodeInterruptStateChangeHandler? NodeInterruptStateChanged;
|
||||
/// <inheritdoc/>
|
||||
public event ExpInterruptTriggerHandler? InterruptTriggered;
|
||||
/// <inheritdoc/>
|
||||
public event IOCMembersChangedHandler? IOCMembersChanged;
|
||||
/// <inheritdoc/>
|
||||
public event NodeLocatedHandler? NodeLocated;
|
||||
/// <inheritdoc/>
|
||||
public event EnvOutHandler? EnvOutput;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnDllLoad(LoadDllEventArgs eventArgs)
|
||||
{
|
||||
DllLoad?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnProjectLoaded(ProjectLoadedEventArgs eventArgs)
|
||||
{
|
||||
ProjectLoaded?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnProjectSaving(ProjectSavingEventArgs eventArgs)
|
||||
{
|
||||
ProjectSaving?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnNodeConnectChanged(NodeConnectChangeEventArgs eventArgs)
|
||||
{
|
||||
NodeConnectChanged?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnCanvasCreated(CanvasCreateEventArgs eventArgs)
|
||||
{
|
||||
CanvasCreated?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnCanvasRemoved(CanvasRemoveEventArgs eventArgs)
|
||||
{
|
||||
CanvasRemoved?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnNodeCreated(NodeCreateEventArgs eventArgs)
|
||||
{
|
||||
NodeCreated?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnNodeRemoved(NodeRemoveEventArgs eventArgs)
|
||||
{
|
||||
NodeRemoved?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnNodePlace(NodePlaceEventArgs eventArgs)
|
||||
{
|
||||
NodePlace?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnNodeTakeOut(NodeTakeOutEventArgs eventArgs)
|
||||
{
|
||||
NodeTakeOut?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnStartNodeChanged(StartNodeChangeEventArgs eventArgs)
|
||||
{
|
||||
StartNodeChanged?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnFlowRunComplete(FlowEventArgs eventArgs)
|
||||
{
|
||||
FlowRunComplete?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnMonitorObjectChanged(MonitorObjectEventArgs eventArgs)
|
||||
{
|
||||
MonitorObjectChanged?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnNodeInterruptStateChanged(NodeInterruptStateChangeEventArgs eventArgs)
|
||||
{
|
||||
NodeInterruptStateChanged?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnInterruptTriggered(InterruptTriggerEventArgs eventArgs)
|
||||
{
|
||||
InterruptTriggered?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnIOCMembersChanged(IOCMembersChangedEventArgs eventArgs)
|
||||
{
|
||||
IOCMembersChanged?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnNodeLocated(NodeLocatedEventArgs eventArgs)
|
||||
{
|
||||
NodeLocated?.Invoke(eventArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void OnEnvOutput(InfoType type, string value)
|
||||
{
|
||||
EnvOutput?.Invoke(type, value);
|
||||
|
||||
@@ -5,6 +5,7 @@ using Serein.NodeFlow.Model.Nodes;
|
||||
using Serein.NodeFlow.Services;
|
||||
using Serein.NodeFlow.Tool;
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text;
|
||||
|
||||
namespace Serein.NodeFlow.Env
|
||||
@@ -64,7 +65,7 @@ namespace Serein.NodeFlow.Env
|
||||
/// 打开远程管理
|
||||
/// </summary>
|
||||
/// <param name="port"></param>
|
||||
public async Task StartRemoteServerAsync(int port = 7525)
|
||||
public void StartRemoteServerAsync(int port = 7525)
|
||||
{
|
||||
/*if (clientMsgManage is null)
|
||||
{
|
||||
@@ -116,7 +117,7 @@ namespace Serein.NodeFlow.Env
|
||||
/// <summary>
|
||||
/// UI线程操作类
|
||||
/// </summary>
|
||||
public UIContextOperation UIContextOperation { get; private set; }
|
||||
public UIContextOperation? UIContextOperation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 节点MVVM管理服务
|
||||
@@ -173,15 +174,10 @@ namespace Serein.NodeFlow.Env
|
||||
|
||||
#region 私有变量
|
||||
|
||||
/// <summary>
|
||||
/// 装饰器运行环境类
|
||||
/// </summary>
|
||||
private readonly IFlowEnvironment mainFlowEnvironment;
|
||||
|
||||
/// <summary>
|
||||
/// 流程运行时的IOC容器
|
||||
/// </summary>
|
||||
private ISereinIOC flowRunIOC;
|
||||
private ISereinIOC? flowRunIOC;
|
||||
|
||||
/// <summary>
|
||||
/// local环境的IOC容器,主要用于注册本地环境的服务
|
||||
@@ -203,28 +199,7 @@ namespace Serein.NodeFlow.Env
|
||||
/// </summary>
|
||||
private readonly FlowModelService _flowModelService;
|
||||
|
||||
/* /// <summary>
|
||||
/// 环境加载的节点集合
|
||||
/// Node Guid - Node Model
|
||||
/// </summary>
|
||||
private Dictionary<string, IFlowNode> NodeModels { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 运行环境加载的画布集合
|
||||
/// </summary>
|
||||
private Dictionary<string, FlowCanvasDetails> FlowCanvass { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 存放触发器节点(运行时全部调用)
|
||||
/// </summary>
|
||||
private List<SingleFlipflopNode> FlipflopNodes { get; } = [];
|
||||
*/
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 流程任务管理
|
||||
/// </summary>
|
||||
private FlowWorkManagement? flowTaskManagement;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -247,34 +222,15 @@ namespace Serein.NodeFlow.Env
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前环境信息(远程连接)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<FlowEnvInfo> GetEnvInfoAsync()
|
||||
{
|
||||
// 获取所有的程序集对应的方法信息(程序集相关的数据)
|
||||
var libraryMdss = this._flowLibraryService.GetAllLibraryMds().ToArray();
|
||||
// 获取当前项目的信息(节点相关的数据)
|
||||
var project = await GetProjectInfoAsync(); // 远程连接获取远程环境项目信息
|
||||
SereinEnv.WriteLine(InfoType.INFO, "已将当前环境信息发送到远程客户端");
|
||||
return new FlowEnvInfo
|
||||
{
|
||||
Project = project, // 项目信息
|
||||
LibraryMds = libraryMdss, // 环境方法
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 保存项目
|
||||
/// </summary>
|
||||
public void SaveProject()
|
||||
{
|
||||
var project = GetProjectInfoAsync();
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var project = await GetProjectInfoAsync();
|
||||
|
||||
await SereinEnv.TriggerEvent(() =>
|
||||
{
|
||||
Event.OnProjectSaving(new ProjectSavingEventArgs(project));
|
||||
@@ -316,27 +272,19 @@ namespace Serein.NodeFlow.Env
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
// 加载画布
|
||||
try
|
||||
foreach (var canvasInfo in projectData.Canvass)
|
||||
{
|
||||
foreach (var canvasInfo in projectData.Canvass)
|
||||
{
|
||||
await LoadCanvasAsync(canvasInfo);
|
||||
}
|
||||
var nodeInfos = projectData.Nodes.ToList();
|
||||
await FlowEdit.LoadNodeInfosAsync(nodeInfos); // 加载节点信息
|
||||
// 加载画布
|
||||
foreach (var canvasInfo in projectData.Canvass)
|
||||
{
|
||||
FlowEdit.SetStartNode(canvasInfo.Guid, canvasInfo.StartNode); // 设置起始节点
|
||||
}
|
||||
|
||||
Event.OnProjectLoaded(new ProjectLoadedEventArgs());
|
||||
await LoadCanvasAsync(canvasInfo);
|
||||
}
|
||||
catch (Exception ex)
|
||||
var nodeInfos = projectData.Nodes.ToList();
|
||||
await FlowEdit.LoadNodeInfosAsync(nodeInfos); // 加载节点信息
|
||||
// 加载画布
|
||||
foreach (var canvasInfo in projectData.Canvass)
|
||||
{
|
||||
|
||||
throw;
|
||||
FlowEdit.SetStartNode(canvasInfo.Guid, canvasInfo.StartNode); // 设置起始节点
|
||||
}
|
||||
|
||||
Event.OnProjectLoaded(new ProjectLoadedEventArgs());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -382,56 +330,11 @@ namespace Serein.NodeFlow.Env
|
||||
Event.OnProjectLoaded(new ProjectLoadedEventArgs());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载远程环境
|
||||
/// </summary>
|
||||
/// <param name="addres">远程环境地址</param>
|
||||
/// <param name="port">远程环境端口</param>
|
||||
/// <param name="token">密码</param>
|
||||
/*public async Task<(bool, RemoteMsgUtil)> ConnectRemoteEnv(string addres, int port, string token)
|
||||
{
|
||||
throw new NotImplementedException("远程环境未实现的方法 ConnectRemoteEnv");
|
||||
*//*if (IsControlRemoteEnv)
|
||||
{
|
||||
await Console.Out.WriteLineAsync($"当前已经连接远程环境");
|
||||
return (false, null);
|
||||
}
|
||||
// 没有连接远程环境,可以重新连接
|
||||
|
||||
var controlConfiguration = new RemoteMsgUtil.ControlConfiguration
|
||||
{
|
||||
Addres = addres,
|
||||
Port = port,
|
||||
Token = token,
|
||||
*//*ThemeJsonKey = LocalFlowEnvironment.ThemeKey,
|
||||
MsgIdJsonKey = LocalFlowEnvironment.MsgIdKey,
|
||||
DataJsonKey = LocalFlowEnvironment.DataKey,*//*
|
||||
};
|
||||
var remoteMsgUtil = new RemoteMsgUtil(controlConfiguration);
|
||||
var result = await remoteMsgUtil.ConnectAsync();
|
||||
if (!result)
|
||||
{
|
||||
await Console.Out.WriteLineAsync("连接失败,请检查地址与端口是否正确");
|
||||
return (false, null);
|
||||
}
|
||||
await Console.Out.WriteLineAsync("连接成功,开始验证Token");
|
||||
IsControlRemoteEnv = true;
|
||||
return (true, remoteMsgUtil);*//*
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// 退出远程环境
|
||||
/// </summary>
|
||||
public void ExitRemoteEnv()
|
||||
{
|
||||
IsControlRemoteEnv = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 序列化当前项目的依赖信息、节点信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<SereinProjectData> GetProjectInfoAsync()
|
||||
public SereinProjectData GetProjectInfoAsync()
|
||||
{
|
||||
var projectData = new SereinProjectData()
|
||||
{
|
||||
@@ -466,28 +369,6 @@ namespace Serein.NodeFlow.Env
|
||||
}
|
||||
}
|
||||
|
||||
/* /// <summary>
|
||||
/// 加载本地程序集
|
||||
/// </summary>
|
||||
/// <param name="flowLibrary"></param>
|
||||
public void LoadLibrary(FlowLibraryCache flowLibrary)
|
||||
{
|
||||
try
|
||||
{
|
||||
libraryInfo = FlowLibraryService.LoadFlowLibrary(flowLibrary);
|
||||
if (mdInfos.Count > 0)
|
||||
{
|
||||
UIContextOperation?.Invoke(() => Event.OnDllLoad(new LoadDllEventArgs(libraryInfo, mdInfos))); // 通知UI创建dll面板显示
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SereinEnv.WriteLine(InfoType.ERROR, $"无法加载DLL文件:{ex.Message}");
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 移除DLL
|
||||
/// </summary>
|
||||
@@ -572,9 +453,6 @@ namespace Serein.NodeFlow.Env
|
||||
//}
|
||||
}
|
||||
|
||||
private int _addCanvasCount = 0;
|
||||
|
||||
|
||||
private async Task<FlowCanvasDetails> LoadCanvasAsync(FlowCanvasDetailsInfo info)
|
||||
{
|
||||
var model = new FlowCanvasDetails(this);
|
||||
@@ -623,6 +501,7 @@ namespace Serein.NodeFlow.Env
|
||||
/// <para>异步方法:Func<object,object[],Task></para>
|
||||
/// <para>异步有返回值方法:Func<object,object[],Task<object>></para>
|
||||
/// </summary>
|
||||
/// <param name="assemblyName"></param>
|
||||
/// <param name="methodName"></param>
|
||||
/// <param name="delegateDetails"></param>
|
||||
/// <returns></returns>
|
||||
@@ -711,10 +590,11 @@ namespace Serein.NodeFlow.Env
|
||||
/// <summary>
|
||||
/// 从Guid获取画布
|
||||
/// </summary>
|
||||
/// <param name="nodeGuid">节点Guid</param>
|
||||
/// <returns>节点Model</returns>
|
||||
/// <param name="nodeGuid">画布Guid</param>
|
||||
/// <param name="canvasDetails">画布实体</param>
|
||||
/// <returns>是否获取成功</returns>
|
||||
/// <exception cref="ArgumentNullException">无法获取节点、Guid/节点为null时报错</exception>
|
||||
public bool TryGetCanvasModel(string nodeGuid, out FlowCanvasDetails canvasDetails)
|
||||
public bool TryGetCanvasModel(string nodeGuid,[NotNullWhen(true)] out FlowCanvasDetails? canvasDetails)
|
||||
{
|
||||
if (string.IsNullOrEmpty(nodeGuid))
|
||||
{
|
||||
@@ -729,9 +609,10 @@ namespace Serein.NodeFlow.Env
|
||||
/// 从Guid获取节点
|
||||
/// </summary>
|
||||
/// <param name="nodeGuid">节点Guid</param>
|
||||
/// <param name="nodeModel">节点Guid</param>
|
||||
/// <returns>节点Model</returns>
|
||||
/// <exception cref="ArgumentNullException">无法获取节点、Guid/节点为null时报错</exception>
|
||||
public bool TryGetNodeModel(string nodeGuid, out IFlowNode nodeModel)
|
||||
public bool TryGetNodeModel(string nodeGuid, [NotNullWhen(true)] out IFlowNode? nodeModel)
|
||||
{
|
||||
if (string.IsNullOrEmpty(nodeGuid))
|
||||
{
|
||||
|
||||
@@ -158,10 +158,11 @@ namespace Serein.NodeFlow
|
||||
/// <param name="sb">字符串构建器</param>
|
||||
/// <param name="retractCount">缩进次数(4个空格)</param>
|
||||
/// <param name="code">要添加的代码</param>
|
||||
/// <param name="isWrapping">是否换行</param>
|
||||
/// <returns>字符串构建器本身</returns>
|
||||
public static StringBuilder AppendCode(this StringBuilder sb,
|
||||
int retractCount = 0,
|
||||
string code = null,
|
||||
string? code = null,
|
||||
bool isWrapping = true)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(code))
|
||||
|
||||
@@ -4,22 +4,25 @@ using Serein.Library.Api;
|
||||
namespace Serein.NodeFlow
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 流程任务类,包含流程的起始节点和所有节点信息。
|
||||
/// </summary>
|
||||
public class FlowTask
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否异步启动流程
|
||||
/// </summary>
|
||||
public bool IsTaskAsync { get; set; }
|
||||
public bool IsTaskAsync { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 流程起始节点
|
||||
/// </summary>
|
||||
public Func<IFlowNode> GetStartNode { get; set; }
|
||||
public Func<IFlowNode>? GetStartNode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前画布流程的所有节点
|
||||
/// </summary>
|
||||
public Func<List<IFlowNode>> GetNodes { get; set; }
|
||||
public Func<List<IFlowNode>>? GetNodes { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -30,11 +33,11 @@ namespace Serein.NodeFlow
|
||||
/// <summary>
|
||||
/// 流程IOC容器
|
||||
/// </summary>
|
||||
public ISereinIOC FlowIOC { get; set; }
|
||||
public required ISereinIOC FlowIOC { get; set; }
|
||||
/// <summary>
|
||||
/// 流程运行环境
|
||||
/// </summary>
|
||||
public IFlowEnvironment Environment { get; set; }// = environment;
|
||||
public required IFlowEnvironment Environment { get; set; }// = environment;
|
||||
|
||||
/// <summary>
|
||||
/// 表示运行环境状态
|
||||
@@ -44,35 +47,30 @@ namespace Serein.NodeFlow
|
||||
/// <summary>
|
||||
/// 上下文线程池
|
||||
/// </summary>
|
||||
public Serein.Library.Utils.ObjectPool<IFlowContext> FlowContextPool { get; set; }
|
||||
public required Serein.Library.Utils.ObjectPool<IFlowContext> FlowContextPool { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 每个画布需要启用的节点
|
||||
/// </summary>
|
||||
public Dictionary<string, FlowTask> Flows { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前任务加载的所有节点
|
||||
/// </summary>
|
||||
//public List<NodeModelBase> Nodes { get; set; }// = nodes;
|
||||
public Dictionary<string, FlowTask> Flows { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 需要注册的类型
|
||||
/// </summary>
|
||||
public Dictionary<RegisterSequence, List<Type>> AutoRegisterTypes { get; set; } //= autoRegisterTypes;
|
||||
public Dictionary<RegisterSequence, List<Type>> AutoRegisterTypes { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 初始化时需要的方法
|
||||
/// </summary>
|
||||
public List<MethodDetails> InitMds { get; set; }// = initMds;
|
||||
public List<MethodDetails> InitMds { get; set; } = [];
|
||||
/// <summary>
|
||||
/// 加载时需要的方法
|
||||
/// </summary>
|
||||
public List<MethodDetails> LoadMds { get; set; }// = loadMds;
|
||||
public List<MethodDetails> LoadMds { get; set; } = [];
|
||||
/// <summary>
|
||||
/// 退出时需要调用的方法
|
||||
/// </summary>
|
||||
public List<MethodDetails> ExitMds { get; set; } //= exitMds;
|
||||
public List<MethodDetails> ExitMds { get; set; } = [];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace Serein.NodeFlow.Model.Library
|
||||
// 从 scanTypes.Type 创建的方法信息
|
||||
// Md : 方法描述
|
||||
// Dd :方法对应的Emit委托
|
||||
List<LibraryMdDd> detailss = new List<LibraryMdDd>();
|
||||
List<LibraryMthodInfo> detailss = new List<LibraryMthodInfo>();
|
||||
|
||||
// 遍历扫描的类型
|
||||
foreach ((var type, var flowName) in scanTypes)
|
||||
@@ -159,7 +159,7 @@ namespace Serein.NodeFlow.Model.Library
|
||||
continue;
|
||||
}
|
||||
md.MethodAnotherName = flowName + md.MethodAnotherName; // 方法别名
|
||||
detailss.Add(new LibraryMdDd(mi, md, dd));
|
||||
detailss.Add(new LibraryMthodInfo(mi, md, dd));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
using Serein.Library;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Serein.NodeFlow.Model.Library
|
||||
{
|
||||
public class LibraryMdDd
|
||||
{
|
||||
public MethodDetails MethodDetails { get; }
|
||||
public MethodInfo MethodInfo { get; }
|
||||
public DelegateDetails DelegateDetails { get; }
|
||||
|
||||
public LibraryMdDd(MethodInfo methodInfo, MethodDetails methodDetails, DelegateDetails delegateDetails)
|
||||
{
|
||||
MethodDetails = methodDetails;
|
||||
MethodInfo = methodInfo;
|
||||
DelegateDetails = delegateDetails;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
39
NodeFlow/Model/Librarys/LibraryMthodInfo.cs
Normal file
39
NodeFlow/Model/Librarys/LibraryMthodInfo.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using Serein.Library;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Serein.NodeFlow.Model.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// 库方法信息类,包含方法的详细信息、反射信息和委托信息。
|
||||
/// </summary>
|
||||
public class LibraryMthodInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 方法的详细信息。
|
||||
/// </summary>
|
||||
public MethodDetails MethodDetails { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 方法的反射信息,包含方法名称、参数类型等。
|
||||
/// </summary>
|
||||
public MethodInfo MethodInfo { get; }
|
||||
/// <summary>
|
||||
/// Emit构造委托
|
||||
/// </summary>
|
||||
public DelegateDetails DelegateDetails { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的库方法信息实例。
|
||||
/// </summary>
|
||||
/// <param name="methodInfo"></param>
|
||||
/// <param name="methodDetails"></param>
|
||||
/// <param name="delegateDetails"></param>
|
||||
public LibraryMthodInfo(MethodInfo methodInfo, MethodDetails methodDetails, DelegateDetails delegateDetails)
|
||||
{
|
||||
MethodDetails = methodDetails;
|
||||
MethodInfo = methodInfo;
|
||||
DelegateDetails = delegateDetails;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -140,7 +140,6 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// 从节点信息加载节点
|
||||
/// </summary>
|
||||
/// <param name="nodeModel"></param>
|
||||
/// <param name="canvas"></param>
|
||||
/// <param name="nodeInfo"></param>
|
||||
/// <returns></returns>
|
||||
public static void LoadInfo(this IFlowNode nodeModel, NodeInfo nodeInfo)
|
||||
@@ -243,97 +242,6 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查监视表达式是否生效
|
||||
/// </summary>
|
||||
/// <param name="nodeModel">节点Moel</param>
|
||||
/// <param name="context">上下文</param>
|
||||
/// <param name="newData">新的数据</param>
|
||||
/// <returns></returns>
|
||||
/*public static async Task CheckExpInterrupt(this NodeModelBase nodeModel, IDynamicContext context, object newData = null)
|
||||
{
|
||||
string guid = nodeModel.Guid;
|
||||
context.AddOrUpdate(guid, newData); // 上下文中更新数据
|
||||
if (newData is null)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
await nodeModel.MonitorObjExpInterrupt(context, newData, 0); // 首先监视对象
|
||||
await nodeModel.MonitorObjExpInterrupt(context, newData, 1); // 然后监视节点
|
||||
//nodeModel.FlowData = newData; // 替换数据
|
||||
}
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// 监视对象表达式中断
|
||||
/// </summary>
|
||||
/// <param name="nodeModel"></param>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="monitorType"></param>
|
||||
/// <returns></returns>
|
||||
/*private static async Task MonitorObjExpInterrupt(this NodeModelBase nodeModel, IDynamicContext context, object data, int monitorType)
|
||||
{
|
||||
MonitorObjectEventArgs.ObjSourceType sourceType;
|
||||
string key;
|
||||
if (monitorType == 0)
|
||||
{
|
||||
key = data?.GetType()?.FullName;
|
||||
sourceType = MonitorObjectEventArgs.ObjSourceType.IOCObj;
|
||||
}
|
||||
else
|
||||
{
|
||||
key = nodeModel.Guid;
|
||||
sourceType = MonitorObjectEventArgs.ObjSourceType.IOCObj;
|
||||
}
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
return;
|
||||
}
|
||||
//(var isMonitor, var exps) = await context.Env.CheckObjMonitorStateAsync(key);
|
||||
//if (isMonitor) // 如果新的数据处于查看状态,通知UI进行更新?交给运行环境判断?
|
||||
//{
|
||||
// context.Env.MonitorObjectNotification(nodeModel.Guid, data, sourceType); // 对象处于监视状态,通知UI更新数据显示
|
||||
// if (exps.Length > 0)
|
||||
// {
|
||||
// // 表达式环境下判断是否需要执行中断
|
||||
// bool isExpInterrupt = false;
|
||||
// string exp = "";
|
||||
// // 判断执行监视表达式,直到为 true 时退出
|
||||
// for (int i = 0; i < exps.Length && !isExpInterrupt; i++)
|
||||
// {
|
||||
// exp = exps[i];
|
||||
// if (string.IsNullOrEmpty(exp)) continue;
|
||||
// // isExpInterrupt = SereinConditionParser.To(data, exp);
|
||||
// }
|
||||
|
||||
// if (isExpInterrupt) // 触发中断
|
||||
// {
|
||||
// nodeModel.DebugSetting.IsInterrupt = true;
|
||||
// if (await context.Env.SetNodeInterruptAsync(nodeModel.Guid,true))
|
||||
// {
|
||||
// context.Env.TriggerInterrupt(nodeModel.Guid, exp, InterruptTriggerEventArgs.InterruptTriggerType.Exp);
|
||||
// var cancelType = await nodeModel.DebugSetting.GetInterruptTask();
|
||||
// await Console.Out.WriteLineAsync($"[{data}]中断已{cancelType},开始执行后继分支");
|
||||
// nodeModel.DebugSetting.IsInterrupt = false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
//}
|
||||
}*/
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 不再中断
|
||||
/// </summary>
|
||||
public static void CancelInterrupt(IFlowNode nodeModel)
|
||||
{
|
||||
nodeModel.DebugSetting.IsInterrupt = false;
|
||||
nodeModel.DebugSetting.CancelInterrupt?.Invoke();
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// 程序集更新,更新节点方法描述、以及所有入参描述的类型
|
||||
@@ -13,49 +13,49 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// <summary>
|
||||
/// 节点基类(数据)
|
||||
/// </summary>
|
||||
[NodeProperty(ValuePath = NodeValuePath.Node)]
|
||||
[FlowDataProperty(ValuePath = NodeValuePath.Node)]
|
||||
public abstract partial class NodeModelBase : IFlowNode
|
||||
{
|
||||
/// <summary>
|
||||
/// 节点运行环境
|
||||
/// </summary>
|
||||
[PropertyInfo(IsProtection = true)]
|
||||
[DataInfo(IsProtection = true)]
|
||||
private IFlowEnvironment _env;
|
||||
|
||||
/// <summary>
|
||||
/// 标识节点对象全局唯一
|
||||
/// </summary>
|
||||
[PropertyInfo(IsProtection = true)]
|
||||
[DataInfo(IsProtection = true)]
|
||||
private string _guid;
|
||||
|
||||
/// <summary>
|
||||
/// 描述节点对应的控件类型
|
||||
/// </summary>
|
||||
[PropertyInfo(IsProtection = true)]
|
||||
[DataInfo(IsProtection = true)]
|
||||
private NodeControlType _controlType;
|
||||
|
||||
/// <summary>
|
||||
/// 所属画布
|
||||
/// </summary>
|
||||
[PropertyInfo(IsProtection = true)]
|
||||
[DataInfo(IsProtection = true)]
|
||||
private FlowCanvasDetails _canvasDetails ;
|
||||
|
||||
/// <summary>
|
||||
/// 在画布中的位置
|
||||
/// </summary>
|
||||
[PropertyInfo(IsProtection = true)]
|
||||
[DataInfo(IsProtection = true)]
|
||||
private PositionOfUI _position ;
|
||||
|
||||
/// <summary>
|
||||
/// 显示名称
|
||||
/// </summary>
|
||||
[PropertyInfo]
|
||||
[DataInfo]
|
||||
private string _displayName;
|
||||
|
||||
/// <summary>
|
||||
/// 是否公开
|
||||
/// </summary>
|
||||
[PropertyInfo(IsNotification = true)]
|
||||
[DataInfo(IsNotification = true)]
|
||||
private bool _isPublic;
|
||||
|
||||
/* /// <summary>
|
||||
@@ -67,13 +67,13 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// <summary>
|
||||
/// 附加的调试功能
|
||||
/// </summary>
|
||||
[PropertyInfo(IsProtection = true)]
|
||||
[DataInfo(IsProtection = true)]
|
||||
private NodeDebugSetting _debugSetting ;
|
||||
|
||||
/// <summary>
|
||||
/// 方法描述。包含参数信息。不包含Method与委托,如若需要调用对应的方法,需要通过MethodName从环境中获取委托进行调用。
|
||||
/// </summary>
|
||||
[PropertyInfo]
|
||||
[DataInfo]
|
||||
private MethodDetails _methodDetails ;
|
||||
}
|
||||
|
||||
@@ -90,6 +90,10 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// </summary>
|
||||
public virtual int MaxChildrenCount { get; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 创建一个节点模型的基类实例
|
||||
/// </summary>
|
||||
/// <param name="environment"></param>
|
||||
public NodeModelBase(IFlowEnvironment environment)
|
||||
{
|
||||
PreviousNodes = new Dictionary<ConnectionInvokeType, List<IFlowNode>>();
|
||||
@@ -47,7 +47,6 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// </summary>
|
||||
/// <param name="context">流程上下文</param>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="args">自定义参数</param>
|
||||
/// <returns>节点传回数据对象</returns>
|
||||
public virtual async Task<FlowResult> ExecutingAsync(IFlowContext context, CancellationToken token)
|
||||
{
|
||||
@@ -9,6 +9,10 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// </summary>
|
||||
public class SingleActionNode : NodeModelBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造一个新的单动作节点实例。
|
||||
/// </summary>
|
||||
/// <param name="environment"></param>
|
||||
public SingleActionNode(IFlowEnvironment environment):base(environment)
|
||||
{
|
||||
|
||||
@@ -9,25 +9,25 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// <summary>
|
||||
/// 条件节点(用于条件控件)
|
||||
/// </summary>
|
||||
[NodeProperty(ValuePath = NodeValuePath.Node)]
|
||||
[FlowDataProperty(ValuePath = NodeValuePath.Node, IsNodeImp = true)]
|
||||
public partial class SingleConditionNode : NodeModelBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否为自定义参数
|
||||
/// </summary>
|
||||
[PropertyInfo(IsNotification = true)]
|
||||
[DataInfo(IsNotification = true)]
|
||||
private bool _isExplicitData;
|
||||
|
||||
/// <summary>
|
||||
/// 自定义参数值
|
||||
/// </summary>
|
||||
[PropertyInfo(IsNotification = true)]
|
||||
[DataInfo(IsNotification = true)]
|
||||
private string? _explicitData;
|
||||
|
||||
/// <summary>
|
||||
/// 条件表达式
|
||||
/// </summary>
|
||||
[PropertyInfo(IsNotification = true)]
|
||||
[DataInfo(IsNotification = true)]
|
||||
private string _expression;
|
||||
|
||||
}
|
||||
@@ -44,7 +44,10 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// </summary>
|
||||
private const int INDEX_EXPRESSION = 0;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 条件节点构造函数
|
||||
/// </summary>
|
||||
/// <param name="environment"></param>
|
||||
public SingleConditionNode(IFlowEnvironment environment):base(environment)
|
||||
{
|
||||
this.IsExplicitData = false;
|
||||
@@ -52,6 +55,9 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
this.Expression = "PASS";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建节点时调用的方法
|
||||
/// </summary>
|
||||
public override void OnCreating()
|
||||
{
|
||||
// 这里的这个参数是为了方便使用入参控制点,参数无意义
|
||||
@@ -106,6 +112,7 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// 重写节点的方法执行
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<FlowResult> ExecutingAsync(IFlowContext context, CancellationToken token)
|
||||
{
|
||||
@@ -8,19 +8,21 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// <summary>
|
||||
/// Expression Operation - 表达式操作
|
||||
/// </summary>
|
||||
[NodeProperty(ValuePath = NodeValuePath.Node)]
|
||||
[FlowDataProperty(ValuePath = NodeValuePath.Node, IsNodeImp = true)]
|
||||
public partial class SingleExpOpNode : NodeModelBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 表达式
|
||||
/// </summary>
|
||||
[PropertyInfo(IsNotification = true)]
|
||||
[DataInfo(IsNotification = true)]
|
||||
private string _expression;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 表达式节点模型基类
|
||||
/// </summary>
|
||||
public partial class SingleExpOpNode : NodeModelBase
|
||||
{
|
||||
/// <summary>
|
||||
@@ -33,6 +35,10 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// </summary>
|
||||
private const int INDEX_EXPRESSION = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 表达式节点构造函数
|
||||
/// </summary>
|
||||
/// <param name="environment"></param>
|
||||
public SingleExpOpNode(IFlowEnvironment environment) : base(environment)
|
||||
{
|
||||
|
||||
@@ -87,7 +93,12 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
this.Expression = nodeInfo.CustomData?.Expression ?? "";
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 执行节点操作
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<FlowResult> ExecutingAsync(IFlowContext context, CancellationToken token)
|
||||
{
|
||||
if(token.IsCancellationRequested) return FlowResult.Fail(this.Guid, context, "流程已通过token取消");
|
||||
@@ -10,7 +10,10 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// </summary>
|
||||
public class SingleFlipflopNode : NodeModelBase
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的单触发器节点实例。
|
||||
/// </summary>
|
||||
/// <param name="environment"></param>
|
||||
public SingleFlipflopNode(IFlowEnvironment environment) : base(environment)
|
||||
{
|
||||
|
||||
@@ -21,6 +24,7 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// 执行触发器进行等待触发
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public override async Task<FlowResult> ExecutingAsync(IFlowContext context, CancellationToken token)
|
||||
@@ -7,26 +7,26 @@ using System.Reflection;
|
||||
namespace Serein.NodeFlow.Model.Nodes
|
||||
{
|
||||
|
||||
[NodeProperty(ValuePath = NodeValuePath.Node)]
|
||||
[FlowDataProperty(ValuePath = NodeValuePath.Node, IsNodeImp = true)]
|
||||
public partial class SingleFlowCallNode
|
||||
{
|
||||
/// <summary>
|
||||
/// 目标公开节点
|
||||
/// </summary>
|
||||
[PropertyInfo(IsNotification = true)]
|
||||
private string targetNodeGuid;
|
||||
[DataInfo(IsNotification = true)]
|
||||
private string targetNodeGuid = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 使用目标节点的参数(如果为true,则使用目标节点的入参,如果为false,则使用节点自定义入参)
|
||||
/// </summary>
|
||||
[PropertyInfo(IsNotification = true)]
|
||||
private bool _isShareParam ;
|
||||
[DataInfo(IsNotification = true)]
|
||||
private bool _isShareParam ;
|
||||
|
||||
/// <summary>
|
||||
/// 接口全局名称
|
||||
/// </summary>
|
||||
[PropertyInfo(IsNotification = true)]
|
||||
private string _apiGlobalName;
|
||||
[DataInfo(IsNotification = true)]
|
||||
private string _apiGlobalName = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,10 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// </summary>
|
||||
public MethodDetails CacheMethodDetails { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 流程接口节点
|
||||
/// </summary>
|
||||
/// <param name="environment"></param>
|
||||
public SingleFlowCallNode(IFlowEnvironment environment) : base(environment)
|
||||
{
|
||||
|
||||
@@ -207,7 +211,7 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
}
|
||||
|
||||
private static Dictionary<string, int> ApiInvokeNameCache = new Dictionary<string, int>();
|
||||
public static int getApiInvokeNameCount = 0;
|
||||
private static int getApiInvokeNameCount = 0;
|
||||
private static string GetApiInvokeName(SingleFlowCallNode node, string apiName)
|
||||
{
|
||||
if (ApiInvokeNameCache.ContainsKey(apiName))
|
||||
@@ -223,6 +227,12 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
return $"{apiName}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取流程接口节点的名称
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetApiInvokeName(SingleFlowCallNode node)
|
||||
{
|
||||
if(node.TargetNode is null)
|
||||
@@ -9,13 +9,13 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// <summary>
|
||||
/// Expression Operation - 表达式操作
|
||||
/// </summary>
|
||||
[NodeProperty(ValuePath = NodeValuePath.Node)]
|
||||
[FlowDataProperty(ValuePath = NodeValuePath.Node, IsNodeImp = true)]
|
||||
public partial class SingleGlobalDataNode : NodeModelBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 全局数据的Key名称
|
||||
/// </summary>
|
||||
[PropertyInfo(IsNotification = true)]
|
||||
[DataInfo(IsNotification = true)]
|
||||
private string _keyName;
|
||||
|
||||
}
|
||||
@@ -36,6 +36,10 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// </summary>
|
||||
public override int MaxChildrenCount => 1;
|
||||
|
||||
/// <summary>
|
||||
/// 全局数据节点,允许放置一个数据源节点,通常是[Action]或[Script]节点,用于获取全局数据。
|
||||
/// </summary>
|
||||
/// <param name="environment"></param>
|
||||
public SingleGlobalDataNode(IFlowEnvironment environment) : base(environment)
|
||||
{
|
||||
}
|
||||
@@ -85,7 +89,11 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 从容器中取出节点
|
||||
/// </summary>
|
||||
/// <param name="nodeModel"></param>
|
||||
/// <returns></returns>
|
||||
public bool TakeOutNode(IFlowNode nodeModel)
|
||||
{
|
||||
if (ChildrenNode.Contains(nodeModel))
|
||||
@@ -102,7 +110,10 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
|
||||
}
|
||||
|
||||
public async void TakeOutAll()
|
||||
/// <summary>
|
||||
/// 从容器中取出所有节点
|
||||
/// </summary>
|
||||
public void TakeOutAll()
|
||||
{
|
||||
foreach (var nodeModel in ChildrenNode)
|
||||
{
|
||||
@@ -111,12 +122,13 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
DataNode = null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置全局数据
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<FlowResult> ExecutingAsync(IFlowContext context, CancellationToken token)
|
||||
{
|
||||
@@ -10,27 +10,30 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.NodeFlow.Model.Nodes
|
||||
{
|
||||
/// <summary>
|
||||
/// 单脚本节点(用于脚本控件)
|
||||
/// </summary>
|
||||
|
||||
[NodeProperty(ValuePath = NodeValuePath.Node)]
|
||||
[FlowDataProperty(ValuePath = NodeValuePath.Node, IsNodeImp = true)]
|
||||
public partial class SingleNetScriptNode : NodeModelBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 脚本代码
|
||||
/// </summary>
|
||||
[PropertyInfo(IsNotification = true)]
|
||||
private string _script;
|
||||
[DataInfo(IsNotification = true)]
|
||||
private string _script = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 功能提示
|
||||
/// </summary>
|
||||
[PropertyInfo(IsNotification = true)]
|
||||
[DataInfo(IsNotification = true)]
|
||||
private string _tips = "写一下提示吧";
|
||||
|
||||
/// <summary>
|
||||
/// 依赖路径
|
||||
/// </summary>
|
||||
[PropertyInfo(IsNotification = true)]
|
||||
private List<string> _libraryFilePaths;
|
||||
[DataInfo(IsNotification = true)]
|
||||
private List<string> _libraryFilePaths = [];
|
||||
|
||||
}
|
||||
|
||||
@@ -41,46 +44,16 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// </summary>
|
||||
public override bool IsBase => true;
|
||||
|
||||
/// <summary>
|
||||
/// 脚本代码
|
||||
/// </summary>
|
||||
/// <param name="environment"></param>
|
||||
public SingleNetScriptNode(IFlowEnvironment environment) : base(environment)
|
||||
{
|
||||
this.Env = environment;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public override void OnCreating()
|
||||
{
|
||||
//MethodInfo? method = this.GetType().GetMethod(nameof(GetFlowApi));
|
||||
//if (method != null)
|
||||
//{
|
||||
// ScriptInterpreter.AddFunction(nameof(GetFlowApi), method, () => this); // 挂载获取流程接口
|
||||
//}
|
||||
|
||||
//var md = MethodDetails;
|
||||
//var pd = md.ParameterDetailss ??= new ParameterDetails[1];
|
||||
//md.ParamsArgIndex = 0;
|
||||
//pd[0] = new ParameterDetails
|
||||
//{
|
||||
// Index = 0,
|
||||
// Name = "object",
|
||||
// IsExplicitData = true,
|
||||
// DataValue = string.Empty,
|
||||
// DataType = typeof(object),
|
||||
// ExplicitType = typeof(object),
|
||||
// ArgDataSourceNodeGuid = string.Empty,
|
||||
// ArgDataSourceType = ConnectionArgSourceType.GetPreviousNodeData,
|
||||
// NodeModel = this,
|
||||
// InputType = ParameterValueInputType.Input,
|
||||
// Items = null,
|
||||
// IsParams = true,
|
||||
// Description = "脚本节点入参"
|
||||
|
||||
//};
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导出脚本代码
|
||||
/// </summary>
|
||||
@@ -18,11 +18,11 @@ using System.Xml.Linq;
|
||||
namespace Serein.NodeFlow.Model.Nodes
|
||||
{
|
||||
|
||||
[NodeProperty(ValuePath = NodeValuePath.Node)]
|
||||
[FlowDataProperty(ValuePath = NodeValuePath.Node, IsNodeImp = true)]
|
||||
public partial class SingleScriptNode : NodeModelBase
|
||||
{
|
||||
[PropertyInfo(IsNotification = true)]
|
||||
private string _script;
|
||||
[DataInfo(IsNotification = true)]
|
||||
private string _script = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -293,6 +293,7 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
/// 执行脚本
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<FlowResult> ExecutingAsync(IFlowContext context, CancellationToken token)
|
||||
{
|
||||
@@ -8,13 +8,30 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.NodeFlow.Model.Nodes
|
||||
{
|
||||
/// <summary>
|
||||
/// 单个UI节点,适用于需要在流程中嵌入用户自定义控件的场景。
|
||||
/// </summary>
|
||||
public class SingleUINode : NodeModelBase
|
||||
{
|
||||
public IEmbeddedContent Adapter { get; private set; }
|
||||
/// <summary>
|
||||
/// 适配的UI控件,必须实现IEmbeddedContent接口。
|
||||
/// </summary>
|
||||
public IEmbeddedContent? Adapter { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 单个UI节点构造函数,初始化流程环境。
|
||||
/// </summary>
|
||||
/// <param name="environment"></param>
|
||||
public SingleUINode(IFlowEnvironment environment) : base(environment)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行节点逻辑,适用于嵌入式UI控件的流程节点。
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<FlowResult> ExecutingAsync(IFlowContext context, CancellationToken token)
|
||||
{
|
||||
if (token.IsCancellationRequested) return FlowResult.Fail(this.Guid, context, "流程已通过token取消");
|
||||
@@ -11,7 +11,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static Serein.Library.Api.NodeConnectChangeEventArgs;
|
||||
|
||||
namespace Serein.NodeFlow.Model.Operation
|
||||
namespace Serein.NodeFlow.Model.Operations
|
||||
{
|
||||
/// <summary>
|
||||
/// 节点连接状态发生改变
|
||||
@@ -45,6 +45,7 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
/// </summary>
|
||||
public JunctionType ToNodeJunctionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接类型
|
||||
/// </summary>
|
||||
public ConnectionInvokeType ConnectionInvokeType { get; set; }
|
||||
@@ -69,9 +70,9 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
public override bool IsCanUndo => false;
|
||||
|
||||
#region 私有参数
|
||||
private FlowCanvasDetails FlowCanvas;
|
||||
private IFlowNode FromNode;
|
||||
private IFlowNode ToNode;
|
||||
private FlowCanvasDetails? FlowCanvas;
|
||||
private IFlowNode? FromNode;
|
||||
private IFlowNode? ToNode;
|
||||
#endregion
|
||||
|
||||
public override bool ValidationParameter()
|
||||
@@ -155,7 +156,10 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
/// </summary>
|
||||
private async Task<bool> CreateInvokeConnection()
|
||||
{
|
||||
IFlowNode fromNode = FromNode ;
|
||||
ArgumentNullException.ThrowIfNull(FlowCanvas);
|
||||
ArgumentNullException.ThrowIfNull(FromNode);
|
||||
ArgumentNullException.ThrowIfNull(ToNode);
|
||||
IFlowNode fromNode = FromNode;
|
||||
IFlowNode toNode = ToNode;
|
||||
ConnectionInvokeType invokeType = ConnectionInvokeType;
|
||||
if (fromNode.ControlType == NodeControlType.FlowCall)
|
||||
@@ -340,6 +344,10 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
/// </summary>
|
||||
private async Task<bool> RemoveInvokeConnection()
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(FlowCanvas);
|
||||
ArgumentNullException.ThrowIfNull(FromNode);
|
||||
ArgumentNullException.ThrowIfNull(ToNode);
|
||||
|
||||
FromNode.SuccessorNodes[ConnectionInvokeType].Remove(ToNode);
|
||||
ToNode.PreviousNodes[ConnectionInvokeType].Remove(FromNode);
|
||||
|
||||
@@ -383,7 +391,12 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
/// </summary>
|
||||
/// <exception cref="Exception"></exception>
|
||||
private async Task<bool> CreateArgConnection()
|
||||
{/*
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(FlowCanvas);
|
||||
ArgumentNullException.ThrowIfNull(FromNode);
|
||||
ArgumentNullException.ThrowIfNull(ToNode);
|
||||
|
||||
/*
|
||||
IFlowNode fromNodeControl = ToNode;
|
||||
IFlowNode toNodeControl = ToNode;*/
|
||||
ConnectionArgSourceType type = ConnectionArgSourceType;
|
||||
@@ -520,11 +533,12 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
/// <summary>
|
||||
/// 移除参数连接关系
|
||||
/// </summary>
|
||||
/// <param name="fromNodeControl"></param>
|
||||
/// <param name="toNodeControl"></param>
|
||||
/// <param name="index"></param>
|
||||
private async Task<bool> RemoveArgConnection()
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(FlowCanvas);
|
||||
ArgumentNullException.ThrowIfNull(FromNode);
|
||||
ArgumentNullException.ThrowIfNull(ToNode);
|
||||
|
||||
if (ToNode.MethodDetails.ParameterDetailss is null) return false;
|
||||
var type = ToNode.MethodDetails.ParameterDetailss[ArgIndex].ArgDataSourceType;
|
||||
FromNode.NeedResultNodes[type].Remove(ToNode);
|
||||
@@ -7,7 +7,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.NodeFlow.Model.Operation
|
||||
namespace Serein.NodeFlow.Model.Operations
|
||||
{
|
||||
internal class ChangeParameterOperation : OperationBase
|
||||
{
|
||||
@@ -9,7 +9,7 @@ using System.Net.Mime;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.NodeFlow.Model.Operation
|
||||
namespace Serein.NodeFlow.Model.Operations
|
||||
{
|
||||
/// <summary>
|
||||
/// 放置节点操作
|
||||
@@ -5,7 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.NodeFlow.Model.Operation
|
||||
namespace Serein.NodeFlow.Model.Operations
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
@@ -7,7 +7,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.NodeFlow.Model.Operation
|
||||
namespace Serein.NodeFlow.Model.Operations
|
||||
{
|
||||
internal class CreateCanvasOperation : OperationBase
|
||||
{
|
||||
@@ -9,7 +9,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.NodeFlow.Model.Operation
|
||||
namespace Serein.NodeFlow.Model.Operations
|
||||
{
|
||||
internal class CreateNodeOperation : OperationBase
|
||||
{
|
||||
@@ -9,7 +9,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.NodeFlow.Model.Operation
|
||||
namespace Serein.NodeFlow.Model.Operations
|
||||
{
|
||||
internal interface IOperation
|
||||
{
|
||||
@@ -64,6 +64,7 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
[AutoInjection]
|
||||
protected IFlowEnvironmentEvent flowEnvironmentEvent;
|
||||
|
||||
|
||||
public abstract string Theme { get;}
|
||||
|
||||
/// <summary>
|
||||
@@ -7,7 +7,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.NodeFlow.Model.Operation
|
||||
namespace Serein.NodeFlow.Model.Operations
|
||||
{
|
||||
internal class RemoveCanvasOperation : OperationBase
|
||||
{
|
||||
@@ -2,7 +2,7 @@
|
||||
using Serein.Library.Api;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace Serein.NodeFlow.Model.Operation
|
||||
namespace Serein.NodeFlow.Model.Operations
|
||||
{
|
||||
internal class RemoveNodeOperation : OperationBase
|
||||
{
|
||||
@@ -15,6 +15,7 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
/// 节点所在画布
|
||||
/// </summary>
|
||||
private FlowCanvasDetails flowCanvasDetails;
|
||||
|
||||
/// <summary>
|
||||
/// 被删除的节点
|
||||
/// </summary>
|
||||
@@ -46,9 +47,19 @@ namespace Serein.NodeFlow.Model.Operation
|
||||
{
|
||||
if (!ValidationParameter()) return false;
|
||||
|
||||
// 需要移除对应的方法调用、以及参数获取调用
|
||||
// 需要移除对应的方法调用、参数获取调用以及子节点信息
|
||||
// 还需要记录移除的事件参数,用以撤销恢复
|
||||
|
||||
if (flowNode.ChildrenNode.Count > 0)
|
||||
{
|
||||
// 如果该节点存在子节点,则删除所有子节点
|
||||
foreach(var child in flowNode.ChildrenNode)
|
||||
{
|
||||
flowEnvironment.FlowEdit.RemoveNode(CanvasGuid, child.Guid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region 移除方法调用关系
|
||||
|
||||
// 检查该节点的前继节点,然后从这些前继节点中移除与该节点的连接关系
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.NodeFlow.Model.Operation
|
||||
namespace Serein.NodeFlow.Model.Operations
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.NodeFlow.Model.Operation
|
||||
namespace Serein.NodeFlow.Model.Operations
|
||||
{
|
||||
/// <summary>
|
||||
/// 设置起始节点
|
||||
@@ -42,22 +42,11 @@ namespace Serein.NodeFlow
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
//public object? GetArgData(IDynamicContext context, int index)
|
||||
//{
|
||||
// var _paramsKey = $"{context?.Guid}_{NodeModel.Guid}_Params";
|
||||
// var obj = context?.GetFlowData(_paramsKey);
|
||||
// if (obj is object[] @params && index < @params.Length)
|
||||
// {
|
||||
// return @params[index];
|
||||
// }
|
||||
// return null;
|
||||
//}
|
||||
|
||||
//public object? GetFlowData(IDynamicContext context)
|
||||
//{
|
||||
// return context?.GetFlowData(NodeModel.Guid);
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 获取全局数据
|
||||
/// </summary>
|
||||
/// <param name="keyName"></param>
|
||||
/// <returns></returns>
|
||||
public object? GetGlobalData(string keyName)
|
||||
{
|
||||
return SereinEnv.GetFlowGlobalData(keyName);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>1.2.2</Version>
|
||||
<Version>1.2.3</Version>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
@@ -54,6 +54,7 @@
|
||||
<Compile Remove="Tool\ExpressionHelper.cs" />
|
||||
<Compile Remove="Tool\FlowLibraryAssemblyContext2.cs" />
|
||||
<Compile Remove="Tool\NodeModelBaseFunc.cs" />
|
||||
<Compile Remove="Tool\ObjDynamicCreateHelper.cs" />
|
||||
<Compile Remove="Tool\TcsSignal.cs" />
|
||||
<Compile Remove="Tool\ToCSharpCodeHelper.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -77,6 +77,7 @@ namespace Serein.NodeFlow.Services
|
||||
/// 生成完全的xml注释
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="retractCount"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToXmlComments(this string context, int retractCount = 0)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Serein.NodeFlow.Services
|
||||
/// <summary>
|
||||
/// 流程API服务,用于外部调用流程接口
|
||||
/// </summary>
|
||||
public class FlowApiService
|
||||
internal class FlowApiService
|
||||
{
|
||||
private readonly IFlowEnvironment flowEnvironment;
|
||||
private readonly FlowModelService flowModelService;
|
||||
|
||||
@@ -20,6 +20,11 @@ namespace Serein.NodeFlow.Services
|
||||
private readonly FlowModelService flowModelService;
|
||||
private readonly FlowLibraryService flowLibraryService;
|
||||
|
||||
/// <summary>
|
||||
/// 流程代码生成服务
|
||||
/// </summary>
|
||||
/// <param name="flowModelService"></param>
|
||||
/// <param name="flowLibraryService"></param>
|
||||
public FlowCoreGenerateService(FlowModelService flowModelService ,FlowLibraryService flowLibraryService )
|
||||
{
|
||||
this.flowModelService = flowModelService;
|
||||
@@ -429,7 +434,6 @@ namespace Serein.NodeFlow.Services
|
||||
if (param is null) return;
|
||||
if (pds is null) return;
|
||||
|
||||
bool isGetPreviousNode = false;
|
||||
for (int index = 0; index < pds.Length; index++)
|
||||
{
|
||||
ParameterDetails? pd = pds[index];
|
||||
@@ -798,7 +802,6 @@ namespace Serein.NodeFlow.Services
|
||||
if (param is null) return;
|
||||
if (pds is null) return;
|
||||
|
||||
bool isGetPreviousNode = false;
|
||||
for (int index = 0; index < pds.Length; index++)
|
||||
{
|
||||
ParameterDetails? pd = pds[index];
|
||||
@@ -998,17 +1001,18 @@ namespace Serein.NodeFlow.Services
|
||||
sb.AppendCode(1, $"}}");
|
||||
}
|
||||
|
||||
public class SereinGlobalDataInfo
|
||||
|
||||
private class SereinGlobalDataInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 全局数据节点
|
||||
/// </summary>
|
||||
public SingleGlobalDataNode Node { get; set; }
|
||||
public required SingleGlobalDataNode Node { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 全局数据的来源节点
|
||||
/// </summary>
|
||||
public IFlowNode DataSourceNode { get; set; }
|
||||
public required IFlowNode DataSourceNode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 全局数据的键名
|
||||
|
||||
@@ -14,6 +14,10 @@ namespace Serein.NodeFlow.Services
|
||||
/// </summary>
|
||||
public class FlowLibraryService
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数,初始化流程依赖
|
||||
/// </summary>
|
||||
/// <param name="flowEnvironment"></param>
|
||||
public FlowLibraryService(IFlowEnvironment flowEnvironment)
|
||||
{
|
||||
this.flowEnvironment = flowEnvironment;
|
||||
@@ -35,10 +39,12 @@ namespace Serein.NodeFlow.Services
|
||||
/// 每个类库下面至少需要有“Serein.Library.dll”类库依赖
|
||||
/// </summary>
|
||||
/// <param name="libraryfilePath"></param>
|
||||
/// <param name="baseLibraryPath"></param>
|
||||
/// <returns></returns>
|
||||
private bool CheckBaseLibrary(string libraryfilePath, out string baseLibraryPath)
|
||||
{
|
||||
var dir = Path.GetDirectoryName(libraryfilePath); // 获取目录路径
|
||||
ArgumentNullException.ThrowIfNullOrWhiteSpace(dir);
|
||||
var sereinFlowBaseLibraryPath = Path.Combine(dir, SereinBaseLibrary);
|
||||
if (!Path.Exists(sereinFlowBaseLibraryPath))
|
||||
{
|
||||
@@ -146,7 +152,7 @@ namespace Serein.NodeFlow.Services
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">程序集名称</param>
|
||||
/// <param name="methodName">方法名称</param>
|
||||
/// <param name="md">返回的方法描述</param>
|
||||
/// <param name="methodInfo">返回的方法描述</param>
|
||||
/// <returns>是否获取成功</returns>
|
||||
public bool TryGetMethodInfo(string assemblyName, string methodName, [MaybeNullWhen(false)] out MethodInfo methodInfo)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Serein.Library.Api;
|
||||
using Serein.NodeFlow.Model;
|
||||
using Serein.NodeFlow.Model.Nodes;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Serein.NodeFlow.Services
|
||||
{
|
||||
@@ -13,6 +14,11 @@ namespace Serein.NodeFlow.Services
|
||||
private readonly IFlowEnvironment environment;
|
||||
private readonly FlowLibraryService flowLibraryService;
|
||||
|
||||
/// <summary>
|
||||
/// 流程模型服务构造函数
|
||||
/// </summary>
|
||||
/// <param name="environment"></param>
|
||||
/// <param name="flowLibraryService"></param>
|
||||
public FlowModelService(IFlowEnvironment environment, FlowLibraryService flowLibraryService)
|
||||
{
|
||||
this.environment = environment;
|
||||
@@ -35,72 +41,156 @@ namespace Serein.NodeFlow.Services
|
||||
/// </summary>
|
||||
private List<SingleFlipflopNode> FlipflopNodes { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 获取节点模型
|
||||
/// </summary>
|
||||
/// <param name="guid"></param>
|
||||
/// <returns></returns>
|
||||
public IFlowNode? GetNodeModel(string guid)
|
||||
{
|
||||
NodeModels.TryGetValue(guid, out var nodeModel);
|
||||
return nodeModel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取画布模型
|
||||
/// </summary>
|
||||
/// <param name="guid"></param>
|
||||
/// <returns></returns>
|
||||
public FlowCanvasDetails? GetCanvasModel(string guid)
|
||||
{
|
||||
FlowCanvass.TryGetValue(guid, out var nodeModel);
|
||||
return nodeModel;
|
||||
}
|
||||
|
||||
public bool TryGetNodeModel(string guid, out IFlowNode flowNode)
|
||||
/// <summary>
|
||||
/// 尝试获取节点模型
|
||||
/// </summary>
|
||||
/// <param name="guid"></param>
|
||||
/// <param name="flowNode"></param>
|
||||
/// <returns></returns>
|
||||
public bool TryGetNodeModel(string guid, [NotNullWhen(true)] out IFlowNode? flowNode)
|
||||
{
|
||||
return NodeModels.TryGetValue(guid, out flowNode!);
|
||||
}
|
||||
|
||||
public bool TryGetCanvasModel(string guid, out FlowCanvasDetails flowCanvas)
|
||||
/// <summary>
|
||||
/// 尝试获取画布模型
|
||||
/// </summary>
|
||||
/// <param name="guid"></param>
|
||||
/// <param name="flowCanvas"></param>
|
||||
/// <returns></returns>
|
||||
public bool TryGetCanvasModel(string guid, [NotNullWhen(true)] out FlowCanvasDetails? flowCanvas)
|
||||
{
|
||||
return FlowCanvass.TryGetValue(guid, out flowCanvas!); ;
|
||||
if(FlowCanvass.TryGetValue(guid, out var details))
|
||||
{
|
||||
flowCanvas = details;
|
||||
return true;
|
||||
}
|
||||
flowCanvas = details;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否包含节点模型
|
||||
/// </summary>
|
||||
/// <param name="guid"></param>
|
||||
/// <returns></returns>
|
||||
public bool ContainsNodeModel(string guid)
|
||||
{
|
||||
return NodeModels.ContainsKey(guid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否包含画布模型
|
||||
/// </summary>
|
||||
/// <param name="guid"></param>
|
||||
/// <returns></returns>
|
||||
public bool ContainsCanvasModel(string guid)
|
||||
{
|
||||
return FlowCanvass.ContainsKey(guid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加节点模型
|
||||
/// </summary>
|
||||
/// <param name="flowNode"></param>
|
||||
/// <returns></returns>
|
||||
public bool AddNodeModel(IFlowNode flowNode)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(flowNode);
|
||||
ArgumentNullException.ThrowIfNull(flowNode.Guid);
|
||||
return NodeModels.TryAdd(flowNode.Guid, flowNode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加画布模型
|
||||
/// </summary>
|
||||
/// <param name="flowCanvasDetails"></param>
|
||||
/// <returns></returns>
|
||||
public bool AddCanvasModel(FlowCanvasDetails flowCanvasDetails)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(flowCanvasDetails);
|
||||
ArgumentNullException.ThrowIfNull(flowCanvasDetails.Guid);
|
||||
return FlowCanvass.TryAdd(flowCanvasDetails.Guid, flowCanvasDetails);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除节点模型
|
||||
/// </summary>
|
||||
/// <param name="flowNode"></param>
|
||||
/// <returns></returns>
|
||||
public bool RemoveNodeModel(IFlowNode flowNode)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(flowNode.Guid);
|
||||
return NodeModels.Remove(flowNode.Guid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除画布模型
|
||||
/// </summary>
|
||||
/// <param name="flowCanvasDetails"></param>
|
||||
/// <returns></returns>
|
||||
public bool RemoveCanvasModel(FlowCanvasDetails flowCanvasDetails)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(flowCanvasDetails.Guid);
|
||||
return FlowCanvass.Remove(flowCanvasDetails.Guid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有节点模型
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<IFlowNode> GetAllNodeModel() => [.. NodeModels.Values];
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定画布上的所有节点模型
|
||||
/// </summary>
|
||||
/// <param name="canvasGuid"></param>
|
||||
/// <returns></returns>
|
||||
public List<IFlowNode> GetAllNodeModel(string canvasGuid) =>
|
||||
NodeModels.Values.Where(x => x.CanvasDetails.Guid == canvasGuid).ToList();
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有画布模型
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<FlowCanvasDetails> GetAllCanvasModel() => [.. FlowCanvass.Values];
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在画布模型
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool IsExsitCanvas()
|
||||
{
|
||||
return FlowCanvass.Count > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查指定画布上是否存在节点模型
|
||||
/// </summary>
|
||||
/// <param name="canvasGuid"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsExsitNodeOnCanvas(string canvasGuid)
|
||||
{
|
||||
if (!FlowCanvass.TryGetValue(canvasGuid, out var flowCanvasDetails))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Serein.Library.Api;
|
||||
using Serein.NodeFlow.Model.Operation;
|
||||
using Serein.NodeFlow.Model.Operations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@@ -17,11 +17,22 @@ namespace Serein.NodeFlow.Tool
|
||||
private AssemblyLoadContext context;
|
||||
private Dictionary<string, Type> dicTypes = new Dictionary<string, Type>();
|
||||
|
||||
/// <summary>
|
||||
/// 程序集加载器构造函数
|
||||
/// </summary>
|
||||
/// <param name="basePath"></param>
|
||||
public AssemblyLoader(string basePath)
|
||||
{
|
||||
_basePath = basePath;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 加载指定的类型
|
||||
/// </summary>
|
||||
/// <param name="dllFileName"></param>
|
||||
/// <param name="typeName"></param>
|
||||
/// <returns></returns>
|
||||
public Type Load(string dllFileName, string typeName)
|
||||
{
|
||||
context = new AssemblyLoadContext(dllFileName);
|
||||
|
||||
@@ -12,6 +12,9 @@ namespace Serein.NodeFlow.Tool
|
||||
{
|
||||
private readonly HashSet<MetadataReference> _references = new HashSet<MetadataReference>();
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的动态编译器实例。
|
||||
/// </summary>
|
||||
public DynamicCompiler()
|
||||
{
|
||||
// 默认添加当前 AppDomain 加载的所有程序集
|
||||
@@ -110,10 +113,6 @@ namespace Serein.NodeFlow.Tool
|
||||
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,11 @@ namespace Serein.NodeFlow.Tool
|
||||
/// </summary>
|
||||
public override Encoding Encoding => Encoding.UTF8;
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 重写Write方法,处理单个字符的写入
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public override void Write(char value)
|
||||
{
|
||||
stringWriter.Write(value);
|
||||
@@ -43,6 +47,10 @@ namespace Serein.NodeFlow.Tool
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重写Write方法,处理字符串的写入
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public override void Write(string? value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value)) return;
|
||||
@@ -53,6 +61,10 @@ namespace Serein.NodeFlow.Tool
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重写WriteLine方法,处理字符串的换行写入
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public override void WriteLine(string? value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value)) return;
|
||||
|
||||
@@ -103,8 +103,7 @@ namespace Serein.NodeFlow.Tool
|
||||
/// <summary>
|
||||
/// 加载Windows类库
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="isRecurrence">是否递归加载</param>
|
||||
/// <param name="file"></param>
|
||||
private static bool LoadWindowsLibrarie(string file)
|
||||
{
|
||||
IntPtr hModule = IntPtr.Zero;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Serein.Library;
|
||||
using Serein.Library.Api;
|
||||
using Serein.Library.Utils;
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
@@ -7,6 +8,9 @@ using System.Reflection;
|
||||
|
||||
namespace Serein.NodeFlow.Tool;
|
||||
|
||||
/// <summary>
|
||||
/// 节点方法描述帮助类
|
||||
/// </summary>
|
||||
public static class NodeMethodDetailsHelper
|
||||
{
|
||||
|
||||
@@ -25,15 +29,16 @@ public static class NodeMethodDetailsHelper
|
||||
/// <param name="type">方法所属的类型</param>
|
||||
/// <param name="methodInfo">方法信息</param>
|
||||
/// <param name="assemblyName">方法所属的程序集名称</param>
|
||||
/// <param name="outMethodInfo">传出的方法信息</param>
|
||||
/// <param name="methodDetails">创建的方法描述,用来生成节点信息</param>
|
||||
/// <param name="delegateDetails">方法对应的Emit动态委托</param>
|
||||
/// <returns>指示是否创建成功</returns>
|
||||
public static bool TryCreateDetails(Type type,
|
||||
MethodInfo methodInfo,
|
||||
string assemblyName,
|
||||
[MaybeNullWhen(false)] out MethodInfo outMethodInfo,
|
||||
[MaybeNullWhen(false)] out MethodDetails methodDetails,
|
||||
[MaybeNullWhen(false)] out DelegateDetails delegateDetails)
|
||||
[NotNullWhen(true)] out MethodInfo? outMethodInfo,
|
||||
[NotNullWhen(true)] out MethodDetails? methodDetails,
|
||||
[NotNullWhen(true)] out DelegateDetails? delegateDetails)
|
||||
{
|
||||
|
||||
|
||||
@@ -60,7 +65,7 @@ public static class NodeMethodDetailsHelper
|
||||
|
||||
|
||||
Type? returnType;
|
||||
bool isAsync = IsGenericTask(methodInfo.ReturnType, out var taskResult);
|
||||
bool isAsync = EmitHelper.IsGenericTask(methodInfo.ReturnType, out var taskResult);
|
||||
bool isStatic = methodInfo.IsStatic;
|
||||
|
||||
|
||||
@@ -172,6 +177,12 @@ public static class NodeMethodDetailsHelper
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取方法签名
|
||||
/// </summary>
|
||||
/// <param name="method"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetMethodSignature(MethodInfo method)
|
||||
{
|
||||
if (method == null) return string.Empty;
|
||||
@@ -184,28 +195,8 @@ public static class NodeMethodDetailsHelper
|
||||
return $"{methodName}({parameters})";
|
||||
//return $"{methodName}({parameters}) : {returnType}";
|
||||
}
|
||||
public static bool IsGenericTask(Type returnType, out Type? taskResult)
|
||||
{
|
||||
// 判断是否为 Task 类型或泛型 Task<T>
|
||||
if (returnType == typeof(Task))
|
||||
{
|
||||
taskResult = null;
|
||||
return true;
|
||||
}
|
||||
else if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>))
|
||||
{
|
||||
// 获取泛型参数类型
|
||||
Type genericArgument = returnType.GetGenericArguments()[0];
|
||||
taskResult = genericArgument;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
taskResult = null;
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static ConcurrentDictionary<string, (object, MethodInfo)> ConvertorInstance =[];
|
||||
@@ -231,6 +222,7 @@ public static class NodeMethodDetailsHelper
|
||||
}
|
||||
#endregion
|
||||
#region 存在自定义的转换器
|
||||
#if false
|
||||
else if (it.GetCustomAttribute<BindConvertorAttribute>() is BindConvertorAttribute attribute2 && attribute2 is not null)
|
||||
{
|
||||
paremType = attribute2.EnumType;
|
||||
@@ -262,6 +254,8 @@ public static class NodeMethodDetailsHelper
|
||||
|
||||
return ed;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endregion
|
||||
#region 常规方法的获取参数
|
||||
else
|
||||
|
||||
@@ -7,11 +7,20 @@ using System.Reflection.Emit;
|
||||
namespace Serein.NodeFlow.Tool
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 动态创建对象的帮助类,支持根据属性字典创建对象并设置属性值。
|
||||
/// </summary>
|
||||
public class ObjDynamicCreateHelper
|
||||
{
|
||||
// 类型缓存,键为类型的唯一名称(可以根据实际需求调整生成方式)
|
||||
static Dictionary<string, Type> typeCache = new Dictionary<string, Type>();
|
||||
|
||||
/// <summary>
|
||||
/// 根据属性字典和类型名称创建对象实例,并设置属性值。
|
||||
/// </summary>
|
||||
/// <param name="properties"></param>
|
||||
/// <param name="typeName"></param>
|
||||
/// <returns></returns>
|
||||
public static object Resolve(Dictionary<string, object> properties, string typeName)
|
||||
{
|
||||
var obj = CreateObjectWithProperties(properties, typeName);
|
||||
|
||||
Reference in New Issue
Block a user