diff --git a/.gitignore b/.gitignore
index ced4e34..16ea43e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,7 +20,9 @@ obj/
# 排除发布文件夹
.Output/
/.git1
+doc
WorkBench.ControlLibrary.Core
WorkBench.Remote
Serein.FlowStartTool
-Serein.CloudWorkbench
\ No newline at end of file
+Serein.CloudWorkbench
+Serein.CollaborationSync
\ No newline at end of file
diff --git a/Library/Api/IFlowEnvironment.cs b/Library/Api/IFlowEnvironment.cs
index a5d85c3..d095342 100644
--- a/Library/Api/IFlowEnvironment.cs
+++ b/Library/Api/IFlowEnvironment.cs
@@ -873,8 +873,6 @@ namespace Serein.Library.Api
///
void ExitRemoteEnv();
-
-
///
/// (用于远程)通知节点属性变更
///
diff --git a/Library/FlowNode/ParameterDetails.cs b/Library/FlowNode/ParameterDetails.cs
index c7864b2..908b5d0 100644
--- a/Library/FlowNode/ParameterDetails.cs
+++ b/Library/FlowNode/ParameterDetails.cs
@@ -8,7 +8,6 @@ using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
-
namespace Serein.Library
{
@@ -118,6 +117,11 @@ namespace Serein.Library
public partial class ParameterDetails
{
+
+
+
+
+
///
/// 用于创建元数据
diff --git a/Library/FlowNode/SereinProjectData.cs b/Library/FlowNode/SereinProjectData.cs
index 8d7944f..8b7a3f0 100644
--- a/Library/FlowNode/SereinProjectData.cs
+++ b/Library/FlowNode/SereinProjectData.cs
@@ -28,6 +28,8 @@ namespace Serein.Library
// IOC节点对象信息
}
+
+
///
/// 程序集相关的方法信息
///
@@ -64,12 +66,6 @@ namespace Serein.Library
public NodeLibraryInfo[] Librarys { get; set; }
- /////
- ///// 起始节点GUID
- /////
-
- //public string StartNode { get; set; }
-
///
/// 画布集合
///
@@ -100,45 +96,7 @@ namespace Serein.Library
}
- /* ///
- /// 画布信息,项目文件相关
- ///
- public class FlowCanvasInfo
- {
- public string Guid { get; set; }
-
- public string Name { get; set; }
-
- ///
- /// 宽度
- ///
- public double Width { get; set; }
- ///
- /// 高度
- ///
- public double Height { get; set; }
-
- ///
- /// 预览位置X
- ///
- public double ViewX { get; set; }
-
- ///
- /// 预览位置Y
- ///
- public double ViewY { get; set; }
-
- ///
- /// 缩放比例X
- ///
- public double ScaleX { get; set; }
-
- ///
- /// 缩放比例Y
- ///
- public double ScaleY { get; set; }
- }*/
-
+
///
/// 项目依赖的程序集,项目文件相关
///
@@ -161,27 +119,7 @@ namespace Serein.Library
public string AssemblyName { get; set; }
}
- #region 暂时注释
- /*public class LibraryInfo
-{
- ///
- /// 文件名称
- ///
-
- public string FileName { get; set; }
-
- ///
- /// 文件路径
- ///
- public string FilePath { get; set; }
-
- ///
- /// 程序集名称
- ///
- public string AssemblyName { get; set; }
-}*/
- #endregion
-
+
///
/// 节点信息,项目文件相关
///
@@ -291,6 +229,8 @@ namespace Serein.Library
public dynamic CustomData { get; set; }
}
+
+
///
/// 参数信息,项目文件相关
///
diff --git a/Library/Serein.Library.csproj b/Library/Serein.Library.csproj
index f8baeb8..c54d5e4 100644
--- a/Library/Serein.Library.csproj
+++ b/Library/Serein.Library.csproj
@@ -2,10 +2,8 @@
1.2.0
-
net8.0;net462
..\.\.Output
-
True
SereinFow
动态节点流、可视化编辑的基本依赖,支持导入C# DLL生成自定义节点,提供二次开发支持,适合用于可视化编程和流程设计
diff --git a/Library/SereinBaseFunction.cs b/Library/SereinBaseFunction.cs
index c0d8961..6be3ab2 100644
--- a/Library/SereinBaseFunction.cs
+++ b/Library/SereinBaseFunction.cs
@@ -18,6 +18,8 @@ namespace Serein.Library
public class SereinBaseFunction
{
+
+
[NodeAction(NodeType.Action, "键值对组装")]
private Dictionary SereinKvDataCollectionNode(string argName,
params object[] value)
diff --git a/Library/Utils/ConvertHelper.cs b/Library/Utils/ConvertHelper.cs
index ba9b238..c3ac1c6 100644
--- a/Library/Utils/ConvertHelper.cs
+++ b/Library/Utils/ConvertHelper.cs
@@ -150,7 +150,7 @@ namespace Serein.Library.Utils
///
- /// 对象转换(好像没啥用)
+ /// 对象转换为对应类型
///
///
///
diff --git a/NodeFlow/Env/FlowEnvironment.cs b/NodeFlow/Env/FlowEnvironment.cs
index 8e1075a..493953f 100644
--- a/NodeFlow/Env/FlowEnvironment.cs
+++ b/NodeFlow/Env/FlowEnvironment.cs
@@ -77,14 +77,12 @@ namespace Serein.NodeFlow.Env
private MsgControllerOfServer clientMsgManage;
-
///
/// 表示是否正在控制远程
/// Local control remote env
///
public bool IsControlRemoteEnv { get; set; }
-
///
/// 打开远程管理
///
@@ -1521,10 +1519,13 @@ namespace Serein.NodeFlow.Env
///
public Task NotificationNodeValueChangeAsync(string nodeGuid, string path, object value)
{
+ // "NodeModel.Path"
if (TryGetNodeModel(nodeGuid, out var nodeModel))
{
SerinExpressionEvaluator.Evaluate($"@Set .{path} = {value}", nodeModel, out _); // 更改对应的数据
}
+
+
return Task.CompletedTask;
//if (NodeValueChangeLogger.Remove((nodeGuid, path, value)))
//{
diff --git a/NodeFlow/FlowNodeExtension.cs b/NodeFlow/FlowNodeExtension.cs
index 21e3212..1b63c82 100644
--- a/NodeFlow/FlowNodeExtension.cs
+++ b/NodeFlow/FlowNodeExtension.cs
@@ -20,11 +20,10 @@ namespace Serein.NodeFlow
///
public static bool IsBaseNode(this NodeControlType nodeControlType)
{
-
var nodeDesc = EnumHelper.GetAttribute(nodeControlType);
- if("base".Equals(nodeDesc?.Description, StringComparison.OrdinalIgnoreCase))
+ if("base".Equals(nodeDesc?.Description, StringComparison.OrdinalIgnoreCase))
{
- return true;
+ return true;
}
return false;
}
diff --git a/Serein.Library.MyGenerator/ParameterDetailsPropertyGenerator.cs b/Serein.Library.MyGenerator/ParameterDetailsPropertyGenerator.cs
index e4c5229..433c661 100644
--- a/Serein.Library.MyGenerator/ParameterDetailsPropertyGenerator.cs
+++ b/Serein.Library.MyGenerator/ParameterDetailsPropertyGenerator.cs
@@ -125,11 +125,10 @@ namespace Serein.Library.NodeGenerator
sb.AppendLine($"using System.Collections.Generic;");
sb.AppendLine($"using Serein.Library;");
sb.AppendLine($"using Serein.Library.Api;");
- //sb.AppendLine($"using static Serein.Library.Utils.ChannelFlowInterrupt;");
sb.AppendLine($"");
- sb.AppendLine($"namespace {namespaceName}");
+ sb.AppendLine($"namespace {namespaceName}"); // 命名空间
sb.AppendLine("{");
- sb.AppendLine($" public partial class {className} : System.ComponentModel.INotifyPropertyChanged");
+ sb.AppendLine($" public partial class {className} : global::System.ComponentModel.INotifyPropertyChanged"); // 类名
sb.AppendLine(" {");
//object path = null ;
@@ -143,10 +142,6 @@ namespace Serein.Library.NodeGenerator
// "ParameterDetails";
// "MethodDetails";
-
-
-
-
try
{
var expInfo = MyAttributeResolver.BuildCacheOfField(classSyntax.Members.OfType());
@@ -158,35 +153,46 @@ namespace Serein.Library.NodeGenerator
continue;
}
- var leadingTrivia = field.GetLeadingTrivia().InsertSummaryComment("(此属性为自动生成)").ToString(); // 获取注释
+ //var leadingTrivia = field.GetLeadingTrivia().InsertSummaryComment("(此属性为自动生成)").ToString(); // 获取注释
var fieldName = field.Declaration.Variables.First().Identifier.Text; // 获取字段名称
var fieldType = field.Declaration.Type.ToString(); // 获取字段类型
var propertyName = field.ToPropertyName(); // 转为合适的属性名称
var attributeInfo = fieldKV.Value; // 缓存的特性信息
var isProtection = attributeInfo.Search(nameof(PropertyInfo), nameof(PropertyInfo.IsProtection), value => bool.Parse(value)); // 是否为保护字段
-
- sb.AppendLine($" partial void On{propertyName}Changed({fieldType} oldValue,{fieldType} newValue);");
+ //sb.AppendLine(leadingTrivia);
+ sb.AppendLine($" partial void On{propertyName}Changed({fieldType} oldValue, {fieldType} newValue);");
sb.AppendLine($" partial void On{propertyName}Changed({fieldType} value);");
+ sb.AppendLine();
// 生成 getter / setter
- sb.AppendLine(leadingTrivia);
+ sb.AppendLine($" /// ");
+ sb.AppendLine( " [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]");
sb.AppendLine($" public {fieldType} {propertyName}");
sb.AppendLine(" {");
sb.AppendLine($" get => {fieldName};"); // getter方法
- sb.AppendLine(" set");
- sb.AppendLine(" {");
+ sb.AppendLine( " set");
+ sb.AppendLine( " {");
sb.AppendLine($" if ({fieldName} {(isProtection ? "== default" : "!= value")})"); // 非保护的Setter
- sb.AppendLine(" {");
+ sb.AppendLine( " {");
sb.AppendLine($" var __oldValue = {fieldName};");
sb.AppendLine($" SetProperty<{fieldType}>(ref {fieldName}, value); // 通知UI属性发生改变了");
sb.AppendLine($" On{propertyName}Changed(value);");
sb.AppendLine($" On{propertyName}Changed(__oldValue, value);");
- if (attributeInfo.Search(nameof(PropertyInfo), nameof(PropertyInfo.IsPrint), value => bool.Parse(value))) // 是否打印
+ if (attributeInfo.Search(nameof(PropertyInfo), nameof(PropertyInfo.IsPrint), value => bool.Parse(value)))
{
sb.AddCode(5, $"Console.WriteLine({fieldName});");
- }
+ } // 是否打印
+
+ // private void ValueChangedNotificationRemoteEnv(string nodeGuid, string nodeValuePath, string proprtyName, string fieldType, string otherData = null)
+
+ // NodeValuePath.Node : 作用在节点
+ // NodeValuePath.DebugSetting : 节点 → 参数信息
+ // NodeValuePath.Method : 节点 → 方法描述
+ // NodeValuePath.Parameter : 节点 → 方法描述 → 参数描述
+
if (attributeInfo.Search(nameof(PropertyInfo), nameof(PropertyInfo.IsNotification), value => bool.Parse(value))) // 是否通知
{
+
if (classInfo.ExitsPath(nameof(NodeValuePath.Node))) // 节点 or 自定义节点
{
sb.AddCode(5, $"if (this?.Env?.IsControlRemoteEnv == true) // 正在控制远程环境时才触发");
@@ -214,9 +220,9 @@ namespace Serein.Library.NodeGenerator
}
sb.AddCode(5, $"}}");
}
-
- }
-
+
+ } // 是否通知
+
sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine(" }"); // 属性的结尾大括号
@@ -250,6 +256,11 @@ namespace Serein.Library.NodeGenerator
sb.AppendLine(" ");
sb.AppendLine(" ");
sb.AppendLine(" ");
+
+ // 生成变量修改
+
+
+
//sb.AppendLine(" /// ");
//sb.AppendLine(" /// 略 ");
//sb.AppendLine(" /// 此方法为自动生成 ");
@@ -272,11 +283,40 @@ namespace Serein.Library.NodeGenerator
return sb.ToString(); // 返回生成的代码
}
-
-
-
-
-
+
+
+
+ /*private void ModifyValue(string path, string value)
+ {
+ if (string.IsNullOrWhiteSpace(path))
+ {
+ return;
+ }
+ else if (path.Equals(nameof(MaxChildrenCount), StringComparison.OrdinalIgnoreCase))
+ {
+ if (typeof(int) == typeof(string))
+ {
+ this.MaxChildrenCount = value;
+ }
+ else
+ {
+ this.MaxChildrenCount = ConvertHelper.ValueParse(value);
+ }
+ }
+ else if (path.Equals(nameof(Guid), StringComparison.OrdinalIgnoreCase))
+ {
+ if (typeof(string) == typeof(string))
+ {
+ this.Guid = value;
+ }
+ else
+ {
+ this.Guid = ConvertHelper.ValueParse(value);
+ }
+ }
+ }*/
+
+
///
/// 获取类所在的命名空间。
///
@@ -310,7 +350,7 @@ namespace Serein.Library.NodeGenerator
///
- /// 为 XML 文档注释中的 标签插入指定的文本
+ /// 为 XML 文档注释中的 summary 标签插入指定的文本
///
/// 语法节点的 LeadingTrivia 或 TrailingTrivia 列表
/// 要插入的注释文本
@@ -348,14 +388,19 @@ namespace Serein.Library.NodeGenerator
var paraElement = SyntaxFactory.XmlElement(
SyntaxFactory.XmlElementStartTag(SyntaxFactory.XmlName("para")), // 起始标签
SyntaxFactory.SingletonList( // 内容
- SyntaxFactory.XmlText(comment).WithLeadingTrivia(SyntaxFactory.Whitespace(" "))
+ SyntaxFactory.XmlText(comment)
),
SyntaxFactory.XmlElementEndTag(SyntaxFactory.XmlName("para")) // 结束标签
);
+ // WithLeadingTrivia(SyntaxFactory.Whitespace(""))
+
+ // .AddContent(SyntaxFactory.XmlNewLine("123")
// 将 插入到 中
- var updatedSummaryNode = summaryNode.AddContent(paraElement);
+ var updatedSummaryNode = summaryNode.AddContent(paraElement).AddContent();
+
+
// 用新的 标签替换原来的
var updatedStructuredTrivia = structuredTrivia.ReplaceNode(summaryNode, updatedSummaryNode);
diff --git a/SereinFlow.sln b/SereinFlow.sln
index 7a2ba7c..aaa40ec 100644
--- a/SereinFlow.sln
+++ b/SereinFlow.sln
@@ -26,6 +26,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serein.Workbench.Avalonia",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serein.Workbench.Avalonia.Desktop", "Serein.Workbench.Avalonia.Desktop\Serein.Workbench.Avalonia.Desktop.csproj", "{D46C9E9E-9994-45E6-8084-A8A9497B1DC2}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serein.CollaborationSync", "Serein.CollaborationSync\Serein.CollaborationSync.csproj", "{913AAB34-7383-4F9D-A7DF-A5E6191DDB3D}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -68,6 +70,10 @@ Global
{D46C9E9E-9994-45E6-8084-A8A9497B1DC2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D46C9E9E-9994-45E6-8084-A8A9497B1DC2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D46C9E9E-9994-45E6-8084-A8A9497B1DC2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {913AAB34-7383-4F9D-A7DF-A5E6191DDB3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {913AAB34-7383-4F9D-A7DF-A5E6191DDB3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {913AAB34-7383-4F9D-A7DF-A5E6191DDB3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {913AAB34-7383-4F9D-A7DF-A5E6191DDB3D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Workbench/Services/FlowNodeService.cs b/Workbench/Services/FlowNodeService.cs
index e5b2ea2..25841f1 100644
--- a/Workbench/Services/FlowNodeService.cs
+++ b/Workbench/Services/FlowNodeService.cs
@@ -35,11 +35,6 @@ namespace Serein.Workbench.Services
///
public Action OnRemoveFlowCanvasView { get; set; }
- ///
- /// 添加了节点
- ///
- public Action OnCreateNode { get; set; }
-
///
/// 查看的画布发生改变
///
@@ -356,7 +351,11 @@ namespace Serein.Workbench.Services
nodeMVVM.ViewModelType, // 控件VIewModel类型
nodeModel, // 控件数据实体
nodeCanvas); // 所在画布
- OnCreateNode.Invoke(nodeControl); // 创建节点
+
+ if(nodeCanvas is IFlowCanvas flowCanvas)
+ {
+ flowCanvas.Add(nodeControl); // 创建节点
+ }
}
catch (Exception ex)
{
diff --git a/Workbench/Views/FlowCanvasView.xaml.cs b/Workbench/Views/FlowCanvasView.xaml.cs
index 5aff73a..a070243 100644
--- a/Workbench/Views/FlowCanvasView.xaml.cs
+++ b/Workbench/Views/FlowCanvasView.xaml.cs
@@ -173,7 +173,6 @@ namespace Serein.Workbench.Views
private void InitEvent()
{
- flowNodeService.OnCreateNode += OnCreateNode;
keyEventService.OnKeyDown += KeyEventService_OnKeyDown;
flowEEForwardingService.OnNodeLocated += FlowEEForwardingService_OnNodeLocated;
}
@@ -273,7 +272,7 @@ namespace Serein.Workbench.Views
/// 当前画布创建了节点
///
///
- private void OnCreateNode(NodeControlBase nodeControl)
+ /* private void OnCreateNode(NodeControlBase nodeControl)
{
if (!nodeControl.FlowCanvas.Guid.Equals(Guid)) // 防止事件传播到其它画布
{
@@ -295,7 +294,7 @@ namespace Serein.Workbench.Views
}
- }
+ }*/
///
/// 尝试判断是否为区域,如果是,将节点放置在区域中
@@ -367,6 +366,18 @@ namespace Serein.Workbench.Views
}
void IFlowCanvas.Add(NodeControlBase nodeControl)
{
+ var p = nodeControl.ViewModel.NodeModel.Position;
+ PositionOfUI position = new PositionOfUI(p.X, p.Y);
+ if (TryPlaceNodeInRegion(nodeControl, position, out var regionControl)) // 判断添加到区域容器
+ {
+ // 通知运行环境调用加载节点子项的方法
+ _ = flowEnvironment.PlaceNodeToContainerAsync(Guid,
+ nodeControl.ViewModel.NodeModel.Guid, // 待移动的节点
+ regionControl.ViewModel.NodeModel.Guid); // 目标的容器节点
+ return;
+ }
+
+ // 并非添加在容器中,直接放置节点
ViewModel.NodeControls.TryAdd(nodeControl.ViewModel.NodeModel.Guid, nodeControl);