From 0666f0b2c1e8fd965582da33965cd5f1d6b1ff85 Mon Sep 17 00:00:00 2001
From: fengjiayi <12821976+ning_xi@user.noreply.gitee.com>
Date: Wed, 23 Oct 2024 19:22:27 +0800
Subject: [PATCH] =?UTF-8?q?=E5=87=86=E5=A4=87=E5=8C=BA=E5=88=86=E8=8A=82?=
=?UTF-8?q?=E7=82=B9=E3=80=81=E5=8F=82=E6=95=B0=E3=80=81=E8=BF=94=E5=9B=9E?=
=?UTF-8?q?=E5=80=BC=E7=9A=84=E8=BF=9E=E6=8E=A5=EF=BC=8C=E5=81=9A=E4=B8=AA?=
=?UTF-8?q?=E5=A4=87=E4=BB=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Library/Api/IFlowEnvironment.cs | 2 +-
Library/Enums/ConnectionType.cs | 5 +-
Library/Enums/JunctionType.cs | 31 +
Library/FlowNode/MethodDetails.cs | 10 +-
Library/FlowNode/NodeDebugSetting.cs | 9 +-
Library/FlowNode/NodeModelBaseData.cs | 59 +-
Library/FlowNode/ParameterDetails.cs | 10 +-
Library/FlowNode/SereinProjectData.cs | 28 +-
Library/Utils/EnumHelper.cs | 17 +-
NodeFlow/Env/FlowEnvironment.cs | 69 +-
NodeFlow/Env/FlowEnvironmentDecorator.cs | 4 +-
NodeFlow/Env/RemoteFlowEnvironment.cs | 28 +-
NodeFlow/FlowStarter.cs | 1 +
.../ParameterDetailsPropertyGenerator.cs | 38 +-
WorkBench/App.xaml | 2 +
WorkBench/App.xaml.cs | 42 +-
WorkBench/MainWindow.xaml | 5 +-
WorkBench/MainWindow.xaml.cs | 656 +++---------------
WorkBench/Node/NodeControlViewModelBase.cs | 53 +-
WorkBench/Node/View/ActionNodeControl.xaml | 71 +-
WorkBench/Node/View/ActionNodeControl.xaml.cs | 4 +-
WorkBench/Serein.WorkBench.csproj | 5 +
WorkBench/Themes/MethodDetailsControl.xaml | 41 +-
WorkBench/Themes/MethodDetailsControl.xaml.cs | 2 +-
Workbench/Extension/MyExtension.cs | 42 ++
Workbench/Node/Junction/JunctionCode.cs | 93 +++
Workbench/Node/Junction/JunctionData.cs | 69 ++
.../Node/Junction/NodeJunctionViewBase.cs | 237 +++++++
.../Node/Junction/View/ArgJunctionControl.cs | 54 ++
.../Junction/View/ExecuteJunctionControl.cs | 39 ++
.../Junction/View/NextStepJunctionControl.cs | 38 +
.../Junction/View/ResultJunctionControl.cs | 39 ++
.../Node}/NodeControlBase.cs | 31 +-
Workbench/Node/View/ConnectionControl.cs | 320 +++++++++
Workbench/Themes/ConnectionControl.xaml | 10 +
Workbench/Themes/ConnectionControl.xaml.cs | 89 +++
36 files changed, 1497 insertions(+), 756 deletions(-)
create mode 100644 Library/Enums/JunctionType.cs
create mode 100644 Workbench/Extension/MyExtension.cs
create mode 100644 Workbench/Node/Junction/JunctionCode.cs
create mode 100644 Workbench/Node/Junction/JunctionData.cs
create mode 100644 Workbench/Node/Junction/NodeJunctionViewBase.cs
create mode 100644 Workbench/Node/Junction/View/ArgJunctionControl.cs
create mode 100644 Workbench/Node/Junction/View/ExecuteJunctionControl.cs
create mode 100644 Workbench/Node/Junction/View/NextStepJunctionControl.cs
create mode 100644 Workbench/Node/Junction/View/ResultJunctionControl.cs
rename {WorkBench/Node/View => Workbench/Node}/NodeControlBase.cs (58%)
create mode 100644 Workbench/Node/View/ConnectionControl.cs
create mode 100644 Workbench/Themes/ConnectionControl.xaml
create mode 100644 Workbench/Themes/ConnectionControl.xaml.cs
diff --git a/Library/Api/IFlowEnvironment.cs b/Library/Api/IFlowEnvironment.cs
index 7719fc4..fce88a0 100644
--- a/Library/Api/IFlowEnvironment.cs
+++ b/Library/Api/IFlowEnvironment.cs
@@ -664,7 +664,7 @@ namespace Serein.Library.Api
/// 起始节点Guid
/// 目标节点Guid
/// 连接类型
- Task ConnectNodeAsync(string fromNodeGuid, string toNodeGuid, ConnectionType connectionType);
+ Task ConnectNodeAsync(string fromNodeGuid, string toNodeGuid, JunctionType fromNodeJunctionType, JunctionType toNodeJunctionType, ConnectionType connectionType);
///
/// 创建节点/区域/基础控件
diff --git a/Library/Enums/ConnectionType.cs b/Library/Enums/ConnectionType.cs
index fd26784..9412f99 100644
--- a/Library/Enums/ConnectionType.cs
+++ b/Library/Enums/ConnectionType.cs
@@ -30,7 +30,10 @@ namespace Serein.Library
/// 异常发生分支(当前节点对应的方法执行时出现非预期的异常)
///
IsError,
-
+ ///
+ /// 无视
+ ///
+ // IsIgnore,
}
diff --git a/Library/Enums/JunctionType.cs b/Library/Enums/JunctionType.cs
new file mode 100644
index 0000000..83941fb
--- /dev/null
+++ b/Library/Enums/JunctionType.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Serein.Library
+{
+ ///
+ /// 连接点类型
+ ///
+ public enum JunctionType
+ {
+ ///
+ /// 当前执行
+ ///
+ Execute,
+ ///
+ /// 入参
+ ///
+ ArgData,
+ ///
+ /// 返回值
+ ///
+ ReturnData,
+ ///
+ /// 下一步要执行的节点
+ ///
+ NextStep,
+ }
+}
diff --git a/Library/FlowNode/MethodDetails.cs b/Library/FlowNode/MethodDetails.cs
index 07cd638..a329bcc 100644
--- a/Library/FlowNode/MethodDetails.cs
+++ b/Library/FlowNode/MethodDetails.cs
@@ -13,7 +13,13 @@ namespace Serein.Library
public partial class MethodDetails
{
private readonly IFlowEnvironment env;
- private readonly NodeModelBase nodeModel;
+
+ ///
+ /// 对应的节点
+ ///
+ [PropertyInfo(IsProtection = true)]
+ private NodeModelBase _nodeModel;
+
///
/// 是否保护参数(目前仅视觉效果参数,不影响运行实现,后续将设置作用在运行逻辑中)
///
@@ -88,7 +94,7 @@ namespace Serein.Library
/// 标识属于哪个节点
public MethodDetails(IFlowEnvironment env, NodeModelBase nodeModel)
{
- this.nodeModel = nodeModel;
+ NodeModel = nodeModel;
}
diff --git a/Library/FlowNode/NodeDebugSetting.cs b/Library/FlowNode/NodeDebugSetting.cs
index 7cfc4fd..f4dd378 100644
--- a/Library/FlowNode/NodeDebugSetting.cs
+++ b/Library/FlowNode/NodeDebugSetting.cs
@@ -12,14 +12,19 @@ namespace Serein.Library
[NodeProperty(ValuePath = NodeValuePath.DebugSetting)]
public partial class NodeDebugSetting
{
- private readonly NodeModelBase nodeModel;
+ ///
+ /// 对应的节点
+ ///
+ [PropertyInfo(IsProtection = true)]
+ private NodeModelBase _nodeModel;
+
///
/// 创建属于某个节点的调试设置
///
///
public NodeDebugSetting(NodeModelBase nodeModel)
{
- this.nodeModel = nodeModel;
+ NodeModel = nodeModel;
}
///
/// 是否使能
diff --git a/Library/FlowNode/NodeModelBaseData.cs b/Library/FlowNode/NodeModelBaseData.cs
index cb92d99..5021a68 100644
--- a/Library/FlowNode/NodeModelBaseData.cs
+++ b/Library/FlowNode/NodeModelBaseData.cs
@@ -14,61 +14,60 @@ namespace Serein.Library
[NodeProperty(ValuePath = NodeValuePath.None)]
public abstract partial class NodeModelBase : IDynamicFlowNode
{
-
-
+ ///
+ /// 节点运行环境
+ ///
[PropertyInfo(IsProtection = true)]
private IFlowEnvironment _env;
+ ///
+ /// 标识节点对象全局唯一
+ ///
+ [PropertyInfo(IsProtection = true)]
+ private string _guid;
+
+ ///
+ /// 描述节点对应的控件类型
+ ///
+ [PropertyInfo(IsProtection = true)]
+ private NodeControlType _controlType;
+
///
/// 在画布中的位置
///
[PropertyInfo(IsProtection = true)]
private PositionOfUI _position ;
+ ///
+ /// 显示名称
+ ///
+ [PropertyInfo]
+ private string _displayName;
+
+ ///
+ /// 是否为起点控件
+ ///
+ [PropertyInfo]
+ private bool _isStart;
+
///
/// 附加的调试功能
///
[PropertyInfo(IsProtection = true)]
private NodeDebugSetting _debugSetting ;
- ///
- /// 描述节点对应的控件类型
- ///
- [PropertyInfo(IsProtection = true)]
- private NodeControlType _controlType ;
-
///
/// 方法描述。不包含Method与委托,需要通过MethodName从环境中获取委托进行调用。
///
[PropertyInfo(IsProtection = true)]
private MethodDetails _methodDetails ;
- ///
- /// 标识节点对象全局唯一
- ///
- [PropertyInfo(IsProtection = true)]
- private string _guid ;
-
- ///
- /// 显示名称
- ///
- [PropertyInfo]
- private string _displayName ;
-
- ///
- /// 是否为起点控件
- ///
- [PropertyInfo]
- private bool _isStart ;
-
///
/// 运行时的上一节点
///
[PropertyInfo]
private NodeModelBase _previousNode ;
-
-
///
/// 当前节点执行完毕后需要执行的下一个分支的类别
///
@@ -81,10 +80,11 @@ namespace Serein.Library
[PropertyInfo]
private Exception _runingException ;
+
}
-
+
public abstract partial class NodeModelBase : IDynamicFlowNode
@@ -112,6 +112,7 @@ namespace Serein.Library
///
public Dictionary> SuccessorNodes { get; }
+
///
/// 控制FlowData在同一时间只会被同一个线程更改。
///
diff --git a/Library/FlowNode/ParameterDetails.cs b/Library/FlowNode/ParameterDetails.cs
index 54b25e8..d9c9491 100644
--- a/Library/FlowNode/ParameterDetails.cs
+++ b/Library/FlowNode/ParameterDetails.cs
@@ -15,7 +15,13 @@ namespace Serein.Library
public partial class ParameterDetails
{
private readonly IFlowEnvironment env;
- private readonly NodeModelBase nodeModel;
+
+ ///
+ /// 对应的节点
+ ///
+ [PropertyInfo(IsProtection = true)]
+ private NodeModelBase _nodeModel;
+
///
/// 参数索引
///
@@ -83,7 +89,7 @@ namespace Serein.Library
public ParameterDetails(IFlowEnvironment env, NodeModelBase nodeModel)
{
this.env = env;
- this.nodeModel = nodeModel;
+ this.NodeModel = nodeModel;
}
///
/// 通过参数信息加载实体,用于加载项目文件、远程连接的场景
diff --git a/Library/FlowNode/SereinProjectData.cs b/Library/FlowNode/SereinProjectData.cs
index 1dcf25c..708dd41 100644
--- a/Library/FlowNode/SereinProjectData.cs
+++ b/Library/FlowNode/SereinProjectData.cs
@@ -244,26 +244,30 @@ namespace Serein.Library
///
- /// 节点于画布中的位置
+ /// 节点于画布中的位置(通用类)
///
- public class PositionOfUI
- { ///
- /// 构造一个坐标
- ///
- public PositionOfUI()
- {
-
- }
+ [NodeProperty]
+ public partial class PositionOfUI
+ {
///
/// 构造一个坐标
///
public PositionOfUI(double x, double y)
{
- X = x; Y = y;
+ _x = x; _y = y;
}
- public double X { get; set; } = 0;
- public double Y { get; set; } = 0;
+ ///
+ /// 指示控件在画布的横向向方向上的位置
+ ///
+ [PropertyInfo]
+ private double _x = 0;
+
+ ///
+ /// 指示控件在画布的纵向方向上的位置
+ ///
+ [PropertyInfo]
+ private double _y = 0;
}
diff --git a/Library/Utils/EnumHelper.cs b/Library/Utils/EnumHelper.cs
index 43e2e45..b2a06cb 100644
--- a/Library/Utils/EnumHelper.cs
+++ b/Library/Utils/EnumHelper.cs
@@ -26,8 +26,21 @@ namespace Serein.Library.Utils
result = default;
return false;
}
-
-
+
+ ///
+ /// 将字符串的字面量枚举值,转为对应的枚举值
+ ///
+ /// 枚举
+ /// 枚举字面量
+ /// 转换后的枚举值
+ public static TEnum ConvertEnum(this string value) where TEnum : struct, Enum
+ {
+ if (!string.IsNullOrEmpty(value) && Enum.TryParse(value, true, out TEnum tempResult) && Enum.IsDefined(typeof(TEnum), tempResult))
+ {
+ return tempResult;
+ }
+ throw new NotImplementedException($"枚举值转换失败:value({value})to enum ( {typeof(TEnum).FullName})");
+ }
///
/// 从枚举值的 BindValueAttribute 特性中 获取绑定的参数(用于绑定了某些内容的枚举值)
diff --git a/NodeFlow/Env/FlowEnvironment.cs b/NodeFlow/Env/FlowEnvironment.cs
index d23b216..9dea87b 100644
--- a/NodeFlow/Env/FlowEnvironment.cs
+++ b/NodeFlow/Env/FlowEnvironment.cs
@@ -249,7 +249,7 @@ namespace Serein.NodeFlow.Env
/// 环境加载的节点集合
/// Node Guid - Node Model
///
- private Dictionary Nodes { get; } = [];
+ private Dictionary NodeModels { get; } = [];
///
/// 存放触发器节点(运行时全部调用)
@@ -340,7 +340,7 @@ namespace Serein.NodeFlow.Env
{
ChannelFlowInterrupt?.CancelAllTasks();
flowStarter = new FlowStarter();
- var nodes = Nodes.Values.ToList();
+ var nodes = NodeModels.Values.ToList();
List initMethods = [];
List loadMethods = [];
@@ -417,7 +417,7 @@ namespace Serein.NodeFlow.Env
ChannelFlowInterrupt?.CancelAllTasks();
flowStarter?.Exit();
- foreach (var node in Nodes.Values)
+ foreach (var node in NodeModels.Values)
{
if (node is not null)
{
@@ -588,7 +588,7 @@ namespace Serein.NodeFlow.Env
{
foreach (var childNodeGuid in item.childNodeGuids)
{
- Nodes.TryGetValue(childNodeGuid, out NodeModelBase? childNode);
+ NodeModels.TryGetValue(childNodeGuid, out NodeModelBase? childNode);
if (childNode is null)
{
// 节点尚未加载
@@ -621,35 +621,39 @@ namespace Serein.NodeFlow.Env
// 确定节点之间的连接关系
- foreach (var nodeInfo in projectData.Nodes)
+ Task.Run(async () =>
{
- if (!Nodes.TryGetValue(nodeInfo.Guid, out NodeModelBase? fromNode))
+ await Task.Delay(777);
+ foreach (var nodeInfo in projectData.Nodes)
{
- // 不存在对应的起始节点
- continue;
- }
+ if (!NodeModels.TryGetValue(nodeInfo.Guid, out NodeModelBase? fromNode))
+ {
+ // 不存在对应的起始节点
+ continue;
+ }
- List<(ConnectionType connectionType, string[] guids)> allToNodes = [(ConnectionType.IsSucceed,nodeInfo.TrueNodes),
+ List<(ConnectionType connectionType, string[] guids)> allToNodes = [(ConnectionType.IsSucceed,nodeInfo.TrueNodes),
(ConnectionType.IsFail, nodeInfo.FalseNodes),
(ConnectionType.IsError, nodeInfo.ErrorNodes),
(ConnectionType.Upstream, nodeInfo.UpstreamNodes)];
- List<(ConnectionType, NodeModelBase[])> fromNodes = allToNodes.Where(info => info.guids.Length > 0)
- .Select(info => (info.connectionType,
- info.guids.Where(guid => Nodes.ContainsKey(guid)).Select(guid => Nodes[guid])
- .ToArray()))
- .ToList();
- // 遍历每种类型的节点分支(四种)
- foreach ((ConnectionType connectionType, NodeModelBase[] toNodes) item in fromNodes)
- {
- // 遍历当前类型分支的节点(确认连接关系)
- foreach (var toNode in item.toNodes)
+ List<(ConnectionType, NodeModelBase[])> fromNodes = allToNodes.Where(info => info.guids.Length > 0)
+ .Select(info => (info.connectionType,
+ info.guids.Where(guid => NodeModels.ContainsKey(guid)).Select(guid => NodeModels[guid])
+ .ToArray()))
+ .ToList();
+ // 遍历每种类型的节点分支(四种)
+ foreach ((ConnectionType connectionType, NodeModelBase[] toNodes) item in fromNodes)
{
- ConnectNodeAsync(fromNode, toNode, item.connectionType); // 加载时确定节点间的连接关系
+ // 遍历当前类型分支的节点(确认连接关系)
+ foreach (var toNode in item.toNodes)
+ {
+ ConnectNodeAsync(fromNode, toNode, item.connectionType); // 加载时确定节点间的连接关系
+ }
}
}
- }
+ });
SetStartNode(projectData.StartNode);
UIContextOperation?.Invoke(() => OnProjectLoaded?.Invoke(new ProjectLoadedEventArgs()));
@@ -710,8 +714,8 @@ namespace Serein.NodeFlow.Env
var projectData = new SereinProjectData()
{
Librarys = Librarys.Values.Select(lib => lib.ToLibrary()).ToArray(),
- Nodes = Nodes.Values.Select(node => node.ToInfo()).Where(info => info is not null).ToArray(),
- StartNode = Nodes.Values.FirstOrDefault(it => it.IsStart)?.Guid,
+ Nodes = NodeModels.Values.Select(node => node.ToInfo()).Where(info => info is not null).ToArray(),
+ StartNode = NodeModels.Values.FirstOrDefault(it => it.IsStart)?.Guid,
};
return Task.FromResult(projectData);
}
@@ -740,7 +744,7 @@ namespace Serein.NodeFlow.Env
{
return false;
}
- var groupedNodes = Nodes.Values
+ var groupedNodes = NodeModels.Values
.Where(node => node.MethodDetails is not null)
.ToArray()
.GroupBy(node => node.MethodDetails!.MethodName)
@@ -749,7 +753,7 @@ namespace Serein.NodeFlow.Env
group => group.Count());
- if (Nodes.Count == 0)
+ if (NodeModels.Count == 0)
{
return true; // 当前无节点,可以直接删除
}
@@ -877,7 +881,7 @@ namespace Serein.NodeFlow.Env
}
// 从集合中移除节点
- Nodes.Remove(nodeGuid);
+ NodeModels.Remove(nodeGuid);
UIContextOperation?.Invoke(() => OnNodeRemove?.Invoke(new NodeRemoveEventArgs(nodeGuid)));
return true;
}
@@ -887,8 +891,10 @@ namespace Serein.NodeFlow.Env
///
/// 起始节点
/// 目标节点
+ /// 起始节点控制点
+ /// 目标节点控制点
/// 连接关系
- public async Task ConnectNodeAsync(string fromNodeGuid, string toNodeGuid, ConnectionType connectionType)
+ public async Task ConnectNodeAsync(string fromNodeGuid, string toNodeGuid, JunctionType fromNodeJunctionType, JunctionType toNodeJunctionType, ConnectionType connectionType)
{
// 获取起始节点与目标节点
var fromNode = GuidToModel(fromNodeGuid);
@@ -978,9 +984,10 @@ namespace Serein.NodeFlow.Env
///
public void MoveNode(string nodeGuid, double x, double y)
{
- var nodeModel = GuidToModel(nodeGuid);
+ NodeModelBase? nodeModel = GuidToModel(nodeGuid);
if (nodeModel is null) return;
nodeModel.Position.X = x;
+
nodeModel.Position.Y = y;
UIContextOperation?.Invoke(() => OnNodeMoved?.Invoke(new NodeMovedEventArgs(nodeGuid, x, y)));
@@ -1225,7 +1232,7 @@ namespace Serein.NodeFlow.Env
//throw new ArgumentNullException("not contains - Guid没有对应节点:" + (nodeGuid));
return null;
}
- if (!Nodes.TryGetValue(nodeGuid, out NodeModelBase? nodeModel) || nodeModel is null)
+ if (!NodeModels.TryGetValue(nodeGuid, out NodeModelBase? nodeModel) || nodeModel is null)
{
//throw new ArgumentNullException("null - Guid存在对应节点,但节点为null:" + (nodeGuid));
return null;
@@ -1410,7 +1417,7 @@ namespace Serein.NodeFlow.Env
private bool TryAddNode(NodeModelBase nodeModel)
{
nodeModel.Guid ??= Guid.NewGuid().ToString();
- Nodes[nodeModel.Guid] = nodeModel;
+ NodeModels[nodeModel.Guid] = nodeModel;
// 如果是触发器,则需要添加到专属集合中
if (nodeModel is SingleFlipflopNode flipflopNode)
diff --git a/NodeFlow/Env/FlowEnvironmentDecorator.cs b/NodeFlow/Env/FlowEnvironmentDecorator.cs
index a9848ef..bf18881 100644
--- a/NodeFlow/Env/FlowEnvironmentDecorator.cs
+++ b/NodeFlow/Env/FlowEnvironmentDecorator.cs
@@ -180,9 +180,9 @@ namespace Serein.NodeFlow.Env
currentFlowEnvironment.ClearAll();
}
- public async Task ConnectNodeAsync(string fromNodeGuid, string toNodeGuid, ConnectionType connectionType)
+ public async Task ConnectNodeAsync(string fromNodeGuid, string toNodeGuid, JunctionType fromNodeJunctionType, JunctionType toNodeJunctionType, ConnectionType connectionType)
{
- return await currentFlowEnvironment.ConnectNodeAsync(fromNodeGuid, toNodeGuid, connectionType);
+ return await currentFlowEnvironment.ConnectNodeAsync(fromNodeGuid, toNodeGuid, fromNodeJunctionType, toNodeJunctionType, connectionType);
}
public async Task<(bool, RemoteEnvControl)> ConnectRemoteEnv(string addres, int port, string token)
diff --git a/NodeFlow/Env/RemoteFlowEnvironment.cs b/NodeFlow/Env/RemoteFlowEnvironment.cs
index 9b963f7..bdfb37e 100644
--- a/NodeFlow/Env/RemoteFlowEnvironment.cs
+++ b/NodeFlow/Env/RemoteFlowEnvironment.cs
@@ -38,7 +38,7 @@ namespace Serein.NodeFlow.Env
/// 环境加载的节点集合
/// Node Guid - Node Model
///
- private Dictionary Nodes { get; } = [];
+ private Dictionary NodeModels { get; } = [];
public event LoadDllHandler OnDllLoad;
public event ProjectLoadedHandler OnProjectLoaded;
@@ -173,7 +173,7 @@ namespace Serein.NodeFlow.Env
{
foreach (var childNodeGuid in item.childNodeGuids)
{
- Nodes.TryGetValue(childNodeGuid, out NodeModelBase? childNode);
+ NodeModels.TryGetValue(childNodeGuid, out NodeModelBase? childNode);
if (childNode is null)
{
// 节点尚未加载
@@ -211,7 +211,7 @@ namespace Serein.NodeFlow.Env
await Task.Delay(250);
foreach (var nodeInfo in projectData.Nodes)
{
- if (!Nodes.TryGetValue(nodeInfo.Guid, out NodeModelBase? fromNode))
+ if (!NodeModels.TryGetValue(nodeInfo.Guid, out NodeModelBase? fromNode))
{
// 不存在对应的起始节点
continue;
@@ -225,7 +225,7 @@ namespace Serein.NodeFlow.Env
List<(ConnectionType, NodeModelBase[])> fromNodes = allToNodes.Where(info => info.guids.Length > 0)
.Select(info => (info.connectionType,
- info.guids.Where(guid => Nodes.ContainsKey(guid)).Select(guid => Nodes[guid])
+ info.guids.Where(guid => NodeModels.ContainsKey(guid)).Select(guid => NodeModels[guid])
.ToArray()))
.ToList();
// 遍历每种类型的节点分支(四种)
@@ -259,7 +259,7 @@ namespace Serein.NodeFlow.Env
private bool TryAddNode(NodeModelBase nodeModel)
{
//nodeModel.Guid ??= Guid.NewGuid().ToString();
- Nodes[nodeModel.Guid] = nodeModel;
+ NodeModels[nodeModel.Guid] = nodeModel;
// 如果是触发器,则需要添加到专属集合中
//if (nodeModel is SingleFlipflopNode flipflopNode)
@@ -395,10 +395,10 @@ namespace Serein.NodeFlow.Env
public void MoveNode(string nodeGuid, double x, double y)
{
- UIContextOperation.Invoke(() =>
- {
- OnNodeMoved.Invoke(new NodeMovedEventArgs(nodeGuid, x, y));
- });
+ //UIContextOperation?.Invoke(() =>
+ //{
+ // OnNodeMoved?.Invoke(new NodeMovedEventArgs(nodeGuid, x, y));
+ //});
_ = msgClient.SendAsync(EnvMsgTheme.MoveNode,
new
{
@@ -406,6 +406,12 @@ namespace Serein.NodeFlow.Env
x,
y
});
+
+ if(NodeModels.TryGetValue(nodeGuid, out var nodeModel))
+ {
+ nodeModel.Position.X = x;
+ nodeModel.Position.Y = y;
+ }
}
@@ -418,12 +424,14 @@ namespace Serein.NodeFlow.Env
//UIContextOperation?.Invoke(() => OnStartNodeChange?.Invoke(new StartNodeChangeEventArgs(nodeGuid,nodeGuid)));
}
- public async Task ConnectNodeAsync(string fromNodeGuid, string toNodeGuid, ConnectionType connectionType)
+ public async Task ConnectNodeAsync(string fromNodeGuid, string toNodeGuid, JunctionType fromNodeJunctionType, JunctionType toNodeJunctionType, ConnectionType connectionType)
{
var result = await msgClient.SendAndWaitDataAsync(EnvMsgTheme.ConnectNode, new
{
fromNodeGuid,
toNodeGuid,
+ fromNodeJunctionType = fromNodeJunctionType.ToString(),
+ toNodeJunctionType = toNodeJunctionType.ToString(),
connectionType = connectionType.ToString(),
});
if (result)
diff --git a/NodeFlow/FlowStarter.cs b/NodeFlow/FlowStarter.cs
index d74a63c..c784236 100644
--- a/NodeFlow/FlowStarter.cs
+++ b/NodeFlow/FlowStarter.cs
@@ -335,6 +335,7 @@ namespace Serein.NodeFlow
}
dictGlobalFlipflop.Clear();
}
+
///
/// 启动全局触发器
///
diff --git a/Serein.Library.MyGenerator/ParameterDetailsPropertyGenerator.cs b/Serein.Library.MyGenerator/ParameterDetailsPropertyGenerator.cs
index 860ff5b..677e111 100644
--- a/Serein.Library.MyGenerator/ParameterDetailsPropertyGenerator.cs
+++ b/Serein.Library.MyGenerator/ParameterDetailsPropertyGenerator.cs
@@ -130,9 +130,12 @@ namespace Serein.Library.NodeGenerator
sb.AppendLine($" public partial class {className} : System.ComponentModel.INotifyPropertyChanged");
sb.AppendLine(" {");
- var path = classInfo[nameof(NodePropertyAttribute)]["ValuePath"];
+ //object path = null ;
+ //if(classInfo.TryGetValue(nameof(NodePropertyAttribute), out var values))
+ //{
+ // values.TryGetValue(nameof(NodePropertyAttribute.ValuePath), out path); // 获取路径
+ //}
-
//
//
@@ -161,8 +164,6 @@ namespace Serein.Library.NodeGenerator
var isProtection = attributeInfo.Search(nameof(PropertyInfo), nameof(PropertyInfo.IsProtection), "true"); // 是否为保护字段
-
-
// 生成 getter / setter
sb.AppendLine(leadingTrivia);
sb.AppendLine($" public {fieldType} {propertyName}");
@@ -184,15 +185,15 @@ namespace Serein.Library.NodeGenerator
}
else if (classInfo.ExitsPath(nameof(NodeValuePath.Method))) // 节点方法详情
{
- sb.AddCode(5, $"nodeModel?.Env?.NotificationNodeValueChangeAsync(nodeModel.Guid, \"MethodDetails.\"+nameof({propertyName}), value); // 通知远程环境属性发生改变了");
+ sb.AddCode(5, $"NodeModel?.Env?.NotificationNodeValueChangeAsync(NodeModel.Guid, \"MethodDetails.\"+nameof({propertyName}), value); // 通知远程环境属性发生改变了");
}
else if (classInfo.ExitsPath(nameof(NodeValuePath.Parameter))) // 节点方法入参参数描述
{
- sb.AddCode(5, "nodeModel?.Env?.NotificationNodeValueChangeAsync(nodeModel.Guid, \"MethodDetails.ParameterDetailss[\"+$\"{Index}\"+\"]." + $"\"+nameof({propertyName}),value); // 通知远程环境属性发生改变了");
+ sb.AddCode(5, "NodeModel?.Env?.NotificationNodeValueChangeAsync(NodeModel.Guid, \"MethodDetails.ParameterDetailss[\"+$\"{Index}\"+\"]." + $"\"+nameof({propertyName}),value); // 通知远程环境属性发生改变了");
}
else if (classInfo.ExitsPath(nameof(NodeValuePath.DebugSetting))) // 节点的调试信息
{
- sb.AddCode(5, $"nodeModel?.Env?.NotificationNodeValueChangeAsync(nodeModel.Guid, \"DebugSetting.\"+nameof({propertyName}), value); // 通知远程环境属性发生改变了");
+ sb.AddCode(5, $"NodeModel?.Env?.NotificationNodeValueChangeAsync(NodeModel.Guid, \"DebugSetting.\"+nameof({propertyName}), value); // 通知远程环境属性发生改变了");
}
}
sb.AppendLine($" SetProperty<{fieldType}>(ref {fieldName}, value); // 通知UI属性发生改变了");
@@ -223,20 +224,21 @@ namespace Serein.Library.NodeGenerator
sb.AppendLine(" } ");
sb.AppendLine(" ");
sb.AppendLine(" storage = value; ");
- sb.AppendLine(" OnPropertyChanged(propertyName); ");
+ //sb.AppendLine(" OnPropertyChanged(propertyName); ");
+ sb.AppendLine(" PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); ");
sb.AppendLine(" } ");
- sb.AppendLine(" /// ");
- sb.AppendLine(" /// 略 ");
- sb.AppendLine(" /// 此方法为自动生成 ");
- sb.AppendLine(" /// ");
- sb.AppendLine(" /// ");
- sb.AppendLine(" ");
- sb.AppendLine(" protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null) ");
- sb.AppendLine(" {");
+ //sb.AppendLine(" /// ");
+ //sb.AppendLine(" /// 略 ");
+ //sb.AppendLine(" /// 此方法为自动生成 ");
+ //sb.AppendLine(" /// ");
+ //sb.AppendLine(" /// ");
+ //sb.AppendLine(" ");
+ //sb.AppendLine(" protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null) ");
+ //sb.AppendLine(" {");
//sb.AppendLine(" Console.WriteLine(\"测试:\"+ propertyName);");
- sb.AppendLine(" PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); ");
- sb.AppendLine(" }");
+ //sb.AppendLine(" PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); ");
+ //sb.AppendLine(" }");
}
finally
diff --git a/WorkBench/App.xaml b/WorkBench/App.xaml
index e6ecadf..fe41f68 100644
--- a/WorkBench/App.xaml
+++ b/WorkBench/App.xaml
@@ -10,6 +10,8 @@
+
+