From e819b63d65cbe8c894c163c781d860ea2e2cddb2 Mon Sep 17 00:00:00 2001 From: Ivo Petrov Date: Tue, 24 Sep 2024 07:33:49 +0100 Subject: [PATCH 1/6] centers on groups --- TuneUp/ProfiledNodeViewModel.cs | 3 ++- TuneUp/TuneUpWindow.xaml.cs | 29 +++++++++++------------------ 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/TuneUp/ProfiledNodeViewModel.cs b/TuneUp/ProfiledNodeViewModel.cs index 53468c9..228f16b 100644 --- a/TuneUp/ProfiledNodeViewModel.cs +++ b/TuneUp/ProfiledNodeViewModel.cs @@ -333,6 +333,7 @@ public string StateDescription internal Stopwatch Stopwatch { get; set; } internal NodeModel NodeModel { get; set; } + internal AnnotationModel GroupModel { get; set; } #endregion @@ -367,7 +368,7 @@ public ProfiledNodeViewModel(string name, TimeSpan exTimeSum, ProfiledNodeState /// the annotation model public ProfiledNodeViewModel(AnnotationModel group) { - NodeModel = null; + GroupModel = group; Name = $"{GroupNodePrefix}{group.AnnotationText}"; GroupName = group.AnnotationText; GroupGUID = group.GUID; diff --git a/TuneUp/TuneUpWindow.xaml.cs b/TuneUp/TuneUpWindow.xaml.cs index 9cb571d..034810b 100644 --- a/TuneUp/TuneUpWindow.xaml.cs +++ b/TuneUp/TuneUpWindow.xaml.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Linq; @@ -8,7 +7,7 @@ using System.Windows.Data; using System.Windows.Media; using Dynamo.Extensions; -using Dynamo.Graph.Nodes; +using Dynamo.Graph; using Dynamo.Models; using Dynamo.UI; using Dynamo.Utilities; @@ -56,26 +55,20 @@ private void NodeAnalysisTable_SelectionChanged(object sender, SelectionChangedE { if (!isUserInitiatedSelection) return; - // Get NodeModel(s) that correspond to selected row(s) - var selectedNodes = new List(); - foreach (var item in e.AddedItems) - { - // Check NodeModel valid before actual selection - var nodeModel = (item as ProfiledNodeViewModel).NodeModel; - if (nodeModel != null) - { - selectedNodes.Add(nodeModel); - } - } + var selectedItem = e.AddedItems.OfType().FirstOrDefault(); + if (selectedItem == null) return; + + // Extract the GUID and type (NodeModel or GroupModel) + var modelBase = selectedItem.NodeModel ?? (ModelBase)selectedItem.GroupModel; - if (selectedNodes.Count() > 0) + if (modelBase != null) { - // Select - var command = new DynamoModel.SelectModelCommand(selectedNodes.Select(nm => nm.GUID), ModifierKeys.None); + // Execute selection command + var command = new DynamoModel.SelectModelCommand(new[] { modelBase.GUID }, ModifierKeys.None); commandExecutive.ExecuteCommand(command, uniqueId, "TuneUp"); - // Focus on selected - viewModelCommandExecutive.FindByIdCommand(selectedNodes.First().GUID.ToString()); + // Focus on selected element + viewModelCommandExecutive.FindByIdCommand(modelBase.GUID.ToString()); } } From 69ea32e320ffbaaf1b93f91d8bf9dc6c8d2f9a32 Mon Sep 17 00:00:00 2001 From: Ivo Petrov Date: Tue, 24 Sep 2024 09:41:17 +0100 Subject: [PATCH 2/6] mid progress record --- TuneUp/ProfiledNodeViewModel.cs | 51 ++++++++++++++++++++------------- TuneUp/TuneUpWindow.xaml.cs | 3 +- TuneUpTests/TuneUpTests.cs | 8 +++--- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/TuneUp/ProfiledNodeViewModel.cs b/TuneUp/ProfiledNodeViewModel.cs index 228f16b..a3f3eb9 100644 --- a/TuneUp/ProfiledNodeViewModel.cs +++ b/TuneUp/ProfiledNodeViewModel.cs @@ -5,6 +5,7 @@ using System.Reflection; using System.Windows.Media; using Dynamo.Core; +using Dynamo.Graph; using Dynamo.Graph.Annotations; using Dynamo.Graph.Nodes; using Dynamo.Graph.Nodes.CustomNodes; @@ -15,7 +16,7 @@ namespace TuneUp public class ProfiledNodeViewModel : NotificationObject { #region Properties - + /// /// Checks if the Node has been Renamed after its creation /// @@ -23,11 +24,10 @@ public bool IsRenamed { get { - if (NodeModel == null) + if (ModelBase is NodeModel node) { - return false; + isRenamed = GetOriginalName(node) != node.Name; } - isRenamed = GetOriginalName(NodeModel) != NodeModel.Name; return isRenamed; } internal set @@ -46,9 +46,11 @@ public string OriginalName { get { - //string originalName = NodeModel.GetOriginalName(); - string originalName = GetOriginalName(NodeModel); - return originalName; + if (ModelBase is NodeModel node) + { + return GetOriginalName(node); + } + return string.Empty; } internal set { @@ -76,8 +78,6 @@ public bool IsGroupExecutionTime /// /// Getting the original name before graph author renamed the node /// - /// target NodeModel - /// Original node name as string private static string GetOriginalName(NodeModel node) { if (node == null) return string.Empty; @@ -125,13 +125,25 @@ private static string GetOriginalName(NodeModel node) /// public string Name { - get + get { - // For virtual row, do not attempt to grab node name - if (!name.Contains(ExecutionTimelString) && - !name.StartsWith(GroupNodePrefix) && - !name.Equals(GroupExecutionTimeString)) - name = NodeModel?.Name; + // For virtual row, do not attempt to grab node or group name if it's already handled + //if (!name.Contains(ExecutionTimelString) && + // !name.StartsWith(GroupNodePrefix) && + // !name.Equals(GroupExecutionTimeString)) + if (this.ModelBase !=null) + { + + // Check the type of BaseModel and assign the appropriate name + if (ModelBase is NodeModel node) + { + name = node.Name; + } + else if (ModelBase is AnnotationModel group) + { + name = group.AnnotationText; // Get AnnotationModel (group) name + } + } return name; } internal set { name = value; } @@ -332,8 +344,7 @@ public string StateDescription /// internal Stopwatch Stopwatch { get; set; } - internal NodeModel NodeModel { get; set; } - internal AnnotationModel GroupModel { get; set; } + internal ModelBase ModelBase { get; set; } #endregion @@ -343,7 +354,7 @@ public string StateDescription /// public ProfiledNodeViewModel(NodeModel node) { - NodeModel = node; + ModelBase = node; State = ProfiledNodeState.NotExecuted; Stopwatch = new Stopwatch(); } @@ -356,7 +367,7 @@ public ProfiledNodeViewModel(NodeModel node) /// state which determine grouping public ProfiledNodeViewModel(string name, TimeSpan exTimeSum, ProfiledNodeState state) { - NodeModel = null; + ModelBase = null; this.Name = name; this.ExecutionTime = exTimeSum; State = state; @@ -368,7 +379,7 @@ public ProfiledNodeViewModel(string name, TimeSpan exTimeSum, ProfiledNodeState /// the annotation model public ProfiledNodeViewModel(AnnotationModel group) { - GroupModel = group; + ModelBase = group; Name = $"{GroupNodePrefix}{group.AnnotationText}"; GroupName = group.AnnotationText; GroupGUID = group.GUID; diff --git a/TuneUp/TuneUpWindow.xaml.cs b/TuneUp/TuneUpWindow.xaml.cs index 034810b..cf794bf 100644 --- a/TuneUp/TuneUpWindow.xaml.cs +++ b/TuneUp/TuneUpWindow.xaml.cs @@ -58,8 +58,7 @@ private void NodeAnalysisTable_SelectionChanged(object sender, SelectionChangedE var selectedItem = e.AddedItems.OfType().FirstOrDefault(); if (selectedItem == null) return; - // Extract the GUID and type (NodeModel or GroupModel) - var modelBase = selectedItem.NodeModel ?? (ModelBase)selectedItem.GroupModel; + var modelBase = selectedItem.ModelBase; if (modelBase != null) { diff --git a/TuneUpTests/TuneUpTests.cs b/TuneUpTests/TuneUpTests.cs index d2b6c92..fe4a485 100644 --- a/TuneUpTests/TuneUpTests.cs +++ b/TuneUpTests/TuneUpTests.cs @@ -53,7 +53,7 @@ public void TuneUpCreatesProfilingDataForEveryNodeInWorkspace() var profiledNodes = tuneUpVE.ViewModel.ProfiledNodesNotExecuted; foreach (var node in nodes) { - Assert.Contains(node.GUID, profiledNodes.Select(n => n.NodeModel.GUID).ToList()); + Assert.Contains(node.GUID, profiledNodes.Select(n => n.ModelBase.GUID).ToList()); } RunCurrentModel(); @@ -94,7 +94,7 @@ public void TuneUpMaintainsProfiledNodeState() Assert.AreEqual(ProfiledNodeState.ExecutedOnCurrentRun, node.State); } - // Mark downstream node as modified so that it gets reexecuted on the next graph run + // Mark downstream node as modified so that it gets re-executed on the next graph run var modifiedNodeID = new Guid("1e49be233be846688122ac48d70ce961"); var homespace = Model.CurrentWorkspace as HomeWorkspaceModel; homespace.Nodes.Where(n => n.GUID == modifiedNodeID).First().MarkNodeAsModified(true); @@ -104,7 +104,7 @@ public void TuneUpMaintainsProfiledNodeState() DispatcherUtil.DoEvents(); foreach (var node in profiledNodes) { - if (node.NodeModel.GUID == modifiedNodeID) + if (node.ModelBase.GUID == modifiedNodeID) { Assert.AreEqual(ProfiledNodeState.ExecutedOnCurrentRun, node.State); } @@ -159,7 +159,7 @@ public void TuneUpDeterminesCorrectNodeExecutionOrder() DispatcherUtil.DoEvents(); foreach (var node in profiledNodes) { - var expected = executionOrderDict[node.NodeModel.GUID]; + var expected = executionOrderDict[node.ModelBase.GUID]; Assert.AreEqual(expected, node.ExecutionOrderNumber); } } From 08a100265473c03a632eb309b5d4cd4267fc0c3d Mon Sep 17 00:00:00 2001 From: Ivo Petrov Date: Tue, 24 Sep 2024 10:57:25 +0100 Subject: [PATCH 3/6] works - option 1 --- TuneUp/ProfiledNodeViewModel.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/TuneUp/ProfiledNodeViewModel.cs b/TuneUp/ProfiledNodeViewModel.cs index a3f3eb9..21ab858 100644 --- a/TuneUp/ProfiledNodeViewModel.cs +++ b/TuneUp/ProfiledNodeViewModel.cs @@ -128,10 +128,7 @@ public string Name get { // For virtual row, do not attempt to grab node or group name if it's already handled - //if (!name.Contains(ExecutionTimelString) && - // !name.StartsWith(GroupNodePrefix) && - // !name.Equals(GroupExecutionTimeString)) - if (this.ModelBase !=null) + if (!this.IsGroupExecutionTime) { // Check the type of BaseModel and assign the appropriate name From e82d6747a01db301807600e5eb23d1dbe5b27528 Mon Sep 17 00:00:00 2001 From: Ivo Petrov Date: Tue, 24 Sep 2024 11:49:45 +0100 Subject: [PATCH 4/6] draft for PR --- TuneUp/ProfiledNodeViewModel.cs | 63 +++++++++++---------------------- TuneUp/TuneUpWindow.xaml.cs | 23 ++++++++++-- TuneUp/TuneUpWindowViewModel.cs | 2 +- TuneUpTests/TuneUpTests.cs | 6 ++-- 4 files changed, 45 insertions(+), 49 deletions(-) diff --git a/TuneUp/ProfiledNodeViewModel.cs b/TuneUp/ProfiledNodeViewModel.cs index 21ab858..80fb921 100644 --- a/TuneUp/ProfiledNodeViewModel.cs +++ b/TuneUp/ProfiledNodeViewModel.cs @@ -24,10 +24,11 @@ public bool IsRenamed { get { - if (ModelBase is NodeModel node) + if (NodeModel == null) { - isRenamed = GetOriginalName(node) != node.Name; + return false; } + isRenamed = GetOriginalName(NodeModel) != NodeModel.Name; return isRenamed; } internal set @@ -46,11 +47,7 @@ public string OriginalName { get { - if (ModelBase is NodeModel node) - { - return GetOriginalName(node); - } - return string.Empty; + return GetOriginalName(NodeModel); } internal set { @@ -64,16 +61,7 @@ internal set /// /// Indicates whether this node represents the total execution time for its group /// - public bool IsGroupExecutionTime - { - get => isGroupExecutionTime; - set - { - isGroupExecutionTime = value; - RaisePropertyChanged(nameof(IsGroupExecutionTime)); - } - } - private bool isGroupExecutionTime = false; + public bool IsGroupExecutionTime => NodeModel == null && GroupModel == null; /// /// Getting the original name before graph author renamed the node @@ -113,9 +101,11 @@ private static string GetOriginalName(NodeModel node) /// /// Prefix string of execution time. /// - public static readonly string ExecutionTimelString = "Execution Time"; - public static readonly string GroupNodePrefix = "Group: "; - public static readonly string GroupExecutionTimeString = "Group total"; + internal const string ExecutionTimelString = "Execution Time"; + internal const string GroupNodePrefix = "Group: "; + internal const string GroupExecutionTimeString = "Group total"; + private const string DefaultGroupName = "Title "; + private const string DefaultDisplayGroupName = "Title"; private string name = String.Empty; /// @@ -130,15 +120,14 @@ public string Name // For virtual row, do not attempt to grab node or group name if it's already handled if (!this.IsGroupExecutionTime) { - - // Check the type of BaseModel and assign the appropriate name - if (ModelBase is NodeModel node) + if (NodeModel != null) { - name = node.Name; + return NodeModel.Name; } - else if (ModelBase is AnnotationModel group) + else if (GroupModel != null) { - name = group.AnnotationText; // Get AnnotationModel (group) name + return GroupModel.AnnotationText == DefaultGroupName ? + $"{GroupNodePrefix}{DefaultDisplayGroupName}" : GroupModel.AnnotationText; } } return name; @@ -279,16 +268,7 @@ public string GroupName /// /// Indicates if this node is a group /// - public bool IsGroup - { - get => isGroup; - set - { - isGroup = value; - RaisePropertyChanged(nameof(IsGroup)); - } - } - private bool isGroup; + public bool IsGroup => NodeModel == null && GroupModel != null; public bool ShowGroupIndicator { @@ -341,7 +321,9 @@ public string StateDescription /// internal Stopwatch Stopwatch { get; set; } - internal ModelBase ModelBase { get; set; } + internal NodeModel NodeModel { get; set; } + + internal AnnotationModel GroupModel { get; set; } #endregion @@ -351,7 +333,7 @@ public string StateDescription /// public ProfiledNodeViewModel(NodeModel node) { - ModelBase = node; + NodeModel = node; State = ProfiledNodeState.NotExecuted; Stopwatch = new Stopwatch(); } @@ -364,7 +346,6 @@ public ProfiledNodeViewModel(NodeModel node) /// state which determine grouping public ProfiledNodeViewModel(string name, TimeSpan exTimeSum, ProfiledNodeState state) { - ModelBase = null; this.Name = name; this.ExecutionTime = exTimeSum; State = state; @@ -376,12 +357,10 @@ public ProfiledNodeViewModel(string name, TimeSpan exTimeSum, ProfiledNodeState /// the annotation model public ProfiledNodeViewModel(AnnotationModel group) { - ModelBase = group; - Name = $"{GroupNodePrefix}{group.AnnotationText}"; + GroupModel = group; GroupName = group.AnnotationText; GroupGUID = group.GUID; BackgroundBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString(group.Background)); - IsGroup = true; State = ProfiledNodeState.NotExecuted; ShowGroupIndicator = true; } diff --git a/TuneUp/TuneUpWindow.xaml.cs b/TuneUp/TuneUpWindow.xaml.cs index cf794bf..addcf05 100644 --- a/TuneUp/TuneUpWindow.xaml.cs +++ b/TuneUp/TuneUpWindow.xaml.cs @@ -56,17 +56,34 @@ private void NodeAnalysisTable_SelectionChanged(object sender, SelectionChangedE if (!isUserInitiatedSelection) return; var selectedItem = e.AddedItems.OfType().FirstOrDefault(); + if (selectedItem == null) return; - var modelBase = selectedItem.ModelBase; + // Extract the GUID and type (NodeModel or GroupModel) + var modelBase = selectedItem.NodeModel ?? (ModelBase)selectedItem.GroupModel; if (modelBase != null) { - // Execute selection command + // Clear the selection in other DataGrids based on the sender + if (sender == LatestRunTable) + { + NotExecutedTable.SelectedItem = null; + PreviousRunTable.SelectedItem = null; + } + else if (sender == NotExecutedTable) + { + LatestRunTable.SelectedItem = null; + PreviousRunTable.SelectedItem = null; + } + else if (sender == PreviousRunTable) + { + LatestRunTable.SelectedItem = null; + NotExecutedTable.SelectedItem = null; + } + var command = new DynamoModel.SelectModelCommand(new[] { modelBase.GUID }, ModifierKeys.None); commandExecutive.ExecuteCommand(command, uniqueId, "TuneUp"); - // Focus on selected element viewModelCommandExecutive.FindByIdCommand(modelBase.GUID.ToString()); } } diff --git a/TuneUp/TuneUpWindowViewModel.cs b/TuneUp/TuneUpWindowViewModel.cs index 4f32150..6d4f72c 100644 --- a/TuneUp/TuneUpWindowViewModel.cs +++ b/TuneUp/TuneUpWindowViewModel.cs @@ -835,7 +835,7 @@ private ProfiledNodeViewModel CreateGroupTotalTimeNode(ProfiledNodeViewModel pro GroupGUID = profiledGroup.GroupGUID, GroupName = profiledGroup.GroupName, BackgroundBrush = profiledGroup.BackgroundBrush, - IsGroupExecutionTime = true, + //IsGroupExecutionTime = true, ShowGroupIndicator = true }; diff --git a/TuneUpTests/TuneUpTests.cs b/TuneUpTests/TuneUpTests.cs index fe4a485..2a0c7a0 100644 --- a/TuneUpTests/TuneUpTests.cs +++ b/TuneUpTests/TuneUpTests.cs @@ -53,7 +53,7 @@ public void TuneUpCreatesProfilingDataForEveryNodeInWorkspace() var profiledNodes = tuneUpVE.ViewModel.ProfiledNodesNotExecuted; foreach (var node in nodes) { - Assert.Contains(node.GUID, profiledNodes.Select(n => n.ModelBase.GUID).ToList()); + Assert.Contains(node.GUID, profiledNodes.Select(n => n.NodeModel.GUID).ToList()); } RunCurrentModel(); @@ -104,7 +104,7 @@ public void TuneUpMaintainsProfiledNodeState() DispatcherUtil.DoEvents(); foreach (var node in profiledNodes) { - if (node.ModelBase.GUID == modifiedNodeID) + if (node.NodeModel.GUID == modifiedNodeID) { Assert.AreEqual(ProfiledNodeState.ExecutedOnCurrentRun, node.State); } @@ -159,7 +159,7 @@ public void TuneUpDeterminesCorrectNodeExecutionOrder() DispatcherUtil.DoEvents(); foreach (var node in profiledNodes) { - var expected = executionOrderDict[node.ModelBase.GUID]; + var expected = executionOrderDict[node.NodeModel.GUID]; Assert.AreEqual(expected, node.ExecutionOrderNumber); } } From 7cd8655f2ae60b2e0bff7f059101298ff9624f63 Mon Sep 17 00:00:00 2001 From: Ivo Petrov Date: Tue, 24 Sep 2024 12:49:34 +0100 Subject: [PATCH 5/6] comments removed --- TuneUp/ProfiledNodeViewModel.cs | 3 +-- TuneUp/TuneUpWindow.xaml.cs | 2 +- TuneUp/TuneUpWindowViewModel.cs | 1 - TuneUpTests/TuneUpTests.cs | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/TuneUp/ProfiledNodeViewModel.cs b/TuneUp/ProfiledNodeViewModel.cs index 80fb921..a250c83 100644 --- a/TuneUp/ProfiledNodeViewModel.cs +++ b/TuneUp/ProfiledNodeViewModel.cs @@ -5,7 +5,6 @@ using System.Reflection; using System.Windows.Media; using Dynamo.Core; -using Dynamo.Graph; using Dynamo.Graph.Annotations; using Dynamo.Graph.Nodes; using Dynamo.Graph.Nodes.CustomNodes; @@ -115,7 +114,7 @@ private static string GetOriginalName(NodeModel node) /// public string Name { - get + get { // For virtual row, do not attempt to grab node or group name if it's already handled if (!this.IsGroupExecutionTime) diff --git a/TuneUp/TuneUpWindow.xaml.cs b/TuneUp/TuneUpWindow.xaml.cs index addcf05..14975c4 100644 --- a/TuneUp/TuneUpWindow.xaml.cs +++ b/TuneUp/TuneUpWindow.xaml.cs @@ -52,7 +52,7 @@ public TuneUpWindow(ViewLoadedParams vlp, string id) } private void NodeAnalysisTable_SelectionChanged(object sender, SelectionChangedEventArgs e) - { + { if (!isUserInitiatedSelection) return; var selectedItem = e.AddedItems.OfType().FirstOrDefault(); diff --git a/TuneUp/TuneUpWindowViewModel.cs b/TuneUp/TuneUpWindowViewModel.cs index 6d4f72c..3f754dd 100644 --- a/TuneUp/TuneUpWindowViewModel.cs +++ b/TuneUp/TuneUpWindowViewModel.cs @@ -835,7 +835,6 @@ private ProfiledNodeViewModel CreateGroupTotalTimeNode(ProfiledNodeViewModel pro GroupGUID = profiledGroup.GroupGUID, GroupName = profiledGroup.GroupName, BackgroundBrush = profiledGroup.BackgroundBrush, - //IsGroupExecutionTime = true, ShowGroupIndicator = true }; diff --git a/TuneUpTests/TuneUpTests.cs b/TuneUpTests/TuneUpTests.cs index 2a0c7a0..d2b6c92 100644 --- a/TuneUpTests/TuneUpTests.cs +++ b/TuneUpTests/TuneUpTests.cs @@ -94,7 +94,7 @@ public void TuneUpMaintainsProfiledNodeState() Assert.AreEqual(ProfiledNodeState.ExecutedOnCurrentRun, node.State); } - // Mark downstream node as modified so that it gets re-executed on the next graph run + // Mark downstream node as modified so that it gets reexecuted on the next graph run var modifiedNodeID = new Guid("1e49be233be846688122ac48d70ce961"); var homespace = Model.CurrentWorkspace as HomeWorkspaceModel; homespace.Nodes.Where(n => n.GUID == modifiedNodeID).First().MarkNodeAsModified(true); From 2c1a8896569bf072120412c87ed2bc375ee7e414 Mon Sep 17 00:00:00 2001 From: Ivo Petrov Date: Tue, 24 Sep 2024 15:45:48 +0100 Subject: [PATCH 6/6] Update ProfiledNodeViewModel.cs --- TuneUp/ProfiledNodeViewModel.cs | 35 --------------------------------- 1 file changed, 35 deletions(-) diff --git a/TuneUp/ProfiledNodeViewModel.cs b/TuneUp/ProfiledNodeViewModel.cs index c6679a3..e6f06d2 100644 --- a/TuneUp/ProfiledNodeViewModel.cs +++ b/TuneUp/ProfiledNodeViewModel.cs @@ -62,41 +62,6 @@ internal set /// public bool IsGroupExecutionTime => NodeModel == null && GroupModel == null; - /// - /// Getting the original name before graph author renamed the node - /// - private static string GetOriginalName(NodeModel node) - { - if (node == null) return string.Empty; - // For dummy node, return the current name so that does not appear to be renamed - if (node is DummyNode) - { - return node.Name; - } - if (node.IsCustomFunction) - { - // If the custom node is not loaded, return the current name so that does not appear to be renamed - if ((node as Function).State == ElementState.Error && (node as Function).Definition.IsProxy) - { - return node.Name; - } - // If the custom node is loaded, return original name as usual - var customNodeFunction = node as Function; - return customNodeFunction?.Definition.DisplayName; - } - - var function = node as DSFunctionBase; - if (function != null) - return function.Controller.Definition.DisplayName; - - var nodeType = node.GetType(); - var elNameAttrib = nodeType.GetCustomAttributes(false).FirstOrDefault(); - if (elNameAttrib != null) - return elNameAttrib.Name; - - return nodeType.FullName; - } - /// /// Prefix string of execution time. ///