From 38a0567ba1b04777aba3b9e3a71f79f1bf19189c Mon Sep 17 00:00:00 2001 From: Michael Kirschner Date: Fri, 1 Sep 2023 10:55:56 -0400 Subject: [PATCH 01/22] fix most memory leaks from opening and closing Dynamo Splash Screen (#14344) * fixing mem leaks in progress * fix test and remove todo --- .../Views/SplashScreen/SplashScreen.xaml.cs | 14 +++++++++-- .../GraphMetadataViewExtension.cs | 10 +++++--- .../LintingViewExtension.cs | 16 +++++++++--- .../NotificationsViewExtension.cs | 25 +++++++++++++------ .../PackageDetailsViewExtension.cs | 5 +++- .../PythonMigrationViewExtension.cs | 15 ++++++++--- .../WorkspaceDependencyViewExtension.cs | 2 +- 7 files changed, 63 insertions(+), 24 deletions(-) diff --git a/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs b/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs index dac29f4272f..59ffb6fd1ac 100644 --- a/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs +++ b/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs @@ -73,6 +73,10 @@ public DynamoView DynamoView set { dynamoView = value; + if(dynamoView == null) + { + return; + } viewModel = value.DataContext as DynamoViewModel; // When view model is closed, we need to close the splash screen if it is displayed. viewModel.RequestClose += SplashScreenRequestClose; @@ -484,8 +488,14 @@ internal void CloseWindow() // RequestUpdateLoadBarStatus event needs to be unsubscribed when the splash screen window is closed, to avoid populating the info on splash screen. else { - this.Close(); - viewModel?.Model.ShutDown(false); + Close(); + if (viewModel != null) + { + viewModel.RequestClose -= SplashScreenRequestClose; + } + + DynamoView?.Close(); + DynamoView = null; } } diff --git a/src/GraphMetadataViewExtension/GraphMetadataViewExtension.cs b/src/GraphMetadataViewExtension/GraphMetadataViewExtension.cs index 06e414fed7d..a7175099062 100644 --- a/src/GraphMetadataViewExtension/GraphMetadataViewExtension.cs +++ b/src/GraphMetadataViewExtension/GraphMetadataViewExtension.cs @@ -110,10 +110,12 @@ public override void Closed() protected virtual void Dispose(bool disposing) { - viewModel.Dispose(); - - this.graphMetadataMenuItem.Checked -= MenuItemCheckHandler; - this.graphMetadataMenuItem.Unchecked -= MenuItemUnCheckedHandler; + viewModel?.Dispose(); + if (graphMetadataMenuItem != null) + { + graphMetadataMenuItem.Checked -= MenuItemCheckHandler; + graphMetadataMenuItem.Unchecked -= MenuItemUnCheckedHandler; + } } public override void Dispose() diff --git a/src/LintingViewExtension/LintingViewExtension.cs b/src/LintingViewExtension/LintingViewExtension.cs index b2af77ba4ab..d1f2cd33960 100644 --- a/src/LintingViewExtension/LintingViewExtension.cs +++ b/src/LintingViewExtension/LintingViewExtension.cs @@ -71,10 +71,18 @@ public override void Shutdown() public override void Dispose() { - this.linterMenuItem.Checked -= MenuItemCheckHandler; - this.linterMenuItem.Unchecked -= MenuItemUnCheckedHandler; - if (linterManager != null) linterManager.PropertyChanged -= OnLinterManagerPropertyChange; - viewLoadedParamsReference.ViewExtensionOpenRequest -= OnViewExtensionOpenRequest; + if (linterMenuItem != null) + { + linterMenuItem.Checked -= MenuItemCheckHandler; + linterMenuItem.Unchecked -= MenuItemUnCheckedHandler; + } + if (linterManager != null){ + linterManager.PropertyChanged -= OnLinterManagerPropertyChange; + } + if (viewLoadedParamsReference != null) + { + viewLoadedParamsReference.ViewExtensionOpenRequest -= OnViewExtensionOpenRequest; + } } public override void Closed() diff --git a/src/Notifications/NotificationsViewExtension.cs b/src/Notifications/NotificationsViewExtension.cs index e146858a253..2840e073f23 100644 --- a/src/Notifications/NotificationsViewExtension.cs +++ b/src/Notifications/NotificationsViewExtension.cs @@ -27,7 +27,7 @@ public ObservableCollection Notifications get { return notifications; } private set { - if(notifications != value) + if (notifications != value) notifications = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Notifications))); } @@ -62,8 +62,11 @@ public void Dispose() { UnregisterEventHandlers(); //for some reason the menuItem was not being gc'd in tests without manually removing it - viewLoadedParams.dynamoMenu.Items.Remove(notificationsMenuItem.MenuItem); - BindingOperations.ClearAllBindings(notificationsMenuItem.CountLabel); + viewLoadedParams?.dynamoMenu.Items.Remove(notificationsMenuItem.MenuItem); + if (notificationsMenuItem != null) + { + BindingOperations.ClearAllBindings(notificationsMenuItem.CountLabel); + } notificationsMenuItem = null; disposed = true; } @@ -71,8 +74,14 @@ public void Dispose() private void UnregisterEventHandlers() { - viewLoadedParams.NotificationRecieved -= notificationHandler; - Notifications.CollectionChanged -= notificationsMenuItem.NotificationsChangeHandler; + if (viewLoadedParams != null) + { + viewLoadedParams.NotificationRecieved -= notificationHandler; + } + if (notificationsMenuItem != null) + { + Notifications.CollectionChanged -= notificationsMenuItem.NotificationsChangeHandler; + } } public void Loaded(ViewLoadedParams viewStartupParams) @@ -83,7 +92,7 @@ public void Loaded(ViewLoadedParams viewStartupParams) logger = viewModel.Model.Logger; Notifications = new ObservableCollection(); - + notificationHandler = (notificationMessage) => { Notifications.Add(notificationMessage); @@ -117,12 +126,12 @@ internal void AddNotifications() public void Shutdown() { - // Do nothing for now + // Do nothing for now } public void Startup(ViewStartupParams viewStartupParams) { - // Do nothing for now + // Do nothing for now } } } diff --git a/src/PackageDetailsViewExtension/PackageDetailsViewExtension.cs b/src/PackageDetailsViewExtension/PackageDetailsViewExtension.cs index a7f04029dd0..e803714a40a 100644 --- a/src/PackageDetailsViewExtension/PackageDetailsViewExtension.cs +++ b/src/PackageDetailsViewExtension/PackageDetailsViewExtension.cs @@ -143,7 +143,10 @@ private void DataContext_Closed(object sender, EventArgs e) public override void Dispose() { PackageDetailsViewModel?.Dispose(); - ViewLoadedParamsReference.ViewExtensionOpenRequestWithParameter -= OnViewExtensionOpenWithParameterRequest; + if (ViewLoadedParamsReference != null) + { + ViewLoadedParamsReference.ViewExtensionOpenRequestWithParameter -= OnViewExtensionOpenWithParameterRequest; + } } public override void Closed() diff --git a/src/PythonMigrationViewExtension/PythonMigrationViewExtension.cs b/src/PythonMigrationViewExtension/PythonMigrationViewExtension.cs index 84207e65a68..8a566f3c793 100644 --- a/src/PythonMigrationViewExtension/PythonMigrationViewExtension.cs +++ b/src/PythonMigrationViewExtension/PythonMigrationViewExtension.cs @@ -199,10 +199,17 @@ private void UnSubscribeWorkspaceEvents() private void UnsubscribeEvents() { - LoadedParams.CurrentWorkspaceChanged -= OnCurrentWorkspaceChanged; - DynamoViewModel.CurrentSpaceViewModel.Model.NodeAdded -= OnNodeAdded; - DynamoViewModel.Model.Logger.NotificationLogged -= OnNotificationLogged; - CurrentWorkspace.RequestPackageDependencies -= PythonDependencies.AddPythonPackageDependency; + if (LoadedParams != null) + { + LoadedParams.CurrentWorkspaceChanged -= OnCurrentWorkspaceChanged; + DynamoViewModel.CurrentSpaceViewModel.Model.NodeAdded -= OnNodeAdded; + DynamoViewModel.Model.Logger.NotificationLogged -= OnNotificationLogged; + } + + if (CurrentWorkspace != null) + { + CurrentWorkspace.RequestPackageDependencies -= PythonDependencies.AddPythonPackageDependency; + } UnSubscribeWorkspaceEvents(); } #endregion diff --git a/src/WorkspaceDependencyViewExtension/WorkspaceDependencyViewExtension.cs b/src/WorkspaceDependencyViewExtension/WorkspaceDependencyViewExtension.cs index 66725d0b820..817924a60e1 100644 --- a/src/WorkspaceDependencyViewExtension/WorkspaceDependencyViewExtension.cs +++ b/src/WorkspaceDependencyViewExtension/WorkspaceDependencyViewExtension.cs @@ -68,7 +68,7 @@ public override string UniqueId /// public override void Dispose() { - DependencyView.Dispose(); + DependencyView?.Dispose(); dataRows = null; localDefinitionDataRows = null; externalFilesDataRows = null; From 06e24bfcbf9f2ddb707afaca3bae18da1ff770b8 Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" Date: Fri, 1 Sep 2023 17:16:22 -0400 Subject: [PATCH 02/22] works and old graphs find method --- .../ViewModels/Preview/WatchViewModel.cs | 4 -- .../ProtoCore/DSASM/Mirror/ExecutionMirror.cs | 63 ++++++++++++++++--- .../ProtoCore/Lang/BuiltInFunctionEndPoint.cs | 6 +- src/Engine/ProtoCore/Lang/BuiltInMethods.cs | 16 ++++- src/Engine/ProtoCore/Reflection/MirrorData.cs | 21 +------ src/Engine/ProtoCore/Utils/StringUtils.cs | 24 ++++++- src/Libraries/CoreNodeModels/String.cs | 10 ++- 7 files changed, 105 insertions(+), 39 deletions(-) diff --git a/src/DynamoCoreWpf/ViewModels/Preview/WatchViewModel.cs b/src/DynamoCoreWpf/ViewModels/Preview/WatchViewModel.cs index 6b80c33b67b..74627d03326 100644 --- a/src/DynamoCoreWpf/ViewModels/Preview/WatchViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/Preview/WatchViewModel.cs @@ -271,10 +271,6 @@ private static string GetStringFromObject(object obj) case TypeCode.Object: return ObjectToLabelString(obj); default: - if (double.TryParse(obj.ToString(), out double d)) - { - return Convert.ToDouble(obj).ToString(ProtoCore.Mirror.MirrorData.PrecisionFormat, CultureInfo.InvariantCulture); - } return (string)obj; }; } diff --git a/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs b/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs index 2b6dd8f536b..3c87c58db09 100644 --- a/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs +++ b/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Text; using ProtoCore.Lang; @@ -44,15 +45,55 @@ public ExecutionMirror(ProtoCore.DSASM.Executive exec, ProtoCore.RuntimeCore cor MirrorTarget = exec; } + /// + /// + /// + /// + /// + /// + /// + /// + /// + public string GetStringValue2(StackValue val, Heap heap, int langblock, bool forPrint = false, + bool useNumericFormat = false) + { + return GetStringValueImplementation(val, heap, langblock, -1, -1, forPrint, useNumericFormat); + } + + /// + /// + /// + /// + /// + /// + /// + /// + [Obsolete] public string GetStringValue(StackValue val, Heap heap, int langblock, bool forPrint = false) { return GetStringValue(val, heap, langblock, -1, -1, forPrint); } + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + [Obsolete] public string GetStringValue(StackValue val, Heap heap, int langblock, int maxArraySize, int maxOutputDepth, bool forPrint = false) { - if (formatParams == null) - formatParams = new OutputFormatParameters(maxArraySize, maxOutputDepth); + return GetStringValueImplementation(val, heap, langblock, maxArraySize, maxOutputDepth, forPrint, false); + } + + private string GetStringValueImplementation(StackValue val, Heap heap, int langblock, int maxArraySize, + int maxOutputDepth, bool forPrint = false, bool useNumericFormat = false) + { + formatParams ??= new OutputFormatParameters(maxArraySize, maxOutputDepth); if (val.IsInteger) { @@ -61,6 +102,10 @@ public string GetStringValue(StackValue val, Heap heap, int langblock, int maxAr if (val.IsDouble) { + if (useNumericFormat) + { + return val.DoubleValue.ToString(ProtoCore.Mirror.MirrorData.PrecisionFormat); + } return val.DoubleValue.ToString("F6"); } @@ -77,7 +122,7 @@ public string GetStringValue(StackValue val, Heap heap, int langblock, int maxAr if (val.IsArray) { HashSet pointers = new HashSet { val.ArrayPointer }; - string arrTrace = GetArrayTrace(val, heap, langblock, pointers, forPrint); + string arrTrace = GetArrayTrace(val, heap, langblock, pointers, forPrint, useNumericFormat); if (forPrint) return "[" + arrTrace + "]"; @@ -212,7 +257,7 @@ public string GetClassTrace(StackValue val, Heap heap, int langblock, bool forPr } } - private string GetPointerTrace(StackValue ptr, Heap heap, int langblock, HashSet pointers, bool forPrint) + private string GetPointerTrace(StackValue ptr, Heap heap, int langblock, HashSet pointers, bool forPrint, bool useNumericFormat) { if (pointers.Contains(ptr.ArrayPointer)) { @@ -223,13 +268,13 @@ private string GetPointerTrace(StackValue ptr, Heap heap, int langblock, HashSet if (forPrint) { - return "[" + GetArrayTrace(ptr, heap, langblock, pointers, forPrint) + "]"; + return "[" + GetArrayTrace(ptr, heap, langblock, pointers, forPrint,useNumericFormat) + "]"; } - return "[ " + GetArrayTrace(ptr, heap, langblock, pointers, forPrint) + " ]"; + return "[ " + GetArrayTrace(ptr, heap, langblock, pointers, forPrint,useNumericFormat) + " ]"; } - private string GetArrayTrace(StackValue svArray, Heap heap, int langblock, HashSet pointers, bool forPrint) + private string GetArrayTrace(StackValue svArray, Heap heap, int langblock, HashSet pointers, bool forPrint, bool useNumericFormat) { if (!formatParams.ContinueOutputTrace()) return "..."; @@ -264,11 +309,11 @@ private string GetArrayTrace(StackValue svArray, Heap heap, int langblock, HashS StackValue sv = array.GetValueFromIndex(n, runtimeCore); if (sv.IsArray) { - arrayElements.Append(GetPointerTrace(sv, heap, langblock, pointers, forPrint)); + arrayElements.Append(GetPointerTrace(sv, heap, langblock, pointers, forPrint,useNumericFormat)); } else { - arrayElements.Append(GetStringValue(array.GetValueFromIndex(n, runtimeCore), heap, langblock, forPrint)); + arrayElements.Append(GetStringValue2(array.GetValueFromIndex(n, runtimeCore), heap, langblock, forPrint,useNumericFormat)); } // If we need to truncate this array (halfArraySize > 0), and we have diff --git a/src/Engine/ProtoCore/Lang/BuiltInFunctionEndPoint.cs b/src/Engine/ProtoCore/Lang/BuiltInFunctionEndPoint.cs index a706482a4e3..3c6b7c0d6f8 100644 --- a/src/Engine/ProtoCore/Lang/BuiltInFunctionEndPoint.cs +++ b/src/Engine/ProtoCore/Lang/BuiltInFunctionEndPoint.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -373,7 +373,9 @@ public override StackValue Execute(ProtoCore.Runtime.Context c, List case BuiltInMethods.MethodID.ToString: case BuiltInMethods.MethodID.ToStringFromObject: case BuiltInMethods.MethodID.ToStringFromArray: - ret = StringUtils.ConvertToString(formalParameters[0], runtimeCore, rmem); + { + ret = StringUtils.ConvertToString(formalParameters, runtimeCore, rmem); + } break; case BuiltInMethods.MethodID.ImportData: ret = ContextDataBuiltIns.ImportData(formalParameters[0], formalParameters[1], runtimeCore, interpreter, c); diff --git a/src/Engine/ProtoCore/Lang/BuiltInMethods.cs b/src/Engine/ProtoCore/Lang/BuiltInMethods.cs index 40ec432ae20..2bdbe3ef67b 100644 --- a/src/Engine/ProtoCore/Lang/BuiltInMethods.cs +++ b/src/Engine/ProtoCore/Lang/BuiltInMethods.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using ProtoCore.AST.AssociativeAST; using ProtoCore.DSASM; @@ -795,6 +795,17 @@ public BuiltInMethods(Core core) Parameters = new List> { new KeyValuePair("object", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var, 0)), + new KeyValuePair("useNumericFormat", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Bool, 0)), + }, + ID = BuiltInMethods.MethodID.ToStringFromObject, + }, + new BuiltInMethod + { + ReturnType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.String, 0), + Parameters = new List> + { + new KeyValuePair("object", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var, 0)), + new KeyValuePair("useNumericFormat", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Bool, 0)), }, ID = BuiltInMethods.MethodID.ToStringFromObject, }, @@ -806,6 +817,7 @@ public BuiltInMethods(Core core) Parameters = new [] { new KeyValuePair("list", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var)), + new KeyValuePair("useNumericFormat", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Bool, 0)), }.ToList(), ID = BuiltInMethods.MethodID.ToStringFromArray }, @@ -915,4 +927,4 @@ public BuiltInMethods(Core core) }; } } -} \ No newline at end of file +} diff --git a/src/Engine/ProtoCore/Reflection/MirrorData.cs b/src/Engine/ProtoCore/Reflection/MirrorData.cs index 4b3c05dea88..8363b142793 100644 --- a/src/Engine/ProtoCore/Reflection/MirrorData.cs +++ b/src/Engine/ProtoCore/Reflection/MirrorData.cs @@ -224,11 +224,11 @@ public string StringData { return "null"; } - else if (Data is bool) + if (Data is bool) { return Data.ToString().ToLower(); } - else if (Data is IFormattable) + if (Data is IFormattable) { // Object.ToString() by default will use the current // culture to do formatting. For example, Double.ToString() @@ -236,24 +236,9 @@ public string StringData // We should always use invariant culture format for formattable // object. - //TODO: uncomment this once https://jira.autodesk.com/browse/DYN-5101 is complete - //if (Data is double) - //{ - // return (Data as IFormattable).ToString(PrecisionFormat, CultureInfo.InvariantCulture); - //} - //else - //{ return (Data as IFormattable).ToString(null, CultureInfo.InvariantCulture); - //} - } - else - { - if (double.TryParse(Data.ToString(), out double d)) - { - return Convert.ToDouble(Data).ToString(PrecisionFormat, CultureInfo.InvariantCulture); - } - return Data.ToString(); } + return Data.ToString(); } } diff --git a/src/Engine/ProtoCore/Utils/StringUtils.cs b/src/Engine/ProtoCore/Utils/StringUtils.cs index d57870ff2da..df814f3fdda 100644 --- a/src/Engine/ProtoCore/Utils/StringUtils.cs +++ b/src/Engine/ProtoCore/Utils/StringUtils.cs @@ -1,5 +1,6 @@ using ProtoCore.DSASM; using System; +using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; @@ -27,14 +28,33 @@ public static string GetStringValue(StackValue sv, RuntimeCore runtimeCore) } public static StackValue ConvertToString(StackValue sv, RuntimeCore runtimeCore, ProtoCore.Runtime.RuntimeMemory rmem) + { + return ConvertToStringInternal(sv, runtimeCore,false); + } + internal static StackValue ConvertToString(IEnumerable args, RuntimeCore runtimeCore, ProtoCore.Runtime.RuntimeMemory rmem) + { + var useNumericFormat = false; + var sv = args.ElementAt(0); + if (args.Count() > 1) + { + useNumericFormat = args.ElementAt(1).BooleanValue; + } + return ConvertToStringInternal(sv, runtimeCore, useNumericFormat); + } + + private static StackValue ConvertToStringInternal(StackValue sv, RuntimeCore runtimeCore,bool useNumericFormat) { StackValue returnSV; //TODO: Change Execution mirror class to have static methods, so that an instance does not have to be created - ProtoCore.DSASM.Mirror.ExecutionMirror mirror = new DSASM.Mirror.ExecutionMirror(new ProtoCore.DSASM.Executive(runtimeCore), runtimeCore); - returnSV = ProtoCore.DSASM.StackValue.BuildString(mirror.GetStringValue(sv, runtimeCore.RuntimeMemory.Heap, 0, true), runtimeCore.RuntimeMemory.Heap); + ProtoCore.DSASM.Mirror.ExecutionMirror mirror = + new DSASM.Mirror.ExecutionMirror(new ProtoCore.DSASM.Executive(runtimeCore), runtimeCore); + returnSV = ProtoCore.DSASM.StackValue.BuildString( + mirror.GetStringValue2(sv, runtimeCore.RuntimeMemory.Heap, 0, true, useNumericFormat), runtimeCore.RuntimeMemory.Heap); return returnSV; } + + public static StackValue ConcatString(StackValue op1, StackValue op2, RuntimeCore runtimeCore) { var v1 = runtimeCore.RuntimeMemory.Heap.ToHeapObject(op1).Value; diff --git a/src/Libraries/CoreNodeModels/String.cs b/src/Libraries/CoreNodeModels/String.cs index f56750c761d..467ce6b0769 100644 --- a/src/Libraries/CoreNodeModels/String.cs +++ b/src/Libraries/CoreNodeModels/String.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Generic; +using System.Linq; using CoreNodeModels.Properties; using Dynamo.Graph.Nodes; using Newtonsoft.Json; @@ -8,7 +9,7 @@ namespace CoreNodeModels { /// /// Base class to represent a single input string node. It supports - /// partiallied applied function. + /// partially applied function. /// public class ToStringNodeBase : NodeModel { @@ -72,6 +73,10 @@ public class FromObject: ToStringNodeBase private FromObject(IEnumerable inPorts, IEnumerable outPorts) : base("__ToStringFromObject",inPorts, outPorts) { + if (inPorts.Count() < 2) + { + InPorts.Add(new PortModel(PortType.Input, this, new PortData("useNumericFormat", "should the numeric precision format be used when converting doubles", AstFactory.BuildBooleanNode(false)))); + } ArgumentLacing = LacingStrategy.Disabled; } @@ -79,6 +84,7 @@ public FromObject() : base("__ToStringFromObject") { ArgumentLacing = LacingStrategy.Disabled; InPorts.Add(new PortModel(PortType.Input, this, new PortData("object", Resources.FromObjectPortDataObjToolTip))); + InPorts.Add(new PortModel(PortType.Input, this, new PortData("useNumericFormat", "should the numeric precision format be used when converting doubles",AstFactory.BuildBooleanNode(false)))); OutPorts.Add(new PortModel(PortType.Output, this, new PortData("string", Resources.FromObjectPortDataResultToolTip))); RegisterAllPorts(); } From 7a1a34412b3ed1c62db87576083f042a44c2fcf3 Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" Date: Tue, 5 Sep 2023 15:46:33 -0400 Subject: [PATCH 03/22] try to get tests passing --- src/Libraries/CoreNodeModels/String.cs | 77 +++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/src/Libraries/CoreNodeModels/String.cs b/src/Libraries/CoreNodeModels/String.cs index 467ce6b0769..224315f2618 100644 --- a/src/Libraries/CoreNodeModels/String.cs +++ b/src/Libraries/CoreNodeModels/String.cs @@ -1,5 +1,7 @@ +using System; using System.Collections.Generic; using System.Linq; +using Autodesk.DesignScript.Runtime; using CoreNodeModels.Properties; using Dynamo.Graph.Nodes; using Newtonsoft.Json; @@ -30,6 +32,15 @@ public override IEnumerable BuildOutputAst(List(); @@ -49,7 +60,7 @@ public override IEnumerable BuildOutputAst(List BuildOutputAst(List inPorts, IEnumerable outPorts) : + base("__ToStringFromObject", inPorts, outPorts) + { + ArgumentLacing = LacingStrategy.Disabled; + } + + public StringFromObject() : base("__ToStringFromObject") + { + ArgumentLacing = LacingStrategy.Disabled; + InPorts.Add(new PortModel(PortType.Input, this, new PortData("object", Resources.FromObjectPortDataObjToolTip))); + InPorts.Add(new PortModel(PortType.Input, this, + new PortData("useNumericFormat", + "should the numeric precision format be used when converting doubles", + AstFactory.BuildBooleanNode(false)))); + OutPorts.Add(new PortModel(PortType.Output, this, new PortData("string", Resources.FromObjectPortDataResultToolTip))); + RegisterAllPorts(); + } + } + [NodeName("String from Object")] [NodeDescription("StringfromObjectDescription", typeof(Resources))] [NodeCategory("Core.String.Actions")] @@ -67,29 +106,49 @@ public override IEnumerable BuildOutputAst(List inPorts, IEnumerable outPorts) : base("__ToStringFromObject",inPorts, outPorts) { - if (inPorts.Count() < 2) - { - InPorts.Add(new PortModel(PortType.Input, this, new PortData("useNumericFormat", "should the numeric precision format be used when converting doubles", AstFactory.BuildBooleanNode(false)))); - } ArgumentLacing = LacingStrategy.Disabled; } - public FromObject() : base("__ToStringFromObject") { ArgumentLacing = LacingStrategy.Disabled; InPorts.Add(new PortModel(PortType.Input, this, new PortData("object", Resources.FromObjectPortDataObjToolTip))); - InPorts.Add(new PortModel(PortType.Input, this, new PortData("useNumericFormat", "should the numeric precision format be used when converting doubles",AstFactory.BuildBooleanNode(false)))); OutPorts.Add(new PortModel(PortType.Output, this, new PortData("string", Resources.FromObjectPortDataResultToolTip))); RegisterAllPorts(); } } + [NodeName("String from Array2")] + [NodeDescription("StringfromArrayDescription", typeof(Resources))] + [NodeCategory("Core.String.Actions")] + [NodeSearchTags("FromArraySearchTags", typeof(Resources))] + [OutPortTypes("string")] + [IsDesignScriptCompatible] + [AlsoKnownAs("DSCoreNodesUI.StringNodes.FromArray", "DSCoreNodesUI.FromArray")] + public class StringFromArray : ToStringNodeBase + { + [JsonConstructor] + private StringFromArray(IEnumerable inPorts, IEnumerable outPorts) : + base("__ToStringFromArray", inPorts, outPorts) + { + ArgumentLacing = LacingStrategy.Disabled; + } + + public StringFromArray() : base("__ToStringFromArray") + { + ArgumentLacing = LacingStrategy.Disabled; + InPorts.Add(new PortModel(PortType.Input, this, new PortData("array", Resources.FromArrayPortDataArrayToolTip))); + OutPorts.Add(new PortModel(PortType.Output, this, new PortData("string", Resources.FromArrayPortDataResultToolTip))); + RegisterAllPorts(); + } + } + [NodeName("String from Array")] [NodeDescription("StringfromArrayDescription", typeof(Resources))] [NodeCategory("Core.String.Actions")] @@ -110,6 +169,10 @@ public FromArray() : base("__ToStringFromArray") { ArgumentLacing = LacingStrategy.Disabled; InPorts.Add(new PortModel(PortType.Input, this, new PortData("array", Resources.FromArrayPortDataArrayToolTip))); + InPorts.Add(new PortModel(PortType.Input, this, + new PortData("useNumericFormat", + "should the numeric precision format be used when converting doubles", + AstFactory.BuildBooleanNode(false)))); OutPorts.Add(new PortModel(PortType.Output, this, new PortData("string", Resources.FromArrayPortDataResultToolTip))); RegisterAllPorts(); } From bd25c840617be1db76f77a6f87f4340b1cb9ab26 Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" Date: Tue, 5 Sep 2023 17:08:08 -0400 Subject: [PATCH 04/22] fix default values add two new tests --- src/Libraries/CoreNodeModels/String.cs | 20 +- test/DynamoCoreTests/Nodes/StringTests.cs | 55 + ...estNumberToString_normal_numericformat.dyn | 1066 +++++++++++++++++ ...stStringFromArrayPreview_numericformat.dyn | 525 ++++++++ 4 files changed, 1662 insertions(+), 4 deletions(-) create mode 100644 test/core/string/TestNumberToString_normal_numericformat.dyn create mode 100644 test/core/string/TestStringFromArrayPreview_numericformat.dyn diff --git a/src/Libraries/CoreNodeModels/String.cs b/src/Libraries/CoreNodeModels/String.cs index 224315f2618..e3c9d70e3a4 100644 --- a/src/Libraries/CoreNodeModels/String.cs +++ b/src/Libraries/CoreNodeModels/String.cs @@ -84,6 +84,12 @@ private StringFromObject(IEnumerable inPorts, IEnumerable base("__ToStringFromObject", inPorts, outPorts) { ArgumentLacing = LacingStrategy.Disabled; + //TODO looks like our nodemodel json constructor base implementation needs some work + //I see this in a few node model nodes that use default vals. + if (inPorts?.Count() > 1) + { + inPorts.ElementAt(1).DefaultValue = AstFactory.BuildBooleanNode(false); + } } public StringFromObject() : base("__ToStringFromObject") @@ -138,12 +144,22 @@ private StringFromArray(IEnumerable inPorts, IEnumerable o base("__ToStringFromArray", inPorts, outPorts) { ArgumentLacing = LacingStrategy.Disabled; + //TODO looks like our nodemodel json constructor base implementation needs some work + //I see this in a few node model nodes that use default vals. + if(inPorts?.Count()>1) + { + inPorts.ElementAt(1).DefaultValue = AstFactory.BuildBooleanNode(false); + } } public StringFromArray() : base("__ToStringFromArray") { ArgumentLacing = LacingStrategy.Disabled; InPorts.Add(new PortModel(PortType.Input, this, new PortData("array", Resources.FromArrayPortDataArrayToolTip))); + InPorts.Add(new PortModel(PortType.Input, this, + new PortData("useNumericFormat", + "should the numeric precision format be used when converting doubles", + AstFactory.BuildBooleanNode(false)))); OutPorts.Add(new PortModel(PortType.Output, this, new PortData("string", Resources.FromArrayPortDataResultToolTip))); RegisterAllPorts(); } @@ -169,10 +185,6 @@ public FromArray() : base("__ToStringFromArray") { ArgumentLacing = LacingStrategy.Disabled; InPorts.Add(new PortModel(PortType.Input, this, new PortData("array", Resources.FromArrayPortDataArrayToolTip))); - InPorts.Add(new PortModel(PortType.Input, this, - new PortData("useNumericFormat", - "should the numeric precision format be used when converting doubles", - AstFactory.BuildBooleanNode(false)))); OutPorts.Add(new PortModel(PortType.Output, this, new PortData("string", Resources.FromArrayPortDataResultToolTip))); RegisterAllPorts(); } diff --git a/test/DynamoCoreTests/Nodes/StringTests.cs b/test/DynamoCoreTests/Nodes/StringTests.cs index e4db34851b4..390271aeb4e 100644 --- a/test/DynamoCoreTests/Nodes/StringTests.cs +++ b/test/DynamoCoreTests/Nodes/StringTests.cs @@ -2,8 +2,10 @@ using System.IO; using System.Linq; using CoreNodeModels; +using Dynamo.Configuration; using Dynamo.Graph.Nodes; using Dynamo.Graph.Nodes.ZeroTouch; +using Dynamo.Models; using NUnit.Framework; namespace Dynamo.Tests @@ -439,6 +441,42 @@ public void TestStringToNumberNormalInput() AssertPreviewValue("898ee89d-a934-4b43-a051-da3459be329a", 1000); AssertPreviewValue("0afc0a8f-3d8a-4d7c-a2ec-d868cbb29b5f", 123456789); } + [Test] + public void TestStringToNumber2() + { + string testFilePath = Path.Combine(localDynamoStringTestFolder, "TestNumberToString_normal_numericFormat.dyn"); + CurrentDynamoModel.PreferenceSettings.NumberFormat = "f1"; + RunModel(testFilePath); + var watch1 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch1").FirstOrDefault().GUID.ToString(); + var watch2 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch2").FirstOrDefault().GUID.ToString(); + var watch3 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch3").FirstOrDefault().GUID.ToString(); + var watch4 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch4").FirstOrDefault().GUID.ToString(); + var watch5 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch5").FirstOrDefault().GUID.ToString(); + var watch6 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch6").FirstOrDefault().GUID.ToString(); + var watch7 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch7").FirstOrDefault().GUID.ToString(); + var useNumericFormat = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name == "Boolean").FirstOrDefault().GUID.ToString(); + + AssertPreviewValue(watch1, 123456789); + AssertPreviewValue(watch2, -123456789); + AssertPreviewValue(watch3, 3.46); + AssertPreviewValue(watch4, -3.46); + AssertPreviewValue(watch5, "3.460000"); + AssertPreviewValue(watch6, "-3.460000"); + AssertPreviewValue(watch7, "{key:0.000000000}"); + + //flip use numeric format on. + var uvc = new DynamoModel.UpdateModelValueCommand(useNumericFormat, "Value", "true"); + uvc.Execute(CurrentDynamoModel); + RunCurrentModel(); + + AssertPreviewValue(watch1, 123456789); + AssertPreviewValue(watch2, -123456789); + AssertPreviewValue(watch3, 3.5); + AssertPreviewValue(watch4, -3.5); + AssertPreviewValue(watch5, "3.5"); + AssertPreviewValue(watch6, "-3.5"); + AssertPreviewValue(watch7, "{key:0.000000000}"); + } #endregion @@ -867,6 +905,23 @@ public void TestStringFromArray() AssertPreviewValue("c27d9e05-45f7-4aac-8f53-a9e485e0f9c0", "[1,2,3]"); } + [Test] + public void TestStringFromArray2() + { + string testFilePath = Path.Combine(localDynamoStringTestFolder, "TestStringFromArrayPreview_numericformat.dyn"); + CurrentDynamoModel.PreferenceSettings.NumberFormat = "f1"; + RunModel(testFilePath); + var watch1 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name == "watch1").FirstOrDefault().GUID.ToString(); + var watch2 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name == "watch2").FirstOrDefault().GUID.ToString(); + var watch3 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name == "watch3").FirstOrDefault().GUID.ToString(); + var watch4 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name == "watch4").FirstOrDefault().GUID.ToString(); + + AssertPreviewValue(watch1, "[1.000000,1.666667,2.333333,3.000000]"); + AssertPreviewValue(watch2, "[1.000000,1.666667,2.333333,3.000000]"); + AssertPreviewValue(watch3, "[1.0,1.7,2.3,3.0]"); + AssertPreviewValue(watch4, "Function"); + + } #endregion } } diff --git a/test/core/string/TestNumberToString_normal_numericformat.dyn b/test/core/string/TestNumberToString_normal_numericformat.dyn new file mode 100644 index 00000000000..2acc9e92894 --- /dev/null +++ b/test/core/string/TestNumberToString_normal_numericformat.dyn @@ -0,0 +1,1066 @@ +{ + "Uuid": "3c9d0464-8643-5ffe-96e5-ab1769818209", + "IsCustomNode": false, + "Description": "", + "Name": "TestNumberToString_normal_numericformat", + "ElementResolver": { + "ResolutionMap": { + "DesignScript.Builtin.Dictionary": { + "Key": "DesignScript.Builtin.Dictionary", + "Value": "DesignScriptBuiltin.dll" + } + } + }, + "Inputs": [], + "Outputs": [], + "Nodes": [ + { + "ConcreteType": "CoreNodeModels.Input.DoubleInput, CoreNodeModels", + "NumberType": "Double", + "Id": "b6fbfc57f9a14609912d3824f806f5b8", + "NodeType": "NumberInputNode", + "Inputs": [], + "Outputs": [ + { + "Id": "a5a3fa26f7dc45a39a173e9928d26464", + "Name": "", + "Description": "Double", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Creates a number", + "InputValue": 123456789.0 + }, + { + "ConcreteType": "CoreNodeModels.Input.DoubleInput, CoreNodeModels", + "NumberType": "Double", + "Id": "9b74289ccd7242749bfbb6b56d2774bb", + "NodeType": "NumberInputNode", + "Inputs": [], + "Outputs": [ + { + "Id": "14d00072325d4ff4a55b64a6e794da3a", + "Name": "", + "Description": "Double", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Creates a number", + "InputValue": -123456789.0 + }, + { + "ConcreteType": "CoreNodeModels.Input.DoubleInput, CoreNodeModels", + "NumberType": "Double", + "Id": "075ecd65d9b44489b09041a309f0b794", + "NodeType": "NumberInputNode", + "Inputs": [], + "Outputs": [ + { + "Id": "3c7008e844154852a868d0360bd5531b", + "Name": "", + "Description": "Double", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Creates a number", + "InputValue": 3.46 + }, + { + "ConcreteType": "CoreNodeModels.Input.DoubleInput, CoreNodeModels", + "NumberType": "Double", + "Id": "1ce66222719e414eb4e393544239f4e5", + "NodeType": "NumberInputNode", + "Inputs": [], + "Outputs": [ + { + "Id": "e5afe6443c5e4dc58e7a1fb8b04bb7ad", + "Name": "", + "Description": "Double", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Creates a number", + "InputValue": -3.46 + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", + "Id": "39b81424e52f4e50a24e570690b00cc6", + "NodeType": "FunctionNode", + "Inputs": [ + { + "Id": "cfb7af8d58164cc1becd72025206192f", + "Name": "string", + "Description": "String to be converted\n\nstring", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "1f642ebeec5e444aa4ae36a1b832ee62", + "Name": "number", + "Description": "Integer or double-type number", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "FunctionSignature": "DSCore.String.ToNumber@string", + "Replication": "Auto", + "Description": "Converts a string to an integer or a double.\n\nString.ToNumber (string: string): var[]..[]" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", + "Id": "e0bb383beb004ef6b5764c3251913495", + "NodeType": "FunctionNode", + "Inputs": [ + { + "Id": "e77f5b74aa0c4531939d0dce7ca2ea44", + "Name": "string", + "Description": "String to be converted\n\nstring", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "d3a731bd764d4b95bb1bed61d967d0ea", + "Name": "number", + "Description": "Integer or double-type number", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "FunctionSignature": "DSCore.String.ToNumber@string", + "Replication": "Auto", + "Description": "Converts a string to an integer or a double.\n\nString.ToNumber (string: string): var[]..[]" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", + "Id": "53e38da5d6454ea39128d2ecffa44912", + "NodeType": "FunctionNode", + "Inputs": [ + { + "Id": "970af28845014907935d9c6842d83445", + "Name": "string", + "Description": "String to be converted\n\nstring", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "5fef519e74ce4fa496410a802424f7f2", + "Name": "number", + "Description": "Integer or double-type number", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "FunctionSignature": "DSCore.String.ToNumber@string", + "Replication": "Auto", + "Description": "Converts a string to an integer or a double.\n\nString.ToNumber (string: string): var[]..[]" + }, + { + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 87.5, + "WatchHeight": 38.0, + "Id": "d3fb3523609f456fbc233dcae1d48732", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "286987f4a6ab4f9580be045e75e6d3c2", + "Name": "", + "Description": "Node to show output from", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "8b2a3051fe5248e0a03e5d53fe56e0d9", + "Name": "", + "Description": "Node output", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Visualizes a node's output" + }, + { + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 95.0, + "WatchHeight": 38.0, + "Id": "ae77e756519e43ad9ac1861827601e22", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "422fe9f197a64b36b0f981800a6d3c21", + "Name": "", + "Description": "Node to show output from", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "8e370b548b2f4075b769fc4c5276af50", + "Name": "", + "Description": "Node output", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Visualizes a node's output" + }, + { + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 50.0, + "WatchHeight": 38.0, + "Id": "1ec6ed7b75a64bfcba77b81f82ed8f50", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "6597820795a745789041ff10a3c1c806", + "Name": "", + "Description": "Node to show output from", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "9774fa5969bc42d490126d1e6b18bc08", + "Name": "", + "Description": "Node output", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Visualizes a node's output" + }, + { + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 57.5, + "WatchHeight": 38.0, + "Id": "02c1b3e721dd4941ac15d8461b154a49", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "6f6a4d2e3e104ba1bbd86db24f642fc5", + "Name": "", + "Description": "Node to show output from", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "79a0315afa344636a1e50549dfe66f8f", + "Name": "", + "Description": "Node output", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Visualizes a node's output" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", + "Id": "f9912ec0f91c49ad82f22c32bad4bb11", + "NodeType": "FunctionNode", + "Inputs": [ + { + "Id": "c1a2092bb2fe4a039815751d49b06c3a", + "Name": "string", + "Description": "String to be converted\n\nstring", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "f2d95d3d01d8413392f48e02b950d2ef", + "Name": "number", + "Description": "Integer or double-type number", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "FunctionSignature": "DSCore.String.ToNumber@string", + "Replication": "Auto", + "Description": "Converts a string to an integer or a double.\n\nString.ToNumber (string: string): var[]..[]" + }, + { + "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "Id": "e4b36729f3b54ef6aca2086f6bb57f58", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "6aabc2cc4cf04250a13db4172d4639d9", + "Name": "object", + "Description": "Object to be serialized", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "26c6b353d485484da02ca6e995274416", + "Name": "useNumericFormat", + "Description": "should the numeric precision format be used when converting doubles", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "ca716b66554a49e8b61510a19fe4006f", + "Name": "string", + "Description": "String representation of the object", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Converts an object to a string representation" + }, + { + "ConcreteType": "CoreNodeModels.Input.BoolSelector, CoreNodeModels", + "Id": "ec91128266524e0a95cdc2e08a99a54b", + "NodeType": "BooleanInputNode", + "Inputs": [], + "Outputs": [ + { + "Id": "420eb88b471548849e114110915c33ef", + "Name": "", + "Description": "Boolean", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Enables selection between True and False", + "InputValue": false + }, + { + "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "Id": "98e44d23bf0d4c15a627025ac68aaf51", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "3d51288719f74206b97a80587f317744", + "Name": "object", + "Description": "Object to be serialized", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "a9314e3f699849dba1cad5e52e62b92b", + "Name": "useNumericFormat", + "Description": "should the numeric precision format be used when converting doubles", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "b637a7c648e04a7fb5696b4379d315bb", + "Name": "string", + "Description": "String representation of the object", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Converts an object to a string representation" + }, + { + "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "Id": "00fe75dd876646779ab8e90c72690e81", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "84d7ad92ce1e42638bbe8162e4e5268d", + "Name": "object", + "Description": "Object to be serialized", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "8cedd63d129745be808ec01669c68c47", + "Name": "useNumericFormat", + "Description": "should the numeric precision format be used when converting doubles", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "0515f8d3c1ea4a26a86a602c771d2ae0", + "Name": "string", + "Description": "String representation of the object", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Converts an object to a string representation" + }, + { + "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "Id": "b67de7cc81f54cd5b25e4df6d54827b6", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "b58d10476fa040f8be7025c53047c0f4", + "Name": "object", + "Description": "Object to be serialized", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "5d829f83fcb84feeaf8451cec711e6dd", + "Name": "useNumericFormat", + "Description": "should the numeric precision format be used when converting doubles", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "87abb8ade0dc4cea8a7bad5cda1a4279", + "Name": "string", + "Description": "String representation of the object", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Converts an object to a string representation" + }, + { + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 80.0, + "WatchHeight": 38.0, + "Id": "a7ec69bec9f546768d640012690aad24", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "57ee3c55175e450c90448f945205b088", + "Name": "", + "Description": "Node to show output from", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "e7c1095b3d434891b48dabcebbc9ac9a", + "Name": "", + "Description": "Node output", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Visualizes a node's output" + }, + { + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 87.5, + "WatchHeight": 38.0, + "Id": "b644da30668e4287bc92918735d5b0fc", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "259b4270cd3347a7911293d685affcee", + "Name": "", + "Description": "Node to show output from", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "718799e6939a421f9b481991f7015fdb", + "Name": "", + "Description": "Node output", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Visualizes a node's output" + }, + { + "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "Id": "680caae1a3ea4095803b2493571cce7a", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "cd3452ad72e94a659eed9d147cff3554", + "Name": "object", + "Description": "Object to be serialized", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "6cb36d659e7a4c9791373741e1a07ec3", + "Name": "useNumericFormat", + "Description": "should the numeric precision format be used when converting doubles (disabled)", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "b7a7cd5475b14f069395f5fd4f760779", + "Name": "string", + "Description": "String representation of the object", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Converts an object to a string representation" + }, + { + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 147.5, + "WatchHeight": 38.0, + "Id": "8b3258a0ac584bf5a3261ca66aaa788d", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "7d5f8dd21d0f493da25b9002273d5e80", + "Name": "", + "Description": "Node to show output from", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "832846b8799d4fe7ae1ac6c9901608cc", + "Name": "", + "Description": "Node output", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Visualizes a node's output" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", + "Id": "5e4770f0e3cc417f92776a8b8b83b533", + "NodeType": "CodeBlockNode", + "Inputs": [], + "Outputs": [ + { + "Id": "b45e2569af7049288b2b0aa558d3a7c3", + "Name": "", + "Description": "Value of expression at line 1", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Allows for DesignScript code to be authored directly", + "Code": "{\"key\":\"0.000000000\"};" + } + ], + "Connectors": [ + { + "Start": "a5a3fa26f7dc45a39a173e9928d26464", + "End": "6aabc2cc4cf04250a13db4172d4639d9", + "Id": "54407ca45ed2419984bec3427451c9e3", + "IsHidden": "False" + }, + { + "Start": "14d00072325d4ff4a55b64a6e794da3a", + "End": "3d51288719f74206b97a80587f317744", + "Id": "40c6ff636e6d4de0923dc11deaf51453", + "IsHidden": "False" + }, + { + "Start": "3c7008e844154852a868d0360bd5531b", + "End": "84d7ad92ce1e42638bbe8162e4e5268d", + "Id": "28b5d66ce83548bf84ccb945f0c04ba0", + "IsHidden": "False" + }, + { + "Start": "e5afe6443c5e4dc58e7a1fb8b04bb7ad", + "End": "b58d10476fa040f8be7025c53047c0f4", + "Id": "e4f244c0898a47c8b39af658f0b5c366", + "IsHidden": "False" + }, + { + "Start": "1f642ebeec5e444aa4ae36a1b832ee62", + "End": "286987f4a6ab4f9580be045e75e6d3c2", + "Id": "b4d4572034e94549aeb3a0370a761147", + "IsHidden": "False" + }, + { + "Start": "d3a731bd764d4b95bb1bed61d967d0ea", + "End": "422fe9f197a64b36b0f981800a6d3c21", + "Id": "1c436d3435d54f94a8f47af0bcfe899a", + "IsHidden": "False" + }, + { + "Start": "5fef519e74ce4fa496410a802424f7f2", + "End": "6597820795a745789041ff10a3c1c806", + "Id": "adff13861d524a1ead8f0673b665c9bf", + "IsHidden": "False" + }, + { + "Start": "f2d95d3d01d8413392f48e02b950d2ef", + "End": "6f6a4d2e3e104ba1bbd86db24f642fc5", + "Id": "2721b446100d40f69461416ceeded1f0", + "IsHidden": "False" + }, + { + "Start": "ca716b66554a49e8b61510a19fe4006f", + "End": "cfb7af8d58164cc1becd72025206192f", + "Id": "81ebdbb3ce4a4774a5d5fd8026ccb12d", + "IsHidden": "False" + }, + { + "Start": "420eb88b471548849e114110915c33ef", + "End": "26c6b353d485484da02ca6e995274416", + "Id": "f8328eb3095047a4a0ee11429df3071b", + "IsHidden": "False" + }, + { + "Start": "420eb88b471548849e114110915c33ef", + "End": "a9314e3f699849dba1cad5e52e62b92b", + "Id": "fb7f62cb04be4471ada2dbcf702d4812", + "IsHidden": "False" + }, + { + "Start": "420eb88b471548849e114110915c33ef", + "End": "5d829f83fcb84feeaf8451cec711e6dd", + "Id": "623087dab2c543248fa5cacc6e554a33", + "IsHidden": "False" + }, + { + "Start": "420eb88b471548849e114110915c33ef", + "End": "8cedd63d129745be808ec01669c68c47", + "Id": "17d53bd28f72401abd5f8ca3cbe88c05", + "IsHidden": "False" + }, + { + "Start": "420eb88b471548849e114110915c33ef", + "End": "6cb36d659e7a4c9791373741e1a07ec3", + "Id": "d80056bbc218425cae561bd6c4f4614b", + "IsHidden": "False" + }, + { + "Start": "b637a7c648e04a7fb5696b4379d315bb", + "End": "e77f5b74aa0c4531939d0dce7ca2ea44", + "Id": "0fcea9db5a7141ef8eaa6548787319bb", + "IsHidden": "False" + }, + { + "Start": "0515f8d3c1ea4a26a86a602c771d2ae0", + "End": "970af28845014907935d9c6842d83445", + "Id": "7cbbdd54dfc7435e9336e3bf551a16fd", + "IsHidden": "False" + }, + { + "Start": "0515f8d3c1ea4a26a86a602c771d2ae0", + "End": "57ee3c55175e450c90448f945205b088", + "Id": "94ed589962c04434ba4d7c9086aea0fd", + "IsHidden": "False" + }, + { + "Start": "87abb8ade0dc4cea8a7bad5cda1a4279", + "End": "c1a2092bb2fe4a039815751d49b06c3a", + "Id": "134511bfedaa41a1957595bf5d3a4ba4", + "IsHidden": "False" + }, + { + "Start": "87abb8ade0dc4cea8a7bad5cda1a4279", + "End": "259b4270cd3347a7911293d685affcee", + "Id": "00b57b7d3d954fec8472bc5715731996", + "IsHidden": "False" + }, + { + "Start": "b7a7cd5475b14f069395f5fd4f760779", + "End": "7d5f8dd21d0f493da25b9002273d5e80", + "Id": "d3bb795d153549bc8ea763615e7ee966", + "IsHidden": "False" + }, + { + "Start": "b45e2569af7049288b2b0aa558d3a7c3", + "End": "cd3452ad72e94a659eed9d147cff3554", + "Id": "633e8fbcb94943b8a0589c96fa302545", + "IsHidden": "False" + } + ], + "Dependencies": [], + "NodeLibraryDependencies": [], + "Thumbnail": "", + "GraphDocumentationURL": null, + "ExtensionWorkspaceData": [ + { + "ExtensionGuid": "28992e1d-abb9-417f-8b1b-05e053bee670", + "Name": "Properties", + "Version": "3.0", + "Data": {} + } + ], + "Author": "None provided", + "Linting": { + "activeLinter": "None", + "activeLinterId": "7b75fb44-43fd-4631-a878-29f4d5d8399a", + "warningCount": 0, + "errorCount": 0 + }, + "Bindings": [], + "View": { + "Dynamo": { + "ScaleFactor": 1.0, + "HasRunWithoutCrash": true, + "IsVisibleInDynamoLibrary": true, + "Version": "3.0.0.6086", + "RunType": "Automatic", + "RunPeriod": "1000" + }, + "Camera": { + "Name": "_Background Preview", + "EyeX": -17.0, + "EyeY": 24.0, + "EyeZ": 50.0, + "LookX": 12.0, + "LookY": -13.0, + "LookZ": -58.0, + "UpX": 0.0, + "UpY": 1.0, + "UpZ": 0.0 + }, + "ConnectorPins": [], + "NodeViews": [ + { + "Id": "b6fbfc57f9a14609912d3824f806f5b8", + "Name": "Number", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 185.44736955102093, + "Y": 162.1923398998582 + }, + { + "Id": "9b74289ccd7242749bfbb6b56d2774bb", + "Name": "Number", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 199.44736955102093, + "Y": 346.1923398998582 + }, + { + "Id": "075ecd65d9b44489b09041a309f0b794", + "Name": "Number", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 179.44736955102093, + "Y": 473.1923398998582 + }, + { + "Id": "1ce66222719e414eb4e393544239f4e5", + "Name": "Number", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 182.44736955102093, + "Y": 595.1923398998582 + }, + { + "Id": "39b81424e52f4e50a24e570690b00cc6", + "Name": "String.ToNumber", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 772.6480556547714, + "Y": 405.4495890984118 + }, + { + "Id": "e0bb383beb004ef6b5764c3251913495", + "Name": "String.ToNumber", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 769.3970019504612, + "Y": 578.4140297708927 + }, + { + "Id": "53e38da5d6454ea39128d2ecffa44912", + "Name": "String.ToNumber", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 762.3970019504612, + "Y": 720.4140297708927 + }, + { + "Id": "d3fb3523609f456fbc233dcae1d48732", + "Name": "Watch1", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 1097.3741239352394, + "Y": 379.02061936181263 + }, + { + "Id": "ae77e756519e43ad9ac1861827601e22", + "Name": "Watch2", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 1040.548580047816, + "Y": 522.0687226159225 + }, + { + "Id": "1ec6ed7b75a64bfcba77b81f82ed8f50", + "Name": "Watch3", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 1143.9844807892096, + "Y": 709.6687279307367 + }, + { + "Id": "02c1b3e721dd4941ac15d8461b154a49", + "Name": "Watch4", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 1163.8342015574185, + "Y": 879.4797576583975 + }, + { + "Id": "f9912ec0f91c49ad82f22c32bad4bb11", + "Name": "String.ToNumber", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 817.3970019504612, + "Y": 842.4140297708927 + }, + { + "Id": "e4b36729f3b54ef6aca2086f6bb57f58", + "Name": "String from Object2", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 498.119488531315, + "Y": 319.9280924046476 + }, + { + "Id": "ec91128266524e0a95cdc2e08a99a54b", + "Name": "Boolean", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 125.74288491428808, + "Y": 827.8484794260075 + }, + { + "Id": "98e44d23bf0d4c15a627025ac68aaf51", + "Name": "String from Object2", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 491.1576104786528, + "Y": 576.3860738606195 + }, + { + "Id": "00fe75dd876646779ab8e90c72690e81", + "Name": "String from Object2", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 464.9062143196976, + "Y": 763.5480428824812 + }, + { + "Id": "b67de7cc81f54cd5b25e4df6d54827b6", + "Name": "String from Object2", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 465.0855234398824, + "Y": 952.1374700195747 + }, + { + "Id": "a7ec69bec9f546768d640012690aad24", + "Name": "Watch5", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 1153.3485221133606, + "Y": 1042.6050120833188 + }, + { + "Id": "b644da30668e4287bc92918735d5b0fc", + "Name": "Watch6", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 1152.1739388504354, + "Y": 1199.0626990481478 + }, + { + "Id": "680caae1a3ea4095803b2493571cce7a", + "Name": "String from Object2", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 745.4698214608002, + "Y": 1307.2261855303775 + }, + { + "Id": "8b3258a0ac584bf5a3261ca66aaa788d", + "Name": "Watch7", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 1081.1123210884134, + "Y": 1365.22135433937 + }, + { + "Id": "5e4770f0e3cc417f92776a8b8b83b533", + "Name": "Code Block", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 131.0, + "Y": 1288.0 + } + ], + "Annotations": [], + "X": 286.99844688136534, + "Y": -122.44121147514721, + "Zoom": 0.9219474033079375 + } +} \ No newline at end of file diff --git a/test/core/string/TestStringFromArrayPreview_numericformat.dyn b/test/core/string/TestStringFromArrayPreview_numericformat.dyn new file mode 100644 index 00000000000..ea9289064e8 --- /dev/null +++ b/test/core/string/TestStringFromArrayPreview_numericformat.dyn @@ -0,0 +1,525 @@ +{ + "Uuid": "45732322-5b7c-4527-a7ff-2181708d3c04", + "IsCustomNode": false, + "Description": null, + "Name": "TestStringFromArrayPreview_numericformat", + "ElementResolver": { + "ResolutionMap": {} + }, + "Inputs": [], + "Outputs": [], + "Nodes": [ + { + "ConcreteType": "CoreNodeModels.FromArray, CoreNodeModels", + "Id": "c27d9e0545f74aac8f53a9e485e0f9c0", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "cc0b8d6aed9043de91272235e6ab2e50", + "Name": "arr", + "Description": "The array of object to be serialized", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "5144a5cf722c4b3da19b0708be143915", + "Name": "str", + "Description": "String representation of the array", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Converts an array to a string representation" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", + "Id": "012e48cbf12d4277a4ee77c990ec7a68", + "NodeType": "CodeBlockNode", + "Inputs": [], + "Outputs": [ + { + "Id": "480593de671c4fd0a5aba280e2065a8b", + "Name": "", + "Description": "Value of expression at line 1", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Allows for DesignScript code to be authored directly", + "Code": "1..3..#4;" + }, + { + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 297.5, + "WatchHeight": 38.0, + "Id": "4b6c7485022c4593ad15d280b5e99e8f", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "cc5f61300a9a40b79d66da1579621edc", + "Name": "", + "Description": "Node to evaluate.", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "f0db4981f30a468bbb33fb9d80199b95", + "Name": "", + "Description": "Watch contents.", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Visualizes a node's output" + }, + { + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 297.5, + "WatchHeight": 38.0, + "Id": "444b7edf23d6447393035c03543e7b2a", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "fd87ba31e76e429b9940e54a2fb7eb05", + "Name": "", + "Description": "Node to show output from", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "b0ae91f09bd740d2979bc716ee6166d1", + "Name": "", + "Description": "Node output", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Visualizes a node's output" + }, + { + "ConcreteType": "CoreNodeModels.StringFromArray, CoreNodeModels", + "Id": "3d39644d6ca04fbca80bc82f8d7a720f", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "4b4c706e2e1b4f8d8b9a9438a2e22601", + "Name": "array", + "Description": "The array of object to be serialized", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "0fd87c00c80d437bab0b70a0e7721e24", + "Name": "useNumericFormat", + "Description": "should the numeric precision format be used when converting doubles", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "0f4992f68f33412a9d5b00b17c0510e0", + "Name": "string", + "Description": "String representation of the array", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Converts an array to a string representation" + }, + { + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 177.5, + "WatchHeight": 38.0, + "Id": "70bf2a936f9141199a0d726dd765f694", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "63f0bd8bc6974ad38237d47f6663b770", + "Name": "", + "Description": "Node to show output from", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "ab4da6a6775e4716b7b44e2c550bc61a", + "Name": "", + "Description": "Node output", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Visualizes a node's output" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", + "Id": "b9352a46c1634e65a64bd8062e2a6102", + "NodeType": "CodeBlockNode", + "Inputs": [], + "Outputs": [ + { + "Id": "1dd82e4720ee46d59e8283b965f62f18", + "Name": "", + "Description": "Value of expression at line 1", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Allows for DesignScript code to be authored directly", + "Code": "true;" + }, + { + "ConcreteType": "CoreNodeModels.StringFromArray, CoreNodeModels", + "Id": "74f97ab047fa49eaaa8d77271ecb87e0", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "39204eddb5214b8784ef4d0a66415a2e", + "Name": "array", + "Description": "The array of object to be serialized", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "a93226abb9014f848ced0e08e546b696", + "Name": "useNumericFormat", + "Description": "should the numeric precision format be used when converting doubles (disabled)", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "9bb562665ed04284adf767976c17b2d2", + "Name": "string", + "Description": "String representation of the array", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Converts an array to a string representation" + }, + { + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 80.0, + "WatchHeight": 38.0, + "Id": "c198ae603bba4cc0a7ef17c3444f8156", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "b389674f395a4746b32d7583d975e743", + "Name": "", + "Description": "Node to show output from", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "929d7e76504340349292c5c432724364", + "Name": "", + "Description": "Node output", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Visualizes a node's output" + }, + { + "ConcreteType": "CoreNodeModels.StringFromArray, CoreNodeModels", + "Id": "c8b9fc78b61e413dae18a01a2d4114f6", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "23c77cf3ae1f447fb3c8fb9a70189e8b", + "Name": "array", + "Description": "The array of object to be serialized", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "20c3c708ee63436badb93364cc6efafb", + "Name": "useNumericFormat", + "Description": "should the numeric precision format be used when converting doubles", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "91e5262223774c2cac5056ab15ecdb2f", + "Name": "string", + "Description": "String representation of the array", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Converts an array to a string representation" + } + ], + "Connectors": [ + { + "Start": "5144a5cf722c4b3da19b0708be143915", + "End": "cc5f61300a9a40b79d66da1579621edc", + "Id": "0c116fd047bc42d4a799794b440ed7f5", + "IsHidden": "False" + }, + { + "Start": "480593de671c4fd0a5aba280e2065a8b", + "End": "cc0b8d6aed9043de91272235e6ab2e50", + "Id": "e1f6a2d64a1547dfb384016d5be86549", + "IsHidden": "False" + }, + { + "Start": "480593de671c4fd0a5aba280e2065a8b", + "End": "4b4c706e2e1b4f8d8b9a9438a2e22601", + "Id": "59019ff77b08442a9fe20ba7b7cde0a2", + "IsHidden": "False" + }, + { + "Start": "480593de671c4fd0a5aba280e2065a8b", + "End": "39204eddb5214b8784ef4d0a66415a2e", + "Id": "6d4611a0e5914a12be3763132720005c", + "IsHidden": "False" + }, + { + "Start": "480593de671c4fd0a5aba280e2065a8b", + "End": "23c77cf3ae1f447fb3c8fb9a70189e8b", + "Id": "ca769a9b5dc341fab5f75a947c403a85", + "IsHidden": "False" + }, + { + "Start": "0f4992f68f33412a9d5b00b17c0510e0", + "End": "63f0bd8bc6974ad38237d47f6663b770", + "Id": "2263ef87ef884e0db460d2aeb1366e93", + "IsHidden": "False" + }, + { + "Start": "1dd82e4720ee46d59e8283b965f62f18", + "End": "0fd87c00c80d437bab0b70a0e7721e24", + "Id": "4e38e9fa28e64afda034e474968c87dd", + "IsHidden": "False" + }, + { + "Start": "9bb562665ed04284adf767976c17b2d2", + "End": "b389674f395a4746b32d7583d975e743", + "Id": "319e84e8bc714198802388fda8aebca2", + "IsHidden": "False" + }, + { + "Start": "91e5262223774c2cac5056ab15ecdb2f", + "End": "fd87ba31e76e429b9940e54a2fb7eb05", + "Id": "324b94c5d10941deacb894c1844b1c3f", + "IsHidden": "False" + } + ], + "Dependencies": [], + "NodeLibraryDependencies": [], + "Thumbnail": "", + "GraphDocumentationURL": null, + "ExtensionWorkspaceData": [ + { + "ExtensionGuid": "28992e1d-abb9-417f-8b1b-05e053bee670", + "Name": "Properties", + "Version": "3.0", + "Data": {} + } + ], + "Author": "None provided", + "Linting": { + "activeLinter": "None", + "activeLinterId": "7b75fb44-43fd-4631-a878-29f4d5d8399a", + "warningCount": 0, + "errorCount": 0 + }, + "Bindings": [], + "View": { + "Dynamo": { + "ScaleFactor": 1.0, + "HasRunWithoutCrash": true, + "IsVisibleInDynamoLibrary": true, + "Version": "3.0.0.6086", + "RunType": "Automatic", + "RunPeriod": "1000" + }, + "Camera": { + "Name": "_Background Preview", + "EyeX": -17.0, + "EyeY": 24.0, + "EyeZ": 50.0, + "LookX": 12.0, + "LookY": -13.0, + "LookZ": -58.0, + "UpX": 0.0, + "UpY": 1.0, + "UpZ": 0.0 + }, + "ConnectorPins": [], + "NodeViews": [ + { + "Id": "c27d9e0545f74aac8f53a9e485e0f9c0", + "Name": "String from Array", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 329.83615590858915, + "Y": 264.44863102728914 + }, + { + "Id": "012e48cbf12d4277a4ee77c990ec7a68", + "Name": "Code Block", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": -3.2945482059884625, + "Y": 259.7251911171454 + }, + { + "Id": "4b6c7485022c4593ad15d280b5e99e8f", + "Name": "watch1", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 592.9054158830944, + "Y": 269.110183681075 + }, + { + "Id": "444b7edf23d6447393035c03543e7b2a", + "Name": "watch2", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 575.2274753658695, + "Y": 417.24281878340815 + }, + { + "Id": "3d39644d6ca04fbca80bc82f8d7a720f", + "Name": "String from Array2", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 335.93713118238543, + "Y": 655.3098310110507 + }, + { + "Id": "70bf2a936f9141199a0d726dd765f694", + "Name": "watch3", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 603.67829140981, + "Y": 656.8284604865979 + }, + { + "Id": "b9352a46c1634e65a64bd8062e2a6102", + "Name": "Code Block", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": -20.865738536736444, + "Y": 685.6950649607055 + }, + { + "Id": "74f97ab047fa49eaaa8d77271ecb87e0", + "Name": "String from Array2", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 327.4697339717835, + "Y": 881.6712841125085 + }, + { + "Id": "c198ae603bba4cc0a7ef17c3444f8156", + "Name": "watch4", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 611.7258533738277, + "Y": 902.9404607916114 + }, + { + "Id": "c8b9fc78b61e413dae18a01a2d4114f6", + "Name": "String from Array2", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 294.9112494242495, + "Y": 418.9155459518879 + } + ], + "Annotations": [], + "X": 113.92114508888528, + "Y": -217.60130393629618, + "Zoom": 0.8428937702322691 + } +} \ No newline at end of file From 17de8d66ecc88231f544a5042b173016ca3c9f7f Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" Date: Tue, 5 Sep 2023 17:48:07 -0400 Subject: [PATCH 05/22] remove duplicated builtin function endpoint --- src/Engine/ProtoCore/Lang/BuiltInMethods.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Engine/ProtoCore/Lang/BuiltInMethods.cs b/src/Engine/ProtoCore/Lang/BuiltInMethods.cs index 2bdbe3ef67b..9bdba625539 100644 --- a/src/Engine/ProtoCore/Lang/BuiltInMethods.cs +++ b/src/Engine/ProtoCore/Lang/BuiltInMethods.cs @@ -799,16 +799,6 @@ public BuiltInMethods(Core core) }, ID = BuiltInMethods.MethodID.ToStringFromObject, }, - new BuiltInMethod - { - ReturnType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.String, 0), - Parameters = new List> - { - new KeyValuePair("object", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var, 0)), - new KeyValuePair("useNumericFormat", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Bool, 0)), - }, - ID = BuiltInMethods.MethodID.ToStringFromObject, - }, new BuiltInMethod { From 602622957e22688725c726ba484d7a33ecf2ed78 Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" Date: Tue, 5 Sep 2023 19:39:49 -0400 Subject: [PATCH 06/22] save status --- src/Engine/ProtoCore/Utils/StringUtils.cs | 1 + src/Libraries/CoreNodeModels/String.cs | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Engine/ProtoCore/Utils/StringUtils.cs b/src/Engine/ProtoCore/Utils/StringUtils.cs index df814f3fdda..ea11f812113 100644 --- a/src/Engine/ProtoCore/Utils/StringUtils.cs +++ b/src/Engine/ProtoCore/Utils/StringUtils.cs @@ -42,6 +42,7 @@ internal static StackValue ConvertToString(IEnumerable args, Runtime return ConvertToStringInternal(sv, runtimeCore, useNumericFormat); } + //TODO support std format strings? private static StackValue ConvertToStringInternal(StackValue sv, RuntimeCore runtimeCore,bool useNumericFormat) { StackValue returnSV; diff --git a/src/Libraries/CoreNodeModels/String.cs b/src/Libraries/CoreNodeModels/String.cs index e3c9d70e3a4..85d0b2b4fdc 100644 --- a/src/Libraries/CoreNodeModels/String.cs +++ b/src/Libraries/CoreNodeModels/String.cs @@ -71,7 +71,7 @@ public override IEnumerable BuildOutputAst(List Date: Wed, 30 Oct 2024 17:36:28 -0400 Subject: [PATCH 07/22] builtin method tests are passing --- .../ProtoCore/DSASM/Mirror/ExecutionMirror.cs | 57 ++++++++++++------- .../ProtoCore/Lang/BuiltInFunctionEndPoint.cs | 8 ++- src/Engine/ProtoCore/Lang/BuiltInMethods.cs | 40 ++++++++++++- src/Engine/ProtoCore/Utils/StringUtils.cs | 32 ++++++++--- src/Libraries/CoreNodeModels/String.cs | 43 ++++++-------- 5 files changed, 123 insertions(+), 57 deletions(-) diff --git a/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs b/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs index 3c87c58db09..82b342944be 100644 --- a/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs +++ b/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs @@ -52,12 +52,11 @@ public ExecutionMirror(ProtoCore.DSASM.Executive exec, ProtoCore.RuntimeCore cor /// /// /// - /// + /// /// - public string GetStringValue2(StackValue val, Heap heap, int langblock, bool forPrint = false, - bool useNumericFormat = false) + public string GetStringValueUsingFormat(StackValue val,string formatSpecifier, Heap heap, int langblock, bool forPrint = false) { - return GetStringValueImplementation(val, heap, langblock, -1, -1, forPrint, useNumericFormat); + return GetStringValueImplementation(val,formatSpecifier, heap, langblock, -1, -1, forPrint); } /// @@ -69,6 +68,9 @@ public string GetStringValue2(StackValue val, Heap heap, int langblock, bool for /// /// [Obsolete] + //TODO this is used all over the place internally + //so it's good to keep it and likely make it internal + //until we want to change formatting everywhere we process strings. public string GetStringValue(StackValue val, Heap heap, int langblock, bool forPrint = false) { return GetStringValue(val, heap, langblock, -1, -1, forPrint); @@ -87,26 +89,41 @@ public string GetStringValue(StackValue val, Heap heap, int langblock, bool forP [Obsolete] public string GetStringValue(StackValue val, Heap heap, int langblock, int maxArraySize, int maxOutputDepth, bool forPrint = false) { - return GetStringValueImplementation(val, heap, langblock, maxArraySize, maxOutputDepth, forPrint, false); + //use F6 to match the existing behavior. + return GetStringValueImplementation(val, StringUtils.LEGACYFORMATTING, heap, langblock, maxArraySize, maxOutputDepth, forPrint); } - private string GetStringValueImplementation(StackValue val, Heap heap, int langblock, int maxArraySize, - int maxOutputDepth, bool forPrint = false, bool useNumericFormat = false) + private string GetStringValueImplementation(StackValue val, string formatSpecifier, Heap heap, int langblock, int maxArraySize, + int maxOutputDepth, bool forPrint = false) { + var legacyBehavior = formatSpecifier == StringUtils.LEGACYFORMATTING; formatParams ??= new OutputFormatParameters(maxArraySize, maxOutputDepth); + //if format is the dynamo format specifier then use prefs format. + if (formatSpecifier == StringUtils.DynamoPreferencesNumberFormat) + { + formatSpecifier = ProtoCore.Mirror.MirrorData.PrecisionFormat; + } + if (val.IsInteger) { - return val.IntegerValue.ToString(); + //in legacy mode we don't format ints. + if (legacyBehavior) + { + return val.IntegerValue.ToString(); + } + + return val.IntegerValue.ToString(formatSpecifier); } if (val.IsDouble) { - if (useNumericFormat) + //we always use f6 for doubles in legacy mode. + if (legacyBehavior) { - return val.DoubleValue.ToString(ProtoCore.Mirror.MirrorData.PrecisionFormat); - } - return val.DoubleValue.ToString("F6"); + return val.DoubleValue.ToString("F6"); + } + return val.DoubleValue.ToString(formatSpecifier); } if (val.IsNull) @@ -122,7 +139,7 @@ private string GetStringValueImplementation(StackValue val, Heap heap, int langb if (val.IsArray) { HashSet pointers = new HashSet { val.ArrayPointer }; - string arrTrace = GetArrayTrace(val, heap, langblock, pointers, forPrint, useNumericFormat); + string arrTrace = GetArrayTrace(val, formatSpecifier, heap, langblock, pointers, forPrint); if (forPrint) return "[" + arrTrace + "]"; @@ -170,6 +187,8 @@ private string GetStringValueImplementation(StackValue val, Heap heap, int langb return "null"; // "Value not yet supported for tracing"; } + //TODO - use format specifier when converting to string + //obsolete this method and introduce another. public string GetClassTrace(StackValue val, Heap heap, int langblock, bool forPrint) { if (!formatParams.ContinueOutputTrace()) @@ -257,7 +276,7 @@ public string GetClassTrace(StackValue val, Heap heap, int langblock, bool forPr } } - private string GetPointerTrace(StackValue ptr, Heap heap, int langblock, HashSet pointers, bool forPrint, bool useNumericFormat) + private string GetPointerTrace(StackValue ptr, string formatSpecifier, Heap heap, int langblock, HashSet pointers, bool forPrint) { if (pointers.Contains(ptr.ArrayPointer)) { @@ -268,13 +287,13 @@ private string GetPointerTrace(StackValue ptr, Heap heap, int langblock, HashSet if (forPrint) { - return "[" + GetArrayTrace(ptr, heap, langblock, pointers, forPrint,useNumericFormat) + "]"; + return "[" + GetArrayTrace(ptr,formatSpecifier, heap, langblock, pointers, forPrint) + "]"; } - return "[ " + GetArrayTrace(ptr, heap, langblock, pointers, forPrint,useNumericFormat) + " ]"; + return "[ " + GetArrayTrace(ptr,formatSpecifier, heap, langblock, pointers, forPrint) + " ]"; } - private string GetArrayTrace(StackValue svArray, Heap heap, int langblock, HashSet pointers, bool forPrint, bool useNumericFormat) + private string GetArrayTrace(StackValue svArray, string formatSpecifier, Heap heap, int langblock, HashSet pointers, bool forPrint) { if (!formatParams.ContinueOutputTrace()) return "..."; @@ -309,11 +328,11 @@ private string GetArrayTrace(StackValue svArray, Heap heap, int langblock, HashS StackValue sv = array.GetValueFromIndex(n, runtimeCore); if (sv.IsArray) { - arrayElements.Append(GetPointerTrace(sv, heap, langblock, pointers, forPrint,useNumericFormat)); + arrayElements.Append(GetPointerTrace(sv,formatSpecifier, heap, langblock, pointers, forPrint)); } else { - arrayElements.Append(GetStringValue2(array.GetValueFromIndex(n, runtimeCore), heap, langblock, forPrint,useNumericFormat)); + arrayElements.Append(GetStringValueUsingFormat(array.GetValueFromIndex(n, runtimeCore),formatSpecifier, heap, langblock, forPrint)); } // If we need to truncate this array (halfArraySize > 0), and we have diff --git a/src/Engine/ProtoCore/Lang/BuiltInFunctionEndPoint.cs b/src/Engine/ProtoCore/Lang/BuiltInFunctionEndPoint.cs index 3c6b7c0d6f8..cd3139260f5 100644 --- a/src/Engine/ProtoCore/Lang/BuiltInFunctionEndPoint.cs +++ b/src/Engine/ProtoCore/Lang/BuiltInFunctionEndPoint.cs @@ -373,10 +373,16 @@ public override StackValue Execute(ProtoCore.Runtime.Context c, List case BuiltInMethods.MethodID.ToString: case BuiltInMethods.MethodID.ToStringFromObject: case BuiltInMethods.MethodID.ToStringFromArray: + { + ret = StringUtils.ConvertToString(formalParameters[0], runtimeCore, rmem); + break; + } + case BuiltInMethods.MethodID.ToStringFromObjectAndFormat: + case BuiltInMethods.MethodID.ToStringFromArrayAndFormat: { ret = StringUtils.ConvertToString(formalParameters, runtimeCore, rmem); + break; } - break; case BuiltInMethods.MethodID.ImportData: ret = ContextDataBuiltIns.ImportData(formalParameters[0], formalParameters[1], runtimeCore, interpreter, c); break; diff --git a/src/Engine/ProtoCore/Lang/BuiltInMethods.cs b/src/Engine/ProtoCore/Lang/BuiltInMethods.cs index 9bdba625539..8db5af10fd9 100644 --- a/src/Engine/ProtoCore/Lang/BuiltInMethods.cs +++ b/src/Engine/ProtoCore/Lang/BuiltInMethods.cs @@ -69,8 +69,13 @@ public enum MethodID NodeAstFailed, GC, ConditionalIf, + ToStringFromObjectAndFormat, + ToStringFromArrayAndFormat, } + //this array gets accessed using the MethodID enum + //so its order is important... could be a dictionary or attributes on the enums + //to avoid confusion, easy to mess this up. private static string[] methodNames = new string[] { "AllFalse", // kAllFalse @@ -130,6 +135,8 @@ public enum MethodID Constants.kNodeAstFailed, // kNodeAstFailed "__GC", // kGC Constants.kIfConditionalMethodName, + "__ToStringFromObjectAndFormat", // kToStringFromObjectAndFormat + "__ToStringFromArrayAndFormat", // kToStringFromArrayAndFormat }; public static string GetMethodName(MethodID id) @@ -795,9 +802,9 @@ public BuiltInMethods(Core core) Parameters = new List> { new KeyValuePair("object", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var, 0)), - new KeyValuePair("useNumericFormat", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Bool, 0)), }, ID = BuiltInMethods.MethodID.ToStringFromObject, + MethodAttributes = new MethodAttributes(true, false, @"This method is obsolete, please use 'ToStringFromObjectAndFormat' "), }, new BuiltInMethod @@ -807,9 +814,36 @@ public BuiltInMethods(Core core) Parameters = new [] { new KeyValuePair("list", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var)), - new KeyValuePair("useNumericFormat", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Bool, 0)), }.ToList(), - ID = BuiltInMethods.MethodID.ToStringFromArray + ID = BuiltInMethods.MethodID.ToStringFromArray, + MethodAttributes = new MethodAttributes(true, false, @"This method is obsolete, please use 'ToStringFromArrayAndFormat' "), + }, + + new BuiltInMethod + { + ReturnType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.String, 0), + Parameters = new List> + { + new KeyValuePair("object", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var, 0)), + new KeyValuePair("formatSpecifier", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.String, 0)), + //TODO (MJK) + //if we wanted to support default args for builtins we would need to support these names being parsed as binary expressions instead + //of just identifiers as is done today. We would need to add a new Parameters entry because all of this is public :( + //or we could invoke the parser directly on these strings as is done for custom node symbols... + }, + ID = BuiltInMethods.MethodID.ToStringFromObjectAndFormat, + }, + + new BuiltInMethod + { + ReturnType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.String, 0), + + Parameters = new [] + { + new KeyValuePair("list", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var)), + new KeyValuePair("formatSpecifier", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.String, 0)), + }.ToList(), + ID = BuiltInMethods.MethodID.ToStringFromArrayAndFormat }, new BuiltInMethod diff --git a/src/Engine/ProtoCore/Utils/StringUtils.cs b/src/Engine/ProtoCore/Utils/StringUtils.cs index ea11f812113..a169ea42319 100644 --- a/src/Engine/ProtoCore/Utils/StringUtils.cs +++ b/src/Engine/ProtoCore/Utils/StringUtils.cs @@ -8,6 +8,9 @@ namespace ProtoCore.Utils { public static class StringUtils { + internal const string DynamoPreferencesNumberFormat = nameof(DynamoPreferencesNumberFormat); + internal const string LEGACYFORMATTING = nameof(LEGACYFORMATTING); + public static int CompareString(StackValue s1, StackValue s2, RuntimeCore runtimeCore) { if (!s1.IsString || !s2.IsString) @@ -27,30 +30,41 @@ public static string GetStringValue(StackValue sv, RuntimeCore runtimeCore) return mirror.GetStringValue(sv, runtimeCore.RuntimeMemory.Heap, 0, true); } + //used by legacy ToString methods without format specifier. public static StackValue ConvertToString(StackValue sv, RuntimeCore runtimeCore, ProtoCore.Runtime.RuntimeMemory rmem) { - return ConvertToStringInternal(sv, runtimeCore,false); + //maintain old behavior of existing string conversion nodes by passing null for formatSpecifier. + return ConvertToStringInternal(sv, runtimeCore, null); } + //used by new ToString methods with format specifier. internal static StackValue ConvertToString(IEnumerable args, RuntimeCore runtimeCore, ProtoCore.Runtime.RuntimeMemory rmem) { - var useNumericFormat = false; + //TODO dislike this as a default... + var formatSpecifier = DynamoPreferencesNumberFormat; var sv = args.ElementAt(0); if (args.Count() > 1) - { - useNumericFormat = args.ElementAt(1).BooleanValue; + { //TODO performance concern? + formatSpecifier = GetStringValue(args.ElementAt(1),runtimeCore); } - return ConvertToStringInternal(sv, runtimeCore, useNumericFormat); + return ConvertToStringInternal(sv, runtimeCore, formatSpecifier); } - //TODO support std format strings? - private static StackValue ConvertToStringInternal(StackValue sv, RuntimeCore runtimeCore,bool useNumericFormat) + private static StackValue ConvertToStringInternal(StackValue sv, RuntimeCore runtimeCore, string formatSpecifier) { StackValue returnSV; //TODO: Change Execution mirror class to have static methods, so that an instance does not have to be created ProtoCore.DSASM.Mirror.ExecutionMirror mirror = new DSASM.Mirror.ExecutionMirror(new ProtoCore.DSASM.Executive(runtimeCore), runtimeCore); - returnSV = ProtoCore.DSASM.StackValue.BuildString( - mirror.GetStringValue2(sv, runtimeCore.RuntimeMemory.Heap, 0, true, useNumericFormat), runtimeCore.RuntimeMemory.Heap); + if (formatSpecifier == null) + { + returnSV = ProtoCore.DSASM.StackValue.BuildString( + mirror.GetStringValue(sv, runtimeCore.RuntimeMemory.Heap, 0, true), runtimeCore.RuntimeMemory.Heap); + } + else + { + returnSV = ProtoCore.DSASM.StackValue.BuildString( + mirror.GetStringValueUsingFormat(sv, formatSpecifier, runtimeCore.RuntimeMemory.Heap, 0, true), runtimeCore.RuntimeMemory.Heap); + } return returnSV; } diff --git a/src/Libraries/CoreNodeModels/String.cs b/src/Libraries/CoreNodeModels/String.cs index 85d0b2b4fdc..4cf0729afd0 100644 --- a/src/Libraries/CoreNodeModels/String.cs +++ b/src/Libraries/CoreNodeModels/String.cs @@ -32,15 +32,6 @@ public override IEnumerable BuildOutputAst(List(); @@ -71,7 +62,7 @@ public override IEnumerable BuildOutputAst(List inPorts, IEnumerable outPorts) : - base("__ToStringFromObject", inPorts, outPorts) + base("__ToStringFromObjectAndFormat", inPorts, outPorts) { ArgumentLacing = LacingStrategy.Disabled; //TODO looks like our nodemodel json constructor base implementation needs some work //I see this in a few node model nodes that use default vals. if (inPorts?.Count() > 1) - { - inPorts.ElementAt(1).DefaultValue = AstFactory.BuildBooleanNode(false); + { + inPorts.ElementAt(1).DefaultValue = AstFactory.BuildStringNode("F6"); } } - public StringFromObject() : base("__ToStringFromObject") + public StringFromObject() : base("__ToStringFromObjectAndFormat") { ArgumentLacing = LacingStrategy.Disabled; InPorts.Add(new PortModel(PortType.Input, this, new PortData("object", Resources.FromObjectPortDataObjToolTip))); InPorts.Add(new PortModel(PortType.Input, this, - new PortData("useNumericFormat", - "should the numeric precision format be used when converting doubles", - AstFactory.BuildBooleanNode(false)))); + new PortData("formatSpecifier", + //TODO add more info here in localized form. + "format specifier for numeric values", + AstFactory.BuildStringNode("F6")))); OutPorts.Add(new PortModel(PortType.Output, this, new PortData("string", Resources.FromObjectPortDataResultToolTip))); RegisterAllPorts(); } @@ -131,7 +123,7 @@ public FromObject() : base("__ToStringFromObject") } } - [NodeName("String from Array2")] + [NodeName("String from Array And Format")] [NodeDescription("StringfromArrayDescription", typeof(Resources))] [NodeCategory("Core.String.Actions")] [NodeSearchTags("FromArraySearchTags", typeof(Resources))] @@ -142,25 +134,26 @@ public class StringFromArray : ToStringNodeBase { [JsonConstructor] private StringFromArray(IEnumerable inPorts, IEnumerable outPorts) : - base("__ToStringFromArray", inPorts, outPorts) + base("__ToStringFromArrayAndFormat", inPorts, outPorts) { ArgumentLacing = LacingStrategy.Disabled; //TODO looks like our nodemodel json constructor base implementation needs some work //I see this in a few node model nodes that use default vals. - if(inPorts?.Count()>1) + if (inPorts?.Count() > 1) { - inPorts.ElementAt(1).DefaultValue = AstFactory.BuildBooleanNode(false); + inPorts.ElementAt(1).DefaultValue = AstFactory.BuildStringNode("F6"); } } - public StringFromArray() : base("__ToStringFromArray") + public StringFromArray() : base("__ToStringFromArrayAndFormat") { ArgumentLacing = LacingStrategy.Disabled; InPorts.Add(new PortModel(PortType.Input, this, new PortData("array", Resources.FromArrayPortDataArrayToolTip))); InPorts.Add(new PortModel(PortType.Input, this, - new PortData("useNumericFormat", - "should the numeric precision format be used when converting doubles", - AstFactory.BuildBooleanNode(false)))); + new PortData("formatSpecifier", + //TODO add more info here in localized form. + "format specifier for numeric values", + AstFactory.BuildStringNode("F6")))); OutPorts.Add(new PortModel(PortType.Output, this, new PortData("string", Resources.FromArrayPortDataResultToolTip))); RegisterAllPorts(); } From dcc9d417803dcf262bffc602bcd0e2eaf680c39e Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" <508936+mjkkirschner@users.noreply.github.com> Date: Thu, 31 Oct 2024 18:17:28 -0400 Subject: [PATCH 08/22] update graph tests --- .../ProtoCore/DSASM/Mirror/ExecutionMirror.cs | 8 +- .../ProtoCore/Lang/BuiltInFunctionEndPoint.cs | 12 +- src/Engine/ProtoCore/Utils/StringUtils.cs | 22 +- test/DynamoCoreTests/Nodes/StringTests.cs | 44 +- ...estNumberToString_normal_numericformat.dyn | 731 ++++++++++-------- ...stStringFromArrayPreview_numericformat.dyn | 245 +++--- 6 files changed, 608 insertions(+), 454 deletions(-) diff --git a/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs b/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs index 82b342944be..b4297e44b9e 100644 --- a/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs +++ b/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs @@ -21,7 +21,7 @@ public SymbolNotFoundException(string symbolName) public string SymbolName { get; private set; } } - //Status: Draft, experiment + //Status: Draft, experiment :) /// /// Provides reflective capabilities over the execution of a DSASM Executable @@ -112,8 +112,13 @@ private string GetStringValueImplementation(StackValue val, string formatSpecifi { return val.IntegerValue.ToString(); } + //TODO I am not sure if it's best to just return null or some message here + //or if we should catch the error higher up where we can log a runtime warning. + //currently we are doing the latter. + //return val.IntegerValue.SafeToStringWithFormat(formatSpecifier); return val.IntegerValue.ToString(formatSpecifier); + } if (val.IsDouble) @@ -123,6 +128,7 @@ private string GetStringValueImplementation(StackValue val, string formatSpecifi { return val.DoubleValue.ToString("F6"); } + //return val.DoubleValue.SafeToStringWithFormat(formatSpecifier); return val.DoubleValue.ToString(formatSpecifier); } diff --git a/src/Engine/ProtoCore/Lang/BuiltInFunctionEndPoint.cs b/src/Engine/ProtoCore/Lang/BuiltInFunctionEndPoint.cs index cd3139260f5..896800a6fc5 100644 --- a/src/Engine/ProtoCore/Lang/BuiltInFunctionEndPoint.cs +++ b/src/Engine/ProtoCore/Lang/BuiltInFunctionEndPoint.cs @@ -380,7 +380,17 @@ public override StackValue Execute(ProtoCore.Runtime.Context c, List case BuiltInMethods.MethodID.ToStringFromObjectAndFormat: case BuiltInMethods.MethodID.ToStringFromArrayAndFormat: { - ret = StringUtils.ConvertToString(formalParameters, runtimeCore, rmem); + try + { + ret = StringUtils.ConvertToString(formalParameters, runtimeCore, rmem); + } + catch(System.FormatException fe) + { + runtimeCore.RuntimeStatus.LogWarning(WarningID.InvalidArguments, fe.Message); + //TODO reuse this string instead of allocating a new one each time? + //the message could be different... + ret = StackValue.BuildString(fe.Message,runtimeCore.Heap); + } break; } case BuiltInMethods.MethodID.ImportData: diff --git a/src/Engine/ProtoCore/Utils/StringUtils.cs b/src/Engine/ProtoCore/Utils/StringUtils.cs index a169ea42319..80bd5a4dbb1 100644 --- a/src/Engine/ProtoCore/Utils/StringUtils.cs +++ b/src/Engine/ProtoCore/Utils/StringUtils.cs @@ -24,6 +24,26 @@ public static int CompareString(StackValue s1, StackValue s2, RuntimeCore runtim return string.Compare(str1, str2); } + /// + /// Wraps ToString(format) in a try catch. Will return empty string if format is not valid for the target type. + /// + /// + /// + /// + /// Will return empty string if format is not valid for the target type. + internal static string SafeToStringWithFormat(this T target, string Format) + where T : IFormattable + { + try + { + return target.ToString(Format, null); + } + catch + { + return string.Empty; + } + } + public static string GetStringValue(StackValue sv, RuntimeCore runtimeCore) { ProtoCore.DSASM.Mirror.ExecutionMirror mirror = new DSASM.Mirror.ExecutionMirror(new ProtoCore.DSASM.Executive(runtimeCore), runtimeCore); @@ -57,7 +77,7 @@ private static StackValue ConvertToStringInternal(StackValue sv, RuntimeCore run new DSASM.Mirror.ExecutionMirror(new ProtoCore.DSASM.Executive(runtimeCore), runtimeCore); if (formatSpecifier == null) { - returnSV = ProtoCore.DSASM.StackValue.BuildString( + returnSV = ProtoCore.DSASM.StackValue.BuildString( mirror.GetStringValue(sv, runtimeCore.RuntimeMemory.Heap, 0, true), runtimeCore.RuntimeMemory.Heap); } else diff --git a/test/DynamoCoreTests/Nodes/StringTests.cs b/test/DynamoCoreTests/Nodes/StringTests.cs index 390271aeb4e..520a4aa53b9 100644 --- a/test/DynamoCoreTests/Nodes/StringTests.cs +++ b/test/DynamoCoreTests/Nodes/StringTests.cs @@ -447,6 +447,7 @@ public void TestStringToNumber2() string testFilePath = Path.Combine(localDynamoStringTestFolder, "TestNumberToString_normal_numericFormat.dyn"); CurrentDynamoModel.PreferenceSettings.NumberFormat = "f1"; RunModel(testFilePath); + var watch0 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch0").FirstOrDefault().GUID.ToString(); var watch1 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch1").FirstOrDefault().GUID.ToString(); var watch2 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch2").FirstOrDefault().GUID.ToString(); var watch3 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch3").FirstOrDefault().GUID.ToString(); @@ -454,28 +455,15 @@ public void TestStringToNumber2() var watch5 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch5").FirstOrDefault().GUID.ToString(); var watch6 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch6").FirstOrDefault().GUID.ToString(); var watch7 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch7").FirstOrDefault().GUID.ToString(); - var useNumericFormat = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name == "Boolean").FirstOrDefault().GUID.ToString(); - - AssertPreviewValue(watch1, 123456789); - AssertPreviewValue(watch2, -123456789); - AssertPreviewValue(watch3, 3.46); - AssertPreviewValue(watch4, -3.46); - AssertPreviewValue(watch5, "3.460000"); - AssertPreviewValue(watch6, "-3.460000"); - AssertPreviewValue(watch7, "{key:0.000000000}"); - - //flip use numeric format on. - var uvc = new DynamoModel.UpdateModelValueCommand(useNumericFormat, "Value", "true"); - uvc.Execute(CurrentDynamoModel); - RunCurrentModel(); - - AssertPreviewValue(watch1, 123456789); - AssertPreviewValue(watch2, -123456789); - AssertPreviewValue(watch3, 3.5); - AssertPreviewValue(watch4, -3.5); - AssertPreviewValue(watch5, "3.5"); - AssertPreviewValue(watch6, "-3.5"); - AssertPreviewValue(watch7, "{key:0.000000000}"); + + AssertPreviewValue(watch0, "123456789.000000"); + AssertPreviewValue(watch1, new string[]{ "123456789.000", "123456789.0", "123456789", "111010110111100110100010101" }); + AssertPreviewValue(watch2, new string[] { "-123456789.000", "-123456789.0", "-123456789", "1111111111111111111111111111111111111000101001000011001011101011" }); + AssertPreviewValue(watch3, new string[] { "3.460", "3.5", "3.46", "Format specifier was invalid." }); + AssertPreviewValue(watch4, new string[] { "-3.460", "-3.5", "-3.46", "Format specifier was invalid." }); + AssertPreviewValue(watch5, new string[] { "5.000", "5.0", "5", "101" }); + AssertPreviewValue(watch6, new string[] { "{key:0.000000000}", "{key:0.000000000}", "{key:0.000000000}", "{key:0.000000000}" }); + AssertPreviewValue(watch7, new string[] { "{key:5}", "{key:5}", "{key:5}", "{key:5}" }); } #endregion @@ -909,16 +897,16 @@ public void TestStringFromArray() public void TestStringFromArray2() { string testFilePath = Path.Combine(localDynamoStringTestFolder, "TestStringFromArrayPreview_numericformat.dyn"); - CurrentDynamoModel.PreferenceSettings.NumberFormat = "f1"; + //CurrentDynamoModel.PreferenceSettings.NumberFormat = "f1"; RunModel(testFilePath); - var watch1 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name == "watch1").FirstOrDefault().GUID.ToString(); - var watch2 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name == "watch2").FirstOrDefault().GUID.ToString(); - var watch3 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name == "watch3").FirstOrDefault().GUID.ToString(); - var watch4 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name == "watch4").FirstOrDefault().GUID.ToString(); + var watch1 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch1").FirstOrDefault().GUID.ToString(); + var watch2 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch2").FirstOrDefault().GUID.ToString(); + var watch3 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch3").FirstOrDefault().GUID.ToString(); + var watch4 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch4").FirstOrDefault().GUID.ToString(); AssertPreviewValue(watch1, "[1.000000,1.666667,2.333333,3.000000]"); AssertPreviewValue(watch2, "[1.000000,1.666667,2.333333,3.000000]"); - AssertPreviewValue(watch3, "[1.0,1.7,2.3,3.0]"); + AssertPreviewValue(watch3, new string[] { "[1.0,1.7,2.3,3.0]", "[1,1.6666666666666667,2.3333333333333335,3]", "Format specifier was invalid." }); AssertPreviewValue(watch4, "Function"); } diff --git a/test/core/string/TestNumberToString_normal_numericformat.dyn b/test/core/string/TestNumberToString_normal_numericformat.dyn index 2acc9e92894..dfb93e2d04a 100644 --- a/test/core/string/TestNumberToString_normal_numericformat.dyn +++ b/test/core/string/TestNumberToString_normal_numericformat.dyn @@ -99,14 +99,16 @@ "InputValue": -3.46 }, { - "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", - "Id": "39b81424e52f4e50a24e570690b00cc6", - "NodeType": "FunctionNode", + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 200.0, + "WatchHeight": 200.0, + "Id": "d3fb3523609f456fbc233dcae1d48732", + "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "cfb7af8d58164cc1becd72025206192f", - "Name": "string", - "Description": "String to be converted\n\nstring", + "Id": "286987f4a6ab4f9580be045e75e6d3c2", + "Name": "", + "Description": "Node to show output from", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, @@ -115,28 +117,29 @@ ], "Outputs": [ { - "Id": "1f642ebeec5e444aa4ae36a1b832ee62", - "Name": "number", - "Description": "Integer or double-type number", + "Id": "8b2a3051fe5248e0a03e5d53fe56e0d9", + "Name": "", + "Description": "Node output", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, "KeepListStructure": false } ], - "FunctionSignature": "DSCore.String.ToNumber@string", - "Replication": "Auto", - "Description": "Converts a string to an integer or a double.\n\nString.ToNumber (string: string): var[]..[]" + "Replication": "Disabled", + "Description": "Visualizes a node's output" }, { - "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", - "Id": "e0bb383beb004ef6b5764c3251913495", - "NodeType": "FunctionNode", + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 200.0, + "WatchHeight": 200.0, + "Id": "ae77e756519e43ad9ac1861827601e22", + "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "e77f5b74aa0c4531939d0dce7ca2ea44", - "Name": "string", - "Description": "String to be converted\n\nstring", + "Id": "422fe9f197a64b36b0f981800a6d3c21", + "Name": "", + "Description": "Node to show output from", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, @@ -145,28 +148,29 @@ ], "Outputs": [ { - "Id": "d3a731bd764d4b95bb1bed61d967d0ea", - "Name": "number", - "Description": "Integer or double-type number", + "Id": "8e370b548b2f4075b769fc4c5276af50", + "Name": "", + "Description": "Node output", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, "KeepListStructure": false } ], - "FunctionSignature": "DSCore.String.ToNumber@string", - "Replication": "Auto", - "Description": "Converts a string to an integer or a double.\n\nString.ToNumber (string: string): var[]..[]" + "Replication": "Disabled", + "Description": "Visualizes a node's output" }, { - "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", - "Id": "53e38da5d6454ea39128d2ecffa44912", - "NodeType": "FunctionNode", + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 200.0, + "WatchHeight": 200.0, + "Id": "1ec6ed7b75a64bfcba77b81f82ed8f50", + "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "970af28845014907935d9c6842d83445", - "Name": "string", - "Description": "String to be converted\n\nstring", + "Id": "6597820795a745789041ff10a3c1c806", + "Name": "", + "Description": "Node to show output from", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, @@ -175,30 +179,36 @@ ], "Outputs": [ { - "Id": "5fef519e74ce4fa496410a802424f7f2", - "Name": "number", - "Description": "Integer or double-type number", + "Id": "9774fa5969bc42d490126d1e6b18bc08", + "Name": "", + "Description": "Node output", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, "KeepListStructure": false } ], - "FunctionSignature": "DSCore.String.ToNumber@string", - "Replication": "Auto", - "Description": "Converts a string to an integer or a double.\n\nString.ToNumber (string: string): var[]..[]" + "Replication": "Disabled", + "Description": "Visualizes a node's output" }, { - "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", - "WatchWidth": 87.5, - "WatchHeight": 38.0, - "Id": "d3fb3523609f456fbc233dcae1d48732", + "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "Id": "680caae1a3ea4095803b2493571cce7a", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "286987f4a6ab4f9580be045e75e6d3c2", - "Name": "", - "Description": "Node to show output from", + "Id": "cd3452ad72e94a659eed9d147cff3554", + "Name": "object", + "Description": "Object to be serialized", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "6cb36d659e7a4c9791373741e1a07ec3", + "Name": "useNumericFormat", + "Description": "should the numeric precision format be used when converting doubles (disabled)", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, @@ -207,9 +217,9 @@ ], "Outputs": [ { - "Id": "8b2a3051fe5248e0a03e5d53fe56e0d9", - "Name": "", - "Description": "Node output", + "Id": "b7a7cd5475b14f069395f5fd4f760779", + "Name": "string", + "Description": "String representation of the object", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, @@ -217,17 +227,17 @@ } ], "Replication": "Disabled", - "Description": "Visualizes a node's output" + "Description": "Converts an object to a string representation" }, { "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", - "WatchWidth": 95.0, - "WatchHeight": 38.0, - "Id": "ae77e756519e43ad9ac1861827601e22", + "WatchWidth": 200.0, + "WatchHeight": 200.0, + "Id": "8b3258a0ac584bf5a3261ca66aaa788d", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "422fe9f197a64b36b0f981800a6d3c21", + "Id": "7d5f8dd21d0f493da25b9002273d5e80", "Name": "", "Description": "Node to show output from", "UsingDefaultValue": false, @@ -238,7 +248,7 @@ ], "Outputs": [ { - "Id": "8e370b548b2f4075b769fc4c5276af50", + "Id": "832846b8799d4fe7ae1ac6c9901608cc", "Name": "", "Description": "Node output", "UsingDefaultValue": false, @@ -251,27 +261,35 @@ "Description": "Visualizes a node's output" }, { - "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", - "WatchWidth": 50.0, - "WatchHeight": 38.0, - "Id": "1ec6ed7b75a64bfcba77b81f82ed8f50", - "NodeType": "ExtensionNode", - "Inputs": [ + "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", + "Id": "5e4770f0e3cc417f92776a8b8b83b533", + "NodeType": "CodeBlockNode", + "Inputs": [], + "Outputs": [ { - "Id": "6597820795a745789041ff10a3c1c806", + "Id": "b45e2569af7049288b2b0aa558d3a7c3", "Name": "", - "Description": "Node to show output from", + "Description": "Value of expression at line 1", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, "KeepListStructure": false } ], + "Replication": "Disabled", + "Description": "Allows for DesignScript code to be authored directly", + "Code": "{\"key\":\"0.000000000\"};" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", + "Id": "662c8c937a80459b971650b87a6fcfe4", + "NodeType": "CodeBlockNode", + "Inputs": [], "Outputs": [ { - "Id": "9774fa5969bc42d490126d1e6b18bc08", + "Id": "bd621135843f4e32b20128fabb5b349a", "Name": "", - "Description": "Node output", + "Description": "Value of expression at line 1", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, @@ -279,17 +297,18 @@ } ], "Replication": "Disabled", - "Description": "Visualizes a node's output" + "Description": "Allows for DesignScript code to be authored directly", + "Code": "[\"F3\",\"F1\",\"G\",\"B\"];" }, { "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", - "WatchWidth": 57.5, - "WatchHeight": 38.0, + "WatchWidth": 200.0, + "WatchHeight": 200.0, "Id": "02c1b3e721dd4941ac15d8461b154a49", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "6f6a4d2e3e104ba1bbd86db24f642fc5", + "Id": "2c2b4228f1f74ccc9ab191dbcddeef2b", "Name": "", "Description": "Node to show output from", "UsingDefaultValue": false, @@ -300,7 +319,7 @@ ], "Outputs": [ { - "Id": "79a0315afa344636a1e50549dfe66f8f", + "Id": "3f9edc8af38c40468c872736e7b6dbdb", "Name": "", "Description": "Node output", "UsingDefaultValue": false, @@ -313,42 +332,32 @@ "Description": "Visualizes a node's output" }, { - "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", - "Id": "f9912ec0f91c49ad82f22c32bad4bb11", - "NodeType": "FunctionNode", - "Inputs": [ - { - "Id": "c1a2092bb2fe4a039815751d49b06c3a", - "Name": "string", - "Description": "String to be converted\n\nstring", - "UsingDefaultValue": false, - "Level": 2, - "UseLevels": false, - "KeepListStructure": false - } - ], + "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", + "Id": "a74956c410ce41b7b43a195dad0e38b5", + "NodeType": "CodeBlockNode", + "Inputs": [], "Outputs": [ { - "Id": "f2d95d3d01d8413392f48e02b950d2ef", - "Name": "number", - "Description": "Integer or double-type number", + "Id": "eb1a9bcb42934dc293bfc3350ef15a85", + "Name": "", + "Description": "Value of expression at line 1", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, "KeepListStructure": false } ], - "FunctionSignature": "DSCore.String.ToNumber@string", - "Replication": "Auto", - "Description": "Converts a string to an integer or a double.\n\nString.ToNumber (string: string): var[]..[]" + "Replication": "Disabled", + "Description": "Allows for DesignScript code to be authored directly", + "Code": "{\"key\":\"5\"};" }, { "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", - "Id": "e4b36729f3b54ef6aca2086f6bb57f58", + "Id": "f776aa328bd043ee8ec082b49bffe6a3", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "6aabc2cc4cf04250a13db4172d4639d9", + "Id": "a9b1075f9ebb426694446b6f97308228", "Name": "object", "Description": "Object to be serialized", "UsingDefaultValue": false, @@ -357,10 +366,10 @@ "KeepListStructure": false }, { - "Id": "26c6b353d485484da02ca6e995274416", - "Name": "useNumericFormat", - "Description": "should the numeric precision format be used when converting doubles", - "UsingDefaultValue": true, + "Id": "28bc476b868f4346aacf08498000189f", + "Name": "formatSpecifier", + "Description": "format specifier for numeric values (disabled)", + "UsingDefaultValue": false, "Level": 2, "UseLevels": false, "KeepListStructure": false @@ -368,7 +377,7 @@ ], "Outputs": [ { - "Id": "ca716b66554a49e8b61510a19fe4006f", + "Id": "484311c3e33d48208bfe70baabef9539", "Name": "string", "Description": "String representation of the object", "UsingDefaultValue": false, @@ -381,15 +390,46 @@ "Description": "Converts an object to a string representation" }, { - "ConcreteType": "CoreNodeModels.Input.BoolSelector, CoreNodeModels", - "Id": "ec91128266524e0a95cdc2e08a99a54b", - "NodeType": "BooleanInputNode", + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 200.0, + "WatchHeight": 200.0, + "Id": "3a45200d74bb4ece97d0fb1bb03ec973", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "8c04eff2dbe74b5bbe8e23b5878a1372", + "Name": "", + "Description": "Node to show output from", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "77435ecf09c347308760f8d9514afd03", + "Name": "", + "Description": "Node output", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Visualizes a node's output" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", + "Id": "e0e5a49813ef41e8bbdcaf9844fd6e86", + "NodeType": "CodeBlockNode", "Inputs": [], "Outputs": [ { - "Id": "420eb88b471548849e114110915c33ef", + "Id": "2a84b826723841daabe17488bfa4696e", "Name": "", - "Description": "Boolean", + "Description": "Value of expression at line 1", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, @@ -397,16 +437,16 @@ } ], "Replication": "Disabled", - "Description": "Enables selection between True and False", - "InputValue": false + "Description": "Allows for DesignScript code to be authored directly", + "Code": "5;" }, { "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", - "Id": "98e44d23bf0d4c15a627025ac68aaf51", + "Id": "9c16d38e96ad477dab6fad80d8f28f74", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "3d51288719f74206b97a80587f317744", + "Id": "065e1a4cbceb41f09a22e802fc9dbe15", "Name": "object", "Description": "Object to be serialized", "UsingDefaultValue": false, @@ -415,9 +455,9 @@ "KeepListStructure": false }, { - "Id": "a9314e3f699849dba1cad5e52e62b92b", - "Name": "useNumericFormat", - "Description": "should the numeric precision format be used when converting doubles", + "Id": "47f0dc27e828410cbaa454c9c29d0e67", + "Name": "formatSpecifier", + "Description": "format specifier for numeric values", "UsingDefaultValue": true, "Level": 2, "UseLevels": false, @@ -426,7 +466,7 @@ ], "Outputs": [ { - "Id": "b637a7c648e04a7fb5696b4379d315bb", + "Id": "1b705b6125b5443195d274ecac8cf387", "Name": "string", "Description": "String representation of the object", "UsingDefaultValue": false, @@ -440,11 +480,11 @@ }, { "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", - "Id": "00fe75dd876646779ab8e90c72690e81", + "Id": "2451b0dca8e54fa98c17fbb6f5aa9c80", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "84d7ad92ce1e42638bbe8162e4e5268d", + "Id": "63692e1c01524a77a4e90dcb64e7ea77", "Name": "object", "Description": "Object to be serialized", "UsingDefaultValue": false, @@ -453,9 +493,9 @@ "KeepListStructure": false }, { - "Id": "8cedd63d129745be808ec01669c68c47", - "Name": "useNumericFormat", - "Description": "should the numeric precision format be used when converting doubles", + "Id": "1d6f9331f32d43fc97b50d78fab08250", + "Name": "formatSpecifier", + "Description": "format specifier for numeric values", "UsingDefaultValue": true, "Level": 2, "UseLevels": false, @@ -464,7 +504,7 @@ ], "Outputs": [ { - "Id": "0515f8d3c1ea4a26a86a602c771d2ae0", + "Id": "3f24ba400c0946f3b530b795f7b07be8", "Name": "string", "Description": "String representation of the object", "UsingDefaultValue": false, @@ -478,11 +518,11 @@ }, { "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", - "Id": "b67de7cc81f54cd5b25e4df6d54827b6", + "Id": "c8801f22da1943cab36bd03806cc20cd", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "b58d10476fa040f8be7025c53047c0f4", + "Id": "bb5682d9c8e44bcc92b842ef0d62d3a1", "Name": "object", "Description": "Object to be serialized", "UsingDefaultValue": false, @@ -491,9 +531,9 @@ "KeepListStructure": false }, { - "Id": "5d829f83fcb84feeaf8451cec711e6dd", - "Name": "useNumericFormat", - "Description": "should the numeric precision format be used when converting doubles", + "Id": "7b2cac575b6143b5bc7f3fd275240764", + "Name": "formatSpecifier", + "Description": "format specifier for numeric values", "UsingDefaultValue": true, "Level": 2, "UseLevels": false, @@ -502,7 +542,7 @@ ], "Outputs": [ { - "Id": "87abb8ade0dc4cea8a7bad5cda1a4279", + "Id": "dd1cde67a44643578a4f79bbffcec458", "Name": "string", "Description": "String representation of the object", "UsingDefaultValue": false, @@ -515,27 +555,34 @@ "Description": "Converts an object to a string representation" }, { - "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", - "WatchWidth": 80.0, - "WatchHeight": 38.0, - "Id": "a7ec69bec9f546768d640012690aad24", + "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "Id": "1bbe9fbe696945ab801c0428693a34c1", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "57ee3c55175e450c90448f945205b088", - "Name": "", - "Description": "Node to show output from", + "Id": "fa02fe5e367b41a286926a6177e390cd", + "Name": "object", + "Description": "Object to be serialized", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, "KeepListStructure": false + }, + { + "Id": "1bdd311b836d48afa8eb87b67e9f7127", + "Name": "formatSpecifier", + "Description": "format specifier for numeric values", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false } ], "Outputs": [ { - "Id": "e7c1095b3d434891b48dabcebbc9ac9a", - "Name": "", - "Description": "Node output", + "Id": "763a0f6364f24fc4ab60eb421975b941", + "Name": "string", + "Description": "String representation of the object", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, @@ -543,30 +590,57 @@ } ], "Replication": "Disabled", - "Description": "Visualizes a node's output" + "Description": "Converts an object to a string representation" }, { - "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", - "WatchWidth": 87.5, - "WatchHeight": 38.0, - "Id": "b644da30668e4287bc92918735d5b0fc", + "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "Id": "2194d136e214459b8d04f11e5d39f0db", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "259b4270cd3347a7911293d685affcee", - "Name": "", - "Description": "Node to show output from", + "Id": "4833cd518b874c648878cda9793b7bfe", + "Name": "object", + "Description": "Object to be serialized", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, "KeepListStructure": false + }, + { + "Id": "52f0dff47f29434b8709fb228a2e2e51", + "Name": "formatSpecifier", + "Description": "format specifier for numeric values", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false } ], "Outputs": [ { - "Id": "718799e6939a421f9b481991f7015fdb", + "Id": "069559e4e385493980c709b0861e8186", + "Name": "string", + "Description": "String representation of the object", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Converts an object to a string representation" + }, + { + "ConcreteType": "CoreNodeModels.Input.DoubleInput, CoreNodeModels", + "NumberType": "Double", + "Id": "275e748e781c45d8895214258a51ab90", + "NodeType": "NumberInputNode", + "Inputs": [], + "Outputs": [ + { + "Id": "487ea80b7ca247de898094a2839611e3", "Name": "", - "Description": "Node output", + "Description": "Double", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, @@ -574,15 +648,16 @@ } ], "Replication": "Disabled", - "Description": "Visualizes a node's output" + "Description": "Creates a number", + "InputValue": 123456789.0 }, { "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", - "Id": "680caae1a3ea4095803b2493571cce7a", + "Id": "df29ded8e49c4755be88d57e4bda23d9", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "cd3452ad72e94a659eed9d147cff3554", + "Id": "bb7a79b378b549c6aede58d93dc2eb37", "Name": "object", "Description": "Object to be serialized", "UsingDefaultValue": false, @@ -591,10 +666,10 @@ "KeepListStructure": false }, { - "Id": "6cb36d659e7a4c9791373741e1a07ec3", - "Name": "useNumericFormat", - "Description": "should the numeric precision format be used when converting doubles (disabled)", - "UsingDefaultValue": false, + "Id": "6bfb6b40654845b8bf33602a6d179536", + "Name": "formatSpecifier", + "Description": "format specifier for numeric values", + "UsingDefaultValue": true, "Level": 2, "UseLevels": false, "KeepListStructure": false @@ -602,7 +677,7 @@ ], "Outputs": [ { - "Id": "b7a7cd5475b14f069395f5fd4f760779", + "Id": "4140df13525c4d9bb934c8fb6d46a328", "Name": "string", "Description": "String representation of the object", "UsingDefaultValue": false, @@ -616,13 +691,13 @@ }, { "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", - "WatchWidth": 147.5, - "WatchHeight": 38.0, - "Id": "8b3258a0ac584bf5a3261ca66aaa788d", + "WatchWidth": 184.0, + "WatchHeight": 102.0, + "Id": "92884c6c303641299316c83273ce718c", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "7d5f8dd21d0f493da25b9002273d5e80", + "Id": "019f22c1b40844b3a7bbc3a551be6310", "Name": "", "Description": "Node to show output from", "UsingDefaultValue": false, @@ -633,7 +708,7 @@ ], "Outputs": [ { - "Id": "832846b8799d4fe7ae1ac6c9901608cc", + "Id": "4022383166d94960b5b0e19c43a36148", "Name": "", "Description": "Node output", "UsingDefaultValue": false, @@ -646,15 +721,27 @@ "Description": "Visualizes a node's output" }, { - "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", - "Id": "5e4770f0e3cc417f92776a8b8b83b533", - "NodeType": "CodeBlockNode", - "Inputs": [], + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 200.0, + "WatchHeight": 200.0, + "Id": "cd8ed092d8a04f3e8a0137d70c3833dd", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "914170b3ab1842cba4f5bb72498f5db5", + "Name": "", + "Description": "Node to show output from", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], "Outputs": [ { - "Id": "b45e2569af7049288b2b0aa558d3a7c3", + "Id": "0e62fb306b7e43b2bdcc1a7619a71b9e", "Name": "", - "Description": "Value of expression at line 1", + "Description": "Node output", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, @@ -662,140 +749,152 @@ } ], "Replication": "Disabled", - "Description": "Allows for DesignScript code to be authored directly", - "Code": "{\"key\":\"0.000000000\"};" + "Description": "Visualizes a node's output" } ], "Connectors": [ { "Start": "a5a3fa26f7dc45a39a173e9928d26464", - "End": "6aabc2cc4cf04250a13db4172d4639d9", - "Id": "54407ca45ed2419984bec3427451c9e3", + "End": "065e1a4cbceb41f09a22e802fc9dbe15", + "Id": "05d4a850182c442a92250b00a02f92f5", "IsHidden": "False" }, { "Start": "14d00072325d4ff4a55b64a6e794da3a", - "End": "3d51288719f74206b97a80587f317744", - "Id": "40c6ff636e6d4de0923dc11deaf51453", + "End": "63692e1c01524a77a4e90dcb64e7ea77", + "Id": "3f607494975b415f8397960344a70028", "IsHidden": "False" }, { "Start": "3c7008e844154852a868d0360bd5531b", - "End": "84d7ad92ce1e42638bbe8162e4e5268d", - "Id": "28b5d66ce83548bf84ccb945f0c04ba0", + "End": "bb5682d9c8e44bcc92b842ef0d62d3a1", + "Id": "09ae3ab31ba44679b93a86f677a6a870", "IsHidden": "False" }, { "Start": "e5afe6443c5e4dc58e7a1fb8b04bb7ad", - "End": "b58d10476fa040f8be7025c53047c0f4", - "Id": "e4f244c0898a47c8b39af658f0b5c366", + "End": "fa02fe5e367b41a286926a6177e390cd", + "Id": "aa6e857c034340a8a5748027b15c19cd", "IsHidden": "False" }, { - "Start": "1f642ebeec5e444aa4ae36a1b832ee62", - "End": "286987f4a6ab4f9580be045e75e6d3c2", - "Id": "b4d4572034e94549aeb3a0370a761147", + "Start": "b7a7cd5475b14f069395f5fd4f760779", + "End": "7d5f8dd21d0f493da25b9002273d5e80", + "Id": "3192964ec1f745c584ceab0aabcb501c", "IsHidden": "False" }, { - "Start": "d3a731bd764d4b95bb1bed61d967d0ea", - "End": "422fe9f197a64b36b0f981800a6d3c21", - "Id": "1c436d3435d54f94a8f47af0bcfe899a", + "Start": "b45e2569af7049288b2b0aa558d3a7c3", + "End": "cd3452ad72e94a659eed9d147cff3554", + "Id": "108c352a91fd4048935715e2e3e59b94", "IsHidden": "False" }, { - "Start": "5fef519e74ce4fa496410a802424f7f2", - "End": "6597820795a745789041ff10a3c1c806", - "Id": "adff13861d524a1ead8f0673b665c9bf", + "Start": "bd621135843f4e32b20128fabb5b349a", + "End": "28bc476b868f4346aacf08498000189f", + "Id": "91c74477d6564065956c24a0a61daad5", "IsHidden": "False" }, { - "Start": "f2d95d3d01d8413392f48e02b950d2ef", - "End": "6f6a4d2e3e104ba1bbd86db24f642fc5", - "Id": "2721b446100d40f69461416ceeded1f0", + "Start": "bd621135843f4e32b20128fabb5b349a", + "End": "6cb36d659e7a4c9791373741e1a07ec3", + "Id": "80a067f1cf8a4985988b16b31dd1dbb1", "IsHidden": "False" }, { - "Start": "ca716b66554a49e8b61510a19fe4006f", - "End": "cfb7af8d58164cc1becd72025206192f", - "Id": "81ebdbb3ce4a4774a5d5fd8026ccb12d", + "Start": "bd621135843f4e32b20128fabb5b349a", + "End": "47f0dc27e828410cbaa454c9c29d0e67", + "Id": "e09be04861044084b200f58bb9ff4e0c", "IsHidden": "False" }, { - "Start": "420eb88b471548849e114110915c33ef", - "End": "26c6b353d485484da02ca6e995274416", - "Id": "f8328eb3095047a4a0ee11429df3071b", + "Start": "bd621135843f4e32b20128fabb5b349a", + "End": "1d6f9331f32d43fc97b50d78fab08250", + "Id": "739924ee07ab4156b85f39253b4985af", "IsHidden": "False" }, { - "Start": "420eb88b471548849e114110915c33ef", - "End": "a9314e3f699849dba1cad5e52e62b92b", - "Id": "fb7f62cb04be4471ada2dbcf702d4812", + "Start": "bd621135843f4e32b20128fabb5b349a", + "End": "7b2cac575b6143b5bc7f3fd275240764", + "Id": "0a57f5cb0e204fdda7664165b2653abc", "IsHidden": "False" }, { - "Start": "420eb88b471548849e114110915c33ef", - "End": "5d829f83fcb84feeaf8451cec711e6dd", - "Id": "623087dab2c543248fa5cacc6e554a33", + "Start": "bd621135843f4e32b20128fabb5b349a", + "End": "1bdd311b836d48afa8eb87b67e9f7127", + "Id": "ae0a23488ea549b8a612b307a5c77a16", "IsHidden": "False" }, { - "Start": "420eb88b471548849e114110915c33ef", - "End": "8cedd63d129745be808ec01669c68c47", - "Id": "17d53bd28f72401abd5f8ca3cbe88c05", + "Start": "bd621135843f4e32b20128fabb5b349a", + "End": "52f0dff47f29434b8709fb228a2e2e51", + "Id": "3fbd3973e22048d9bfad8450520d8aa9", "IsHidden": "False" }, { - "Start": "420eb88b471548849e114110915c33ef", - "End": "6cb36d659e7a4c9791373741e1a07ec3", - "Id": "d80056bbc218425cae561bd6c4f4614b", + "Start": "eb1a9bcb42934dc293bfc3350ef15a85", + "End": "a9b1075f9ebb426694446b6f97308228", + "Id": "85a1759a56cd40f9a754dc38d5b92b61", "IsHidden": "False" }, { - "Start": "b637a7c648e04a7fb5696b4379d315bb", - "End": "e77f5b74aa0c4531939d0dce7ca2ea44", - "Id": "0fcea9db5a7141ef8eaa6548787319bb", + "Start": "484311c3e33d48208bfe70baabef9539", + "End": "8c04eff2dbe74b5bbe8e23b5878a1372", + "Id": "a97a202dcb524a98ae46476c819c8448", "IsHidden": "False" }, { - "Start": "0515f8d3c1ea4a26a86a602c771d2ae0", - "End": "970af28845014907935d9c6842d83445", - "Id": "7cbbdd54dfc7435e9336e3bf551a16fd", + "Start": "2a84b826723841daabe17488bfa4696e", + "End": "4833cd518b874c648878cda9793b7bfe", + "Id": "b004d9b62ce247f592ec9c86dff2d1a3", "IsHidden": "False" }, { - "Start": "0515f8d3c1ea4a26a86a602c771d2ae0", - "End": "57ee3c55175e450c90448f945205b088", - "Id": "94ed589962c04434ba4d7c9086aea0fd", + "Start": "1b705b6125b5443195d274ecac8cf387", + "End": "286987f4a6ab4f9580be045e75e6d3c2", + "Id": "9ebcc1f2b85d4d9581ae33d6e01c9835", "IsHidden": "False" }, { - "Start": "87abb8ade0dc4cea8a7bad5cda1a4279", - "End": "c1a2092bb2fe4a039815751d49b06c3a", - "Id": "134511bfedaa41a1957595bf5d3a4ba4", + "Start": "3f24ba400c0946f3b530b795f7b07be8", + "End": "422fe9f197a64b36b0f981800a6d3c21", + "Id": "3e1ff4c8f2484d4bb657f39ce3acdf76", "IsHidden": "False" }, { - "Start": "87abb8ade0dc4cea8a7bad5cda1a4279", - "End": "259b4270cd3347a7911293d685affcee", - "Id": "00b57b7d3d954fec8472bc5715731996", + "Start": "dd1cde67a44643578a4f79bbffcec458", + "End": "6597820795a745789041ff10a3c1c806", + "Id": "a1ca444d97c94e869e4b236277258c2e", "IsHidden": "False" }, { - "Start": "b7a7cd5475b14f069395f5fd4f760779", - "End": "7d5f8dd21d0f493da25b9002273d5e80", - "Id": "d3bb795d153549bc8ea763615e7ee966", + "Start": "763a0f6364f24fc4ab60eb421975b941", + "End": "2c2b4228f1f74ccc9ab191dbcddeef2b", + "Id": "cf7beef7064841f2afd7abe19eda19e3", "IsHidden": "False" }, { - "Start": "b45e2569af7049288b2b0aa558d3a7c3", - "End": "cd3452ad72e94a659eed9d147cff3554", - "Id": "633e8fbcb94943b8a0589c96fa302545", + "Start": "069559e4e385493980c709b0861e8186", + "End": "914170b3ab1842cba4f5bb72498f5db5", + "Id": "fa9c716ff76d4162a2fb4c45bf6aad00", + "IsHidden": "False" + }, + { + "Start": "487ea80b7ca247de898094a2839611e3", + "End": "bb7a79b378b549c6aede58d93dc2eb37", + "Id": "2a1fe23f82fb4f2d83975ffe29491012", + "IsHidden": "False" + }, + { + "Start": "4140df13525c4d9bb934c8fb6d46a328", + "End": "019f22c1b40844b3a7bbc3a551be6310", + "Id": "2a24a7679ba44adda65ee4bf0534d6c9", "IsHidden": "False" } ], "Dependencies": [], "NodeLibraryDependencies": [], + "EnableLegacyPolyCurveBehavior": true, "Thumbnail": "", "GraphDocumentationURL": null, "ExtensionWorkspaceData": [ @@ -819,8 +918,8 @@ "ScaleFactor": 1.0, "HasRunWithoutCrash": true, "IsVisibleInDynamoLibrary": true, - "Version": "3.0.0.6086", - "RunType": "Automatic", + "Version": "3.4.0.6676", + "RunType": "Manual", "RunPeriod": "1000" }, "Camera": { @@ -844,8 +943,8 @@ "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 185.44736955102093, - "Y": 162.1923398998582 + "X": 115.67426105668028, + "Y": -287.8456424997603 }, { "Id": "9b74289ccd7242749bfbb6b56d2774bb", @@ -854,8 +953,8 @@ "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 199.44736955102093, - "Y": 346.1923398998582 + "X": 64.33938073241075, + "Y": 39.70634987252754 }, { "Id": "075ecd65d9b44489b09041a309f0b794", @@ -864,8 +963,8 @@ "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 179.44736955102093, - "Y": 473.1923398998582 + "X": 115.67426105668028, + "Y": 623.7068471196142 }, { "Id": "1ce66222719e414eb4e393544239f4e5", @@ -874,68 +973,78 @@ "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 182.44736955102093, - "Y": 595.1923398998582 + "X": 52.367205920489596, + "Y": 907.8542090962671 }, { - "Id": "39b81424e52f4e50a24e570690b00cc6", - "Name": "String.ToNumber", + "Id": "d3fb3523609f456fbc233dcae1d48732", + "Name": "Watch1", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 772.6480556547714, - "Y": 405.4495890984118 + "X": 999.6928641254308, + "Y": -54.5580923127701 }, { - "Id": "e0bb383beb004ef6b5764c3251913495", - "Name": "String.ToNumber", + "Id": "ae77e756519e43ad9ac1861827601e22", + "Name": "Watch2", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 769.3970019504612, - "Y": 578.4140297708927 + "X": 998.39733153422, + "Y": 246.587092661364 }, { - "Id": "53e38da5d6454ea39128d2ecffa44912", - "Name": "String.ToNumber", + "Id": "1ec6ed7b75a64bfcba77b81f82ed8f50", + "Name": "Watch3", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 762.3970019504612, - "Y": 720.4140297708927 + "X": 969.5559999591637, + "Y": 567.4236591317275 }, { - "Id": "d3fb3523609f456fbc233dcae1d48732", - "Name": "Watch1", + "Id": "680caae1a3ea4095803b2493571cce7a", + "Name": "String from Object2", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 1097.3741239352394, - "Y": 379.02061936181263 + "X": 721.1166494505987, + "Y": 1605.2830355613005 }, { - "Id": "ae77e756519e43ad9ac1861827601e22", - "Name": "Watch2", + "Id": "8b3258a0ac584bf5a3261ca66aaa788d", + "Name": "Watch6", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 1040.548580047816, - "Y": 522.0687226159225 + "X": 1040.1166494505987, + "Y": 1605.2830355613005 }, { - "Id": "1ec6ed7b75a64bfcba77b81f82ed8f50", - "Name": "Watch3", + "Id": "5e4770f0e3cc417f92776a8b8b83b533", + "Name": "Code Block", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 365.5710819435785, + "Y": 1605.1105355613006 + }, + { + "Id": "662c8c937a80459b971650b87a6fcfe4", + "Name": "Code Block", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 1143.9844807892096, - "Y": 709.6687279307367 + "X": -475.8980754364303, + "Y": 754.2873402247715 }, { "Id": "02c1b3e721dd4941ac15d8461b154a49", @@ -944,123 +1053,143 @@ "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 1163.8342015574185, - "Y": 879.4797576583975 + "X": 969.5559999591637, + "Y": 880.4236591317275 }, { - "Id": "f9912ec0f91c49ad82f22c32bad4bb11", - "Name": "String.ToNumber", + "Id": "a74956c410ce41b7b43a195dad0e38b5", + "Name": "Code Block", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 817.3970019504612, - "Y": 842.4140297708927 + "X": 353.82061073362206, + "Y": 1846.07157949955 }, { - "Id": "e4b36729f3b54ef6aca2086f6bb57f58", + "Id": "f776aa328bd043ee8ec082b49bffe6a3", "Name": "String from Object2", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 498.119488531315, - "Y": 319.9280924046476 + "X": 710.8206107336221, + "Y": 1846.2440794995498 }, { - "Id": "ec91128266524e0a95cdc2e08a99a54b", - "Name": "Boolean", + "Id": "3a45200d74bb4ece97d0fb1bb03ec973", + "Name": "Watch7", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 125.74288491428808, - "Y": 827.8484794260075 + "X": 1032.8006474657432, + "Y": 1928.7051347432157 }, { - "Id": "98e44d23bf0d4c15a627025ac68aaf51", - "Name": "String from Object2", + "Id": "e0e5a49813ef41e8bbdcaf9844fd6e86", + "Name": "Code Block", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 491.1576104786528, - "Y": 576.3860738606195 + "X": -81.75799888567963, + "Y": 1303.8630016714806 }, { - "Id": "00fe75dd876646779ab8e90c72690e81", - "Name": "String from Object2", + "Id": "9c16d38e96ad477dab6fad80d8f28f74", + "Name": "String from Object And Format", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 464.9062143196976, - "Y": 763.5480428824812 + "X": 424.4515027871015, + "Y": -295.59369971031424 }, { - "Id": "b67de7cc81f54cd5b25e4df6d54827b6", - "Name": "String from Object2", + "Id": "2451b0dca8e54fa98c17fbb6f5aa9c80", + "Name": "String from Object And Format", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 465.0855234398824, - "Y": 952.1374700195747 + "X": 388.1005679987211, + "Y": 0.4483476842422647 }, { - "Id": "a7ec69bec9f546768d640012690aad24", - "Name": "Watch5", + "Id": "c8801f22da1943cab36bd03806cc20cd", + "Name": "String from Object And Format", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 1153.3485221133606, - "Y": 1042.6050120833188 + "X": 416.8217740245268, + "Y": 442.56509594756284 }, { - "Id": "b644da30668e4287bc92918735d5b0fc", - "Name": "Watch6", + "Id": "1bbe9fbe696945ab801c0428693a34c1", + "Name": "String from Object And Format", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 1152.1739388504354, - "Y": 1199.0626990481478 + "X": 449.6756726974987, + "Y": 894.8451762576958 }, { - "Id": "680caae1a3ea4095803b2493571cce7a", - "Name": "String from Object2", + "Id": "2194d136e214459b8d04f11e5d39f0db", + "Name": "String from Object And Format", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 745.4698214608002, - "Y": 1307.2261855303775 + "X": 511.71836089332555, + "Y": 1299.6245343442215 }, { - "Id": "8b3258a0ac584bf5a3261ca66aaa788d", - "Name": "Watch7", + "Id": "275e748e781c45d8895214258a51ab90", + "Name": "Number", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 1081.1123210884134, - "Y": 1365.22135433937 + "X": 100.54811428273808, + "Y": -505.73875497749736 }, { - "Id": "5e4770f0e3cc417f92776a8b8b83b533", - "Name": "Code Block", + "Id": "df29ded8e49c4755be88d57e4bda23d9", + "Name": "String from Object And Format", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 409.3253560131593, + "Y": -513.4868121880513 + }, + { + "Id": "92884c6c303641299316c83273ce718c", + "Name": "Watch0", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "ShowGeometry": true, + "X": 884.798673288619, + "Y": -518.8107682252431 + }, + { + "Id": "cd8ed092d8a04f3e8a0137d70c3833dd", + "Name": "Watch5", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 131.0, - "Y": 1288.0 + "X": 983.0477947579423, + "Y": 1253.668472804629 } ], "Annotations": [], - "X": 286.99844688136534, - "Y": -122.44121147514721, - "Zoom": 0.9219474033079375 + "X": -169.52963948937793, + "Y": -578.7067270043049, + "Zoom": 0.6459837027060035 } } \ No newline at end of file diff --git a/test/core/string/TestStringFromArrayPreview_numericformat.dyn b/test/core/string/TestStringFromArrayPreview_numericformat.dyn index ea9289064e8..d4dabeccd35 100644 --- a/test/core/string/TestStringFromArrayPreview_numericformat.dyn +++ b/test/core/string/TestStringFromArrayPreview_numericformat.dyn @@ -60,7 +60,7 @@ }, { "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", - "WatchWidth": 297.5, + "WatchWidth": 298.0, "WatchHeight": 38.0, "Id": "4b6c7485022c4593ad15d280b5e99e8f", "NodeType": "ExtensionNode", @@ -90,27 +90,15 @@ "Description": "Visualizes a node's output" }, { - "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", - "WatchWidth": 297.5, - "WatchHeight": 38.0, - "Id": "444b7edf23d6447393035c03543e7b2a", - "NodeType": "ExtensionNode", - "Inputs": [ - { - "Id": "fd87ba31e76e429b9940e54a2fb7eb05", - "Name": "", - "Description": "Node to show output from", - "UsingDefaultValue": false, - "Level": 2, - "UseLevels": false, - "KeepListStructure": false - } - ], + "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", + "Id": "b9352a46c1634e65a64bd8062e2a6102", + "NodeType": "CodeBlockNode", + "Inputs": [], "Outputs": [ { - "Id": "b0ae91f09bd740d2979bc716ee6166d1", + "Id": "9eebab252bf0454c826a3fb48016ec02", "Name": "", - "Description": "Node output", + "Description": "Value of expression at line 1", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, @@ -118,15 +106,16 @@ } ], "Replication": "Disabled", - "Description": "Visualizes a node's output" + "Description": "Allows for DesignScript code to be authored directly", + "Code": "[\"F1\",\"G\",\"B\"];" }, { "ConcreteType": "CoreNodeModels.StringFromArray, CoreNodeModels", - "Id": "3d39644d6ca04fbca80bc82f8d7a720f", + "Id": "74f97ab047fa49eaaa8d77271ecb87e0", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "4b4c706e2e1b4f8d8b9a9438a2e22601", + "Id": "39204eddb5214b8784ef4d0a66415a2e", "Name": "array", "Description": "The array of object to be serialized", "UsingDefaultValue": false, @@ -135,10 +124,10 @@ "KeepListStructure": false }, { - "Id": "0fd87c00c80d437bab0b70a0e7721e24", + "Id": "a93226abb9014f848ced0e08e546b696", "Name": "useNumericFormat", - "Description": "should the numeric precision format be used when converting doubles", - "UsingDefaultValue": true, + "Description": "should the numeric precision format be used when converting doubles (disabled)", + "UsingDefaultValue": false, "Level": 2, "UseLevels": false, "KeepListStructure": false @@ -146,7 +135,7 @@ ], "Outputs": [ { - "Id": "0f4992f68f33412a9d5b00b17c0510e0", + "Id": "9bb562665ed04284adf767976c17b2d2", "Name": "string", "Description": "String representation of the array", "UsingDefaultValue": false, @@ -160,13 +149,13 @@ }, { "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", - "WatchWidth": 177.5, + "WatchWidth": 80.0, "WatchHeight": 38.0, - "Id": "70bf2a936f9141199a0d726dd765f694", + "Id": "c198ae603bba4cc0a7ef17c3444f8156", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "63f0bd8bc6974ad38237d47f6663b770", + "Id": "b389674f395a4746b32d7583d975e743", "Name": "", "Description": "Node to show output from", "UsingDefaultValue": false, @@ -177,7 +166,7 @@ ], "Outputs": [ { - "Id": "ab4da6a6775e4716b7b44e2c550bc61a", + "Id": "929d7e76504340349292c5c432724364", "Name": "", "Description": "Node output", "UsingDefaultValue": false, @@ -190,15 +179,27 @@ "Description": "Visualizes a node's output" }, { - "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", - "Id": "b9352a46c1634e65a64bd8062e2a6102", - "NodeType": "CodeBlockNode", - "Inputs": [], + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 298.0, + "WatchHeight": 38.0, + "Id": "a28fa354113640eab04af51930aaeca2", + "NodeType": "ExtensionNode", + "Inputs": [ + { + "Id": "44b3628a3c864218b68753a9552537b3", + "Name": "", + "Description": "Node to show output from", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], "Outputs": [ { - "Id": "1dd82e4720ee46d59e8283b965f62f18", + "Id": "f1307dd499c7413587db852a6a66fa42", "Name": "", - "Description": "Value of expression at line 1", + "Description": "Node output", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, @@ -206,27 +207,19 @@ } ], "Replication": "Disabled", - "Description": "Allows for DesignScript code to be authored directly", - "Code": "true;" + "Description": "Visualizes a node's output" }, { - "ConcreteType": "CoreNodeModels.StringFromArray, CoreNodeModels", - "Id": "74f97ab047fa49eaaa8d77271ecb87e0", + "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", + "WatchWidth": 419.0, + "WatchHeight": 136.0, + "Id": "f690cbe74f4c45e7917e742af16219ad", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "39204eddb5214b8784ef4d0a66415a2e", - "Name": "array", - "Description": "The array of object to be serialized", - "UsingDefaultValue": false, - "Level": 2, - "UseLevels": false, - "KeepListStructure": false - }, - { - "Id": "a93226abb9014f848ced0e08e546b696", - "Name": "useNumericFormat", - "Description": "should the numeric precision format be used when converting doubles (disabled)", + "Id": "0a76d7cfd50044868dc5996ae88c325f", + "Name": "", + "Description": "Node to show output from", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, @@ -235,9 +228,9 @@ ], "Outputs": [ { - "Id": "9bb562665ed04284adf767976c17b2d2", - "Name": "string", - "Description": "String representation of the array", + "Id": "05280f24000e45ada5b1e986d72423e4", + "Name": "", + "Description": "Node output", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, @@ -245,30 +238,37 @@ } ], "Replication": "Disabled", - "Description": "Converts an array to a string representation" + "Description": "Visualizes a node's output" }, { - "ConcreteType": "CoreNodeModels.Watch, CoreNodeModels", - "WatchWidth": 80.0, - "WatchHeight": 38.0, - "Id": "c198ae603bba4cc0a7ef17c3444f8156", + "ConcreteType": "CoreNodeModels.StringFromArray, CoreNodeModels", + "Id": "96271f95253f4524a95db2d7400c4f52", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "b389674f395a4746b32d7583d975e743", - "Name": "", - "Description": "Node to show output from", + "Id": "67584c6e3687412ca4c3fca661a85911", + "Name": "array", + "Description": "The array of object to be serialized", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, "KeepListStructure": false + }, + { + "Id": "56f6b5874d3d4474b9efc9266735b5e4", + "Name": "formatSpecifier", + "Description": "format specifier for numeric values", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false } ], "Outputs": [ { - "Id": "929d7e76504340349292c5c432724364", - "Name": "", - "Description": "Node output", + "Id": "2b5df70c7ac34313813f29f47326e817", + "Name": "string", + "Description": "String representation of the array", "UsingDefaultValue": false, "Level": 2, "UseLevels": false, @@ -276,15 +276,15 @@ } ], "Replication": "Disabled", - "Description": "Visualizes a node's output" + "Description": "Converts an array to a string representation" }, { "ConcreteType": "CoreNodeModels.StringFromArray, CoreNodeModels", - "Id": "c8b9fc78b61e413dae18a01a2d4114f6", + "Id": "24cdee3feeb04e09bcad4b0078581347", "NodeType": "ExtensionNode", "Inputs": [ { - "Id": "23c77cf3ae1f447fb3c8fb9a70189e8b", + "Id": "1823631337ab41a58bc0b24670d65ae2", "Name": "array", "Description": "The array of object to be serialized", "UsingDefaultValue": false, @@ -293,9 +293,9 @@ "KeepListStructure": false }, { - "Id": "20c3c708ee63436badb93364cc6efafb", - "Name": "useNumericFormat", - "Description": "should the numeric precision format be used when converting doubles", + "Id": "ea6ed5138ef74182b621508230aaf896", + "Name": "formatSpecifier", + "Description": "format specifier for numeric values", "UsingDefaultValue": true, "Level": 2, "UseLevels": false, @@ -304,7 +304,7 @@ ], "Outputs": [ { - "Id": "91e5262223774c2cac5056ab15ecdb2f", + "Id": "2fac04be2c194c2cabf862a710cda54a", "Name": "string", "Description": "String representation of the array", "UsingDefaultValue": false, @@ -330,12 +330,6 @@ "Id": "e1f6a2d64a1547dfb384016d5be86549", "IsHidden": "False" }, - { - "Start": "480593de671c4fd0a5aba280e2065a8b", - "End": "4b4c706e2e1b4f8d8b9a9438a2e22601", - "Id": "59019ff77b08442a9fe20ba7b7cde0a2", - "IsHidden": "False" - }, { "Start": "480593de671c4fd0a5aba280e2065a8b", "End": "39204eddb5214b8784ef4d0a66415a2e", @@ -344,20 +338,20 @@ }, { "Start": "480593de671c4fd0a5aba280e2065a8b", - "End": "23c77cf3ae1f447fb3c8fb9a70189e8b", - "Id": "ca769a9b5dc341fab5f75a947c403a85", + "End": "67584c6e3687412ca4c3fca661a85911", + "Id": "4a27e6486b994d3a83828b2339bbfd80", "IsHidden": "False" }, { - "Start": "0f4992f68f33412a9d5b00b17c0510e0", - "End": "63f0bd8bc6974ad38237d47f6663b770", - "Id": "2263ef87ef884e0db460d2aeb1366e93", + "Start": "480593de671c4fd0a5aba280e2065a8b", + "End": "1823631337ab41a58bc0b24670d65ae2", + "Id": "58753234ed1f47d49702260243e689c9", "IsHidden": "False" }, { - "Start": "1dd82e4720ee46d59e8283b965f62f18", - "End": "0fd87c00c80d437bab0b70a0e7721e24", - "Id": "4e38e9fa28e64afda034e474968c87dd", + "Start": "9eebab252bf0454c826a3fb48016ec02", + "End": "ea6ed5138ef74182b621508230aaf896", + "Id": "938d461eafdd4ef9806ee339969e12f6", "IsHidden": "False" }, { @@ -367,14 +361,21 @@ "IsHidden": "False" }, { - "Start": "91e5262223774c2cac5056ab15ecdb2f", - "End": "fd87ba31e76e429b9940e54a2fb7eb05", - "Id": "324b94c5d10941deacb894c1844b1c3f", + "Start": "2b5df70c7ac34313813f29f47326e817", + "End": "44b3628a3c864218b68753a9552537b3", + "Id": "2dd8f3f0b65a43f8b2ac4836724943a1", + "IsHidden": "False" + }, + { + "Start": "2fac04be2c194c2cabf862a710cda54a", + "End": "0a76d7cfd50044868dc5996ae88c325f", + "Id": "2ff00e8d99de423195bc927856b1d761", "IsHidden": "False" } ], "Dependencies": [], "NodeLibraryDependencies": [], + "EnableLegacyPolyCurveBehavior": true, "Thumbnail": "", "GraphDocumentationURL": null, "ExtensionWorkspaceData": [ @@ -398,7 +399,7 @@ "ScaleFactor": 1.0, "HasRunWithoutCrash": true, "IsVisibleInDynamoLibrary": true, - "Version": "3.0.0.6086", + "Version": "3.4.0.6676", "RunType": "Automatic", "RunPeriod": "1000" }, @@ -444,82 +445,82 @@ "Excluded": false, "ShowGeometry": true, "X": 592.9054158830944, - "Y": 269.110183681075 + "Y": 268.0759595281854 }, { - "Id": "444b7edf23d6447393035c03543e7b2a", - "Name": "watch2", + "Id": "b9352a46c1634e65a64bd8062e2a6102", + "Name": "Code Block", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 575.2274753658695, - "Y": 417.24281878340815 + "X": -129.38907825891982, + "Y": 682.3632653107057 }, { - "Id": "3d39644d6ca04fbca80bc82f8d7a720f", + "Id": "74f97ab047fa49eaaa8d77271ecb87e0", "Name": "String from Array2", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 335.93713118238543, - "Y": 655.3098310110507 + "X": 327.4697339717835, + "Y": 881.6712841125085 }, { - "Id": "70bf2a936f9141199a0d726dd765f694", - "Name": "watch3", + "Id": "c198ae603bba4cc0a7ef17c3444f8156", + "Name": "watch4", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 603.67829140981, - "Y": 656.8284604865979 + "X": 611.7258533738277, + "Y": 902.9404607916114 }, { - "Id": "b9352a46c1634e65a64bd8062e2a6102", - "Name": "Code Block", + "Id": "a28fa354113640eab04af51930aaeca2", + "Name": "Watch2", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": -20.865738536736444, - "Y": 685.6950649607055 + "X": 620.7629312816283, + "Y": 407.74862501298634 }, { - "Id": "74f97ab047fa49eaaa8d77271ecb87e0", - "Name": "String from Array2", + "Id": "f690cbe74f4c45e7917e742af16219ad", + "Name": "Watch3", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 327.4697339717835, - "Y": 881.6712841125085 + "X": 692.0084730824933, + "Y": 652.511871701363 }, { - "Id": "c198ae603bba4cc0a7ef17c3444f8156", - "Name": "watch4", + "Id": "96271f95253f4524a95db2d7400c4f52", + "Name": "String from Array And Format", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 611.7258533738277, - "Y": 902.9404607916114 + "X": 260.57759376051, + "Y": 410.86538545620147 }, { - "Id": "c8b9fc78b61e413dae18a01a2d4114f6", - "Name": "String from Array2", + "Id": "24cdee3feeb04e09bcad4b0078581347", + "Name": "String from Array And Format", "IsSetAsInput": false, "IsSetAsOutput": false, "Excluded": false, "ShowGeometry": true, - "X": 294.9112494242495, - "Y": 418.9155459518879 + "X": 305.38333347175626, + "Y": 656.9108064199578 } ], "Annotations": [], - "X": 113.92114508888528, - "Y": -217.60130393629618, - "Zoom": 0.8428937702322691 + "X": 5.4580877421955165, + "Y": -256.1436648704163, + "Zoom": 0.6181807073903587 } } \ No newline at end of file From 45753f099a69ea7f87bde00aace63a5bfa8bedcf Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" <508936+mjkkirschner@users.noreply.github.com> Date: Thu, 31 Oct 2024 18:31:46 -0400 Subject: [PATCH 09/22] new builtin tests --- .../ProtoTest/TD/MultiLangTests/StringTest.cs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/test/Engine/ProtoTest/TD/MultiLangTests/StringTest.cs b/test/Engine/ProtoTest/TD/MultiLangTests/StringTest.cs index 9fcf54a255c..15406388892 100644 --- a/test/Engine/ProtoTest/TD/MultiLangTests/StringTest.cs +++ b/test/Engine/ProtoTest/TD/MultiLangTests/StringTest.cs @@ -567,5 +567,45 @@ public void TestLocalizedStringInCode() thisTest.RunScriptSource(code); thisTest.Verify("x", "中文字符"); } + [Test] + public void TestStringFromArrayFormat() { + String code = + @" +import(""FFITarget.dll""); + a = ClassFunctionality.ClassFunctionality(1); + arr1 = [1,2]; + arr2 = [1.100005,a]; + arr3 = [5,a,1.1]; + b1 = ""a"" + __ToStringFromArrayAndFormat(arr1,""F2""); + b2 = ""a"" + __ToStringFromArrayAndFormat(arr2, ""G3""); + b3 = __ToStringFromArrayAndFormat(arr3, ""B""); + "; + thisTest.RunScriptSource(code); + thisTest.Verify("b1", "a[1.00,2.00]"); + thisTest.Verify("b2", "a[1.1,FFITarget.ClassFunctionality]"); + //TODO note this difference between array and object conversion - if any format specifier is invalid the entire array conversion fails. + //how should this behave? + thisTest.Verify("b3", "Format specifier was invalid." ); + + } + [Test] + public void TestStringFromObjectFormat() + { + String code = + @" +import(""FFITarget.dll""); + a = ClassFunctionality.ClassFunctionality(1); + arr1 = [1,2]; + arr2 = [1.100005,a]; + arr3 = [5,a,1.1]; + b1 = __ToStringFromObjectAndFormat(arr1,""F2""); + b2 = __ToStringFromObjectAndFormat(arr2, ""G3""); + b3 = __ToStringFromObjectAndFormat(arr3, ""B""); + "; + thisTest.RunScriptSource(code); + thisTest.Verify("b1", new string[] { "1.00", "2.00" }); + thisTest.Verify("b2", new string[]{"1.1","FFITarget.ClassFunctionality"}); + thisTest.Verify("b3", new string[] { "101", "FFITarget.ClassFunctionality","Format specifier was invalid." }); + } } } From 74a0b9430d4d140ccb2261caa6516a4bcde3f79c Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" <508936+mjkkirschner@users.noreply.github.com> Date: Thu, 31 Oct 2024 19:57:13 -0400 Subject: [PATCH 10/22] fix node doc tests --- .../MarkdownGeneratorCommandTests.cs | 8 +++++--- ...els.FromArray.md => CoreNodeModels.StringFromArray.md} | 4 ++-- ...s.FromObject.md => CoreNodeModels.StringFromObject.md} | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) rename test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/{CoreNodeModels.FromArray.md => CoreNodeModels.StringFromArray.md} (63%) rename test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/{CoreNodeModels.FromObject.md => CoreNodeModels.StringFromObject.md} (63%) diff --git a/test/Tools/NodeDocumentationMarkdownGeneratorTests/MarkdownGeneratorCommandTests.cs b/test/Tools/NodeDocumentationMarkdownGeneratorTests/MarkdownGeneratorCommandTests.cs index 37be71e8629..67dceab776f 100644 --- a/test/Tools/NodeDocumentationMarkdownGeneratorTests/MarkdownGeneratorCommandTests.cs +++ b/test/Tools/NodeDocumentationMarkdownGeneratorTests/MarkdownGeneratorCommandTests.cs @@ -225,7 +225,9 @@ public void DictionaryContentIsFoundCorrectlyForCoreNodes() // Arrange var testOutputDirName = "TestMdOutput_CoreNodeModels"; - + //these are new files/nodes so there is no dictionary content fo them. + var filesToSkip = new string[] { "CoreNodeModels.StringFromArray", "CoreNodeModels.StringFromObject" }; + var coreNodeModelsDll = Path.Combine(DynamoCoreNodesDir, CORENODEMODELS_DLL_NAME); Assert.That(File.Exists(coreNodeModelsDll)); @@ -250,8 +252,8 @@ public void DictionaryContentIsFoundCorrectlyForCoreNodes() //assert that the generated markdown files all contain an "indepth section" from the dictionary entry, which means //they were all found. - - Assert.True(generatedFileNames.Where(x=>Path.GetExtension(x).Contains("md")).All(x => File.ReadAllText(x).ToLower().Contains("in depth"))); + var generatedFileNamesSubset = generatedFileNames.Where(x => !filesToSkip.Contains(Path.GetFileNameWithoutExtension(x))); + Assert.True(generatedFileNamesSubset.Where(x=>Path.GetExtension(x).Contains("md")).All(x => File.ReadAllText(x).ToLower().Contains("in depth"))); } diff --git a/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FromArray.md b/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.StringFromArray.md similarity index 63% rename from test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FromArray.md rename to test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.StringFromArray.md index 53fe56fd7ab..21be3f4831e 100644 --- a/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FromArray.md +++ b/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.StringFromArray.md @@ -1,5 +1,5 @@ -## String from Array - Documentation -This documentation file is auto generated by NodeDocumentationMarkdownGenerator, Version=2.13.0.2212, Culture=neutral, PublicKeyToken=null. +## String from Array And Format - Documentation +This documentation file is auto generated by NodeDocumentationMarkdownGenerator, Version=3.4.0.6676, Culture=neutral, PublicKeyToken=null. For more information about adding documentation to nodes see https://github.com/DynamoDS/Dynamo/wiki/Create-and-Add-Custom-Documentation-to-Nodes diff --git a/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FromObject.md b/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.StringFromObject.md similarity index 63% rename from test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FromObject.md rename to test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.StringFromObject.md index 62127b5e2a0..e06e675cc6e 100644 --- a/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FromObject.md +++ b/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.StringFromObject.md @@ -1,5 +1,5 @@ -## String from Object - Documentation -This documentation file is auto generated by NodeDocumentationMarkdownGenerator, Version=2.13.0.2212, Culture=neutral, PublicKeyToken=null. +## String from Object And Format - Documentation +This documentation file is auto generated by NodeDocumentationMarkdownGenerator, Version=3.4.0.6676, Culture=neutral, PublicKeyToken=null. For more information about adding documentation to nodes see https://github.com/DynamoDS/Dynamo/wiki/Create-and-Add-Custom-Documentation-to-Nodes From 91b7147faa39e836cabfdc08f7880e2c9650013f Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" <508936+mjkkirschner@users.noreply.github.com> Date: Thu, 31 Oct 2024 20:41:13 -0400 Subject: [PATCH 11/22] test dynpref format --- .../ProtoTest/TD/MultiLangTests/StringTest.cs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/Engine/ProtoTest/TD/MultiLangTests/StringTest.cs b/test/Engine/ProtoTest/TD/MultiLangTests/StringTest.cs index 15406388892..ae2bc905365 100644 --- a/test/Engine/ProtoTest/TD/MultiLangTests/StringTest.cs +++ b/test/Engine/ProtoTest/TD/MultiLangTests/StringTest.cs @@ -607,5 +607,30 @@ public void TestStringFromObjectFormat() thisTest.Verify("b2", new string[]{"1.1","FFITarget.ClassFunctionality"}); thisTest.Verify("b3", new string[] { "101", "FFITarget.ClassFunctionality","Format specifier was invalid." }); } + [Test] + public void TestStringFromObjectFormat_Prefs1() + { + String code = + @" + b1 = __ToStringFromObjectAndFormat(1.123456789, ""DynamoPreferencesNumberFormat""); + "; + thisTest.RunScriptSource(code); + thisTest.Verify("b1", "1.123"); + } + [Test] + public void TestStringFromObjectFormat_Prefs2() + { + var oldpref = ProtoCore.Mirror.MirrorData.PrecisionFormat; + ProtoCore.Mirror.MirrorData.PrecisionFormat = "F6"; + String code = + @" + b1 = __ToStringFromObjectAndFormat(1.123456789, ""DynamoPreferencesNumberFormat""); + "; + thisTest.RunScriptSource(code); + thisTest.Verify("b1", "1.123457"); + //reset + ProtoCore.Mirror.MirrorData.PrecisionFormat = oldpref; + + } } } From c21ba952537639a3c591c964d4433e910f7c3449 Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" <508936+mjkkirschner@users.noreply.github.com> Date: Fri, 1 Nov 2024 13:57:06 -0400 Subject: [PATCH 12/22] check for warning state --- test/DynamoCoreTests/DSEvaluationUnitTestBase.cs | 7 ++++++- test/DynamoCoreTests/Nodes/StringTests.cs | 13 ++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/test/DynamoCoreTests/DSEvaluationUnitTestBase.cs b/test/DynamoCoreTests/DSEvaluationUnitTestBase.cs index 02e38cde2ce..2f8e3480d59 100644 --- a/test/DynamoCoreTests/DSEvaluationUnitTestBase.cs +++ b/test/DynamoCoreTests/DSEvaluationUnitTestBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -156,6 +156,11 @@ protected void AssertError(string guid) var node = GetModel().CurrentWorkspace.Nodes.First(n => n.GUID.ToString() == guid); Assert.True(node.IsInErrorState); } + protected void AssertWarning(string guid) + { + var node = GetModel().CurrentWorkspace.Nodes.First(n => n.GUID.ToString() == guid); + Assert.True(node.State is ElementState.Warning || node.State is ElementState.PersistentWarning); + } protected void AssertPreviewValue(string guid, object value) { diff --git a/test/DynamoCoreTests/Nodes/StringTests.cs b/test/DynamoCoreTests/Nodes/StringTests.cs index 520a4aa53b9..b91e55c8817 100644 --- a/test/DynamoCoreTests/Nodes/StringTests.cs +++ b/test/DynamoCoreTests/Nodes/StringTests.cs @@ -442,7 +442,7 @@ public void TestStringToNumberNormalInput() AssertPreviewValue("0afc0a8f-3d8a-4d7c-a2ec-d868cbb29b5f", 123456789); } [Test] - public void TestStringToNumber2() + public void TestStringToNumberWithFormat() { string testFilePath = Path.Combine(localDynamoStringTestFolder, "TestNumberToString_normal_numericFormat.dyn"); CurrentDynamoModel.PreferenceSettings.NumberFormat = "f1"; @@ -450,8 +450,12 @@ public void TestStringToNumber2() var watch0 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch0").FirstOrDefault().GUID.ToString(); var watch1 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch1").FirstOrDefault().GUID.ToString(); var watch2 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch2").FirstOrDefault().GUID.ToString(); + var watch3parent = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch3") + .FirstOrDefault().ImediateUpstreamNodes().FirstOrDefault().GUID.ToString(); var watch3 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch3").FirstOrDefault().GUID.ToString(); var watch4 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch4").FirstOrDefault().GUID.ToString(); + var watch4parent = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch4") + .FirstOrDefault().ImediateUpstreamNodes().FirstOrDefault().GUID.ToString(); var watch5 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch5").FirstOrDefault().GUID.ToString(); var watch6 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch6").FirstOrDefault().GUID.ToString(); var watch7 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch7").FirstOrDefault().GUID.ToString(); @@ -464,6 +468,9 @@ public void TestStringToNumber2() AssertPreviewValue(watch5, new string[] { "5.000", "5.0", "5", "101" }); AssertPreviewValue(watch6, new string[] { "{key:0.000000000}", "{key:0.000000000}", "{key:0.000000000}", "{key:0.000000000}" }); AssertPreviewValue(watch7, new string[] { "{key:5}", "{key:5}", "{key:5}", "{key:5}" }); + + AssertWarning(watch3parent); + AssertWarning(watch4parent); } #endregion @@ -894,10 +901,10 @@ public void TestStringFromArray() AssertPreviewValue("c27d9e05-45f7-4aac-8f53-a9e485e0f9c0", "[1,2,3]"); } [Test] - public void TestStringFromArray2() + public void TestStringFromArrayWithFormat() { string testFilePath = Path.Combine(localDynamoStringTestFolder, "TestStringFromArrayPreview_numericformat.dyn"); - //CurrentDynamoModel.PreferenceSettings.NumberFormat = "f1"; + RunModel(testFilePath); var watch1 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch1").FirstOrDefault().GUID.ToString(); var watch2 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch2").FirstOrDefault().GUID.ToString(); From 8236398adb58e079b9e0269142dd9ecd6e08a09b Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" <508936+mjkkirschner@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:28:24 -0500 Subject: [PATCH 13/22] add experimental flag to typeload data for node models add experimental flag to attr classes and func descriptor for ZT nodes add experimental flag to node model search elements and zt - skip custom node for now... change new node names change layoutspec for string --- src/DynamoCore/Graph/Nodes/TypeLoadData.cs | 9 +++++- src/DynamoCore/Library/FunctionDescriptor.cs | 31 ++++++++++++------- src/DynamoCore/Library/LibraryServices.cs | 3 +- .../NodeModelSearchElementBase.cs | 1 + .../SearchElements/NodeSearchElement.cs | 9 ++++++ .../SearchElements/ZeroTouchSearchElement.cs | 2 ++ src/Engine/ProtoCore/FFI/CLRDLLModule.cs | 8 +++++ src/Engine/ProtoCore/Parser/AssociativeAST.cs | 4 +++ src/Engine/ProtoCore/Utils/StringUtils.cs | 1 + src/Libraries/CoreNodeModels/String.cs | 20 ++++++------ .../Packages/LibrarieJS/layoutSpecs.json | 31 ++++++++++--------- 11 files changed, 81 insertions(+), 38 deletions(-) diff --git a/src/DynamoCore/Graph/Nodes/TypeLoadData.cs b/src/DynamoCore/Graph/Nodes/TypeLoadData.cs index 82dbca9e547..e2771910c12 100644 --- a/src/DynamoCore/Graph/Nodes/TypeLoadData.cs +++ b/src/DynamoCore/Graph/Nodes/TypeLoadData.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -95,6 +95,9 @@ public TypeLoadData(Type typeIn) OutputParameters = Type.GetCustomAttributes(false) .SelectMany(x => x.PortTypes); + + + IsExperimental = Type.GetCustomAttributes(false).Any(); } /// @@ -166,5 +169,9 @@ public string Category /// Indicates output parameters. /// public readonly IEnumerable OutputParameters; + /// + /// Is this type experimental/unstable. + /// + internal readonly bool IsExperimental; } } diff --git a/src/DynamoCore/Library/FunctionDescriptor.cs b/src/DynamoCore/Library/FunctionDescriptor.cs index b0233dc1f03..716f9df76e8 100644 --- a/src/DynamoCore/Library/FunctionDescriptor.cs +++ b/src/DynamoCore/Library/FunctionDescriptor.cs @@ -145,7 +145,12 @@ public FunctionDescriptorParams() /// /// Indicates if the lacing strategy is disabled on the function /// - public bool IsLacingDisabled { get; set; } + public bool IsLacingDisabled { get; set; } + //TODO - should this somehow contain more info - ExperimentalInfo{IsExperimental, ExperimentalMessage/url}?} + /// + /// Experimental/Unstable function + /// + internal bool IsExperimental { get; set; } } /// @@ -186,7 +191,7 @@ public FunctionDescriptor(FunctionDescriptorParams funcDescParams) var type = funcDescParams.FunctionType; var inputParameters = new List>(); //Add instance parameter as one of the inputs for instance method as well as properties. - if(type == FunctionType.InstanceMethod || type == FunctionType.InstanceProperty) + if (type == FunctionType.InstanceMethod || type == FunctionType.InstanceProperty) inputParameters.Add(Tuple.Create(UnqualifedClassName.ToLower(), UnqualifedClassName)); if (Parameters.Any()) @@ -196,7 +201,7 @@ public FunctionDescriptor(FunctionDescriptorParams funcDescParams) } InputParameters = inputParameters; - ReturnType = funcDescParams.ReturnType; + ReturnType = funcDescParams.ReturnType; Type = type; ReturnKeys = funcDescParams.ReturnKeys; IsVarArg = funcDescParams.IsVarArg; @@ -206,6 +211,7 @@ public FunctionDescriptor(FunctionDescriptorParams funcDescParams) IsBuiltIn = funcDescParams.IsBuiltIn; IsPackageMember = funcDescParams.IsPackageMember; IsLacingDisabled = funcDescParams.IsLacingDisabled; + IsExperimental = funcDescParams.IsExperimental; } /// @@ -320,28 +326,28 @@ public string Category { var categoryBuf = new StringBuilder(); categoryBuf.Append(GetRootCategory()); - + //if this is not BuiltIn function search NodeCategoryAttribute for it - if (ClassName!=null) + if (ClassName != null) { //get function assembly var asm = AppDomain.CurrentDomain.GetAssemblies() .Where(x => x.GetName().Name == Path.GetFileNameWithoutExtension(Assembly)) .ToArray(); - if (asm.Any() && asm.First().GetType(ClassName)!=null) + if (asm.Any() && asm.First().GetType(ClassName) != null) { //get class type of function var type = asm.First().GetType(ClassName); //get NodeCategoryAttribute for this function if it was been defined - var nodeCat = type.GetMethods().Where(x=>x.Name==FunctionName) - .Select(x => x.GetCustomAttribute(typeof (NodeCategoryAttribute))) - .Where(x=>x!=null) + var nodeCat = type.GetMethods().Where(x => x.Name == FunctionName) + .Select(x => x.GetCustomAttribute(typeof(NodeCategoryAttribute))) + .Where(x => x != null) .Cast() - .Select(x=>x.ElementCategory) + .Select(x => x.ElementCategory) .FirstOrDefault(); - + //if attribute is found compose node category string with last part from attribute if (!string.IsNullOrEmpty(nodeCat) && ( nodeCat == LibraryServices.Categories.Constructors @@ -353,7 +359,7 @@ public string Category } } } - + switch (Type) { case FunctionType.Constructor: @@ -567,5 +573,6 @@ private string GetRootCategory() return string.IsNullOrEmpty(Namespace) ? filename : filename + "." + Namespace; } + internal bool IsExperimental {get;} } } diff --git a/src/DynamoCore/Library/LibraryServices.cs b/src/DynamoCore/Library/LibraryServices.cs index 6b78418f09e..47c2ca7801c 100644 --- a/src/DynamoCore/Library/LibraryServices.cs +++ b/src/DynamoCore/Library/LibraryServices.cs @@ -1083,7 +1083,8 @@ private void ImportProcedure(string library, ProcedureNode proc) IsBuiltIn = pathManager.PreloadedLibraries.Contains(library) || library.StartsWith(PathManager.BuiltinPackagesDirectory), IsPackageMember = packagedLibraries.Contains(library), - IsLacingDisabled = isLacingDisabled + IsLacingDisabled = isLacingDisabled, + IsExperimental = (methodAttribute?.IsExperimental).GetValueOrDefault() || (classAttribute?.IsExperimental).GetValueOrDefault() }); AddImportedFunctions(library, new[] { function }); diff --git a/src/DynamoCore/Search/SearchElements/NodeModelSearchElementBase.cs b/src/DynamoCore/Search/SearchElements/NodeModelSearchElementBase.cs index 8ac8fa2943c..8bd914983f8 100644 --- a/src/DynamoCore/Search/SearchElements/NodeModelSearchElementBase.cs +++ b/src/DynamoCore/Search/SearchElements/NodeModelSearchElementBase.cs @@ -39,6 +39,7 @@ protected NodeModelSearchElementBase(TypeLoadData typeLoadData) { ElementType |= ElementTypes.BuiltIn; } + IsExperimental = typeLoadData.IsExperimental; } } } diff --git a/src/DynamoCore/Search/SearchElements/NodeSearchElement.cs b/src/DynamoCore/Search/SearchElements/NodeSearchElement.cs index 0d1751345d4..9e3521216c0 100644 --- a/src/DynamoCore/Search/SearchElements/NodeSearchElement.cs +++ b/src/DynamoCore/Search/SearchElements/NodeSearchElement.cs @@ -19,6 +19,7 @@ public abstract class NodeSearchElement : ISearchEntry, ISource, IClo private SearchElementGroup group; private string assembly; private bool isVisibleInSearch = true; + internal virtual bool IsExperimental { get; set; } internal AutoCompletionNodeElementInfo AutoCompletionNodeElementInfo { get; set; } = new AutoCompletionNodeElementInfo(); @@ -141,7 +142,15 @@ public string Description get { if (string.IsNullOrEmpty(description)) + { return Configurations.NoDescriptionAvailable; + } + if (IsExperimental) + { + //TODO localize + return "This node is marked experimental, it may change frequently!" + Environment.NewLine + Environment.NewLine + description; + } + return description; } diff --git a/src/DynamoCore/Search/SearchElements/ZeroTouchSearchElement.cs b/src/DynamoCore/Search/SearchElements/ZeroTouchSearchElement.cs index 9831ed8e4ac..59572a7419d 100644 --- a/src/DynamoCore/Search/SearchElements/ZeroTouchSearchElement.cs +++ b/src/DynamoCore/Search/SearchElements/ZeroTouchSearchElement.cs @@ -32,6 +32,8 @@ public class ZeroTouchSearchElement : NodeSearchElement /// internal FunctionDescriptor Descriptor => functionDescriptor; + internal override bool IsExperimental => functionDescriptor.IsExperimental; + /// /// Initializes a new instance of the class /// with the DesignScript function description diff --git a/src/Engine/ProtoCore/FFI/CLRDLLModule.cs b/src/Engine/ProtoCore/FFI/CLRDLLModule.cs index bdadb618a15..5321f4be7f7 100644 --- a/src/Engine/ProtoCore/FFI/CLRDLLModule.cs +++ b/src/Engine/ProtoCore/FFI/CLRDLLModule.cs @@ -1274,6 +1274,10 @@ public FFIClassAttributes(Type type) { PreferredShortName = (attr as PreferredShortNameAttribute).PreferredShortName; } + else if (attr is System.Diagnostics.CodeAnalysis.ExperimentalAttribute) + { + IsExperimental = true; + } } } } @@ -1432,6 +1436,10 @@ public FFIMethodAttributes(MethodBase method, Dictionary ReturnKeys /// public string Description { get; set; } + internal bool IsExperimental { get; set; } + + public MethodAttributes(bool hiddenInLibrary = false, bool canUpdatePeriodically = false, string msg = "") { HiddenInLibrary = hiddenInLibrary; diff --git a/src/Engine/ProtoCore/Utils/StringUtils.cs b/src/Engine/ProtoCore/Utils/StringUtils.cs index 80bd5a4dbb1..7ffbcd31e90 100644 --- a/src/Engine/ProtoCore/Utils/StringUtils.cs +++ b/src/Engine/ProtoCore/Utils/StringUtils.cs @@ -8,6 +8,7 @@ namespace ProtoCore.Utils { public static class StringUtils { + //TODO consider removing this option. It makes sharing harder. internal const string DynamoPreferencesNumberFormat = nameof(DynamoPreferencesNumberFormat); internal const string LEGACYFORMATTING = nameof(LEGACYFORMATTING); diff --git a/src/Libraries/CoreNodeModels/String.cs b/src/Libraries/CoreNodeModels/String.cs index 4cf0729afd0..dd743aac8d2 100644 --- a/src/Libraries/CoreNodeModels/String.cs +++ b/src/Libraries/CoreNodeModels/String.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Autodesk.DesignScript.Runtime; using CoreNodeModels.Properties; using Dynamo.Graph.Nodes; using Newtonsoft.Json; @@ -62,16 +61,17 @@ public override IEnumerable BuildOutputAst(List inPorts, IEnumerable outPorts) : + private FormattedStringFromObject(IEnumerable inPorts, IEnumerable outPorts) : base("__ToStringFromObjectAndFormat", inPorts, outPorts) { ArgumentLacing = LacingStrategy.Disabled; @@ -83,7 +83,7 @@ private StringFromObject(IEnumerable inPorts, IEnumerable } } - public StringFromObject() : base("__ToStringFromObjectAndFormat") + public FormattedStringFromObject() : base("__ToStringFromObjectAndFormat") { ArgumentLacing = LacingStrategy.Disabled; InPorts.Add(new PortModel(PortType.Input, this, new PortData("object", Resources.FromObjectPortDataObjToolTip))); @@ -123,17 +123,17 @@ public FromObject() : base("__ToStringFromObject") } } - [NodeName("String from Array And Format")] + [NodeName("Formatted String from Array")] [NodeDescription("StringfromArrayDescription", typeof(Resources))] [NodeCategory("Core.String.Actions")] [NodeSearchTags("FromArraySearchTags", typeof(Resources))] [OutPortTypes("string")] [IsDesignScriptCompatible] - [AlsoKnownAs("DSCoreNodesUI.StringNodes.FromArray", "DSCoreNodesUI.FromArray")] - public class StringFromArray : ToStringNodeBase + [System.Diagnostics.CodeAnalysis.Experimental("NEWNODE_FormattedStringFromArray")] + public class FormattedStringFromArray : ToStringNodeBase { [JsonConstructor] - private StringFromArray(IEnumerable inPorts, IEnumerable outPorts) : + private FormattedStringFromArray(IEnumerable inPorts, IEnumerable outPorts) : base("__ToStringFromArrayAndFormat", inPorts, outPorts) { ArgumentLacing = LacingStrategy.Disabled; @@ -145,7 +145,7 @@ private StringFromArray(IEnumerable inPorts, IEnumerable o } } - public StringFromArray() : base("__ToStringFromArrayAndFormat") + public FormattedStringFromArray() : base("__ToStringFromArrayAndFormat") { ArgumentLacing = LacingStrategy.Disabled; InPorts.Add(new PortModel(PortType.Input, this, new PortData("array", Resources.FromArrayPortDataArrayToolTip))); diff --git a/src/LibraryViewExtensionWebView2/Packages/LibrarieJS/layoutSpecs.json b/src/LibraryViewExtensionWebView2/Packages/LibrarieJS/layoutSpecs.json index 3b3baa4a8c6..4a8e3f6b74f 100644 --- a/src/LibraryViewExtensionWebView2/Packages/LibrarieJS/layoutSpecs.json +++ b/src/LibraryViewExtensionWebView2/Packages/LibrarieJS/layoutSpecs.json @@ -1311,20 +1311,23 @@ "text": "Generate", "iconUrl": "", "elementType": "group", - "include": [ - { - "path": "Core.String.String from Object" - }, - { - "path": "Core.String.String from Array" - }, - { - "path": "DSCoreNodes.DSCore.String.Concat" - }, - { - "path": "DSCoreNodes.DSCore.String.Join" - } - ], + "include": [ + { + "path": "Core.String.String from Object" + }, + { + "path": "Core.String.String from Array" + }, + { + "path": "DSCoreNodes.DSCore.String.Concat" + }, + { + "path": "DSCoreNodes.DSCore.String.Join" + }, + { + "path": "Core.String" + }, + ], "childElements": [] } ] From ad3ff1b3e9d0191f2c1df6cc27c4d70b4a95e718 Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" <508936+mjkkirschner@users.noreply.github.com> Date: Tue, 5 Nov 2024 11:32:56 -0500 Subject: [PATCH 14/22] fix docs tests --- .../MarkdownGeneratorCommandTests.cs | 2 +- ...gFromArray.md => CoreNodeModels.FormattedStringFromArray.md} | 0 ...romObject.md => CoreNodeModels.FormattedStringFromObject.md} | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/{CoreNodeModels.StringFromArray.md => CoreNodeModels.FormattedStringFromArray.md} (100%) rename test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/{CoreNodeModels.StringFromObject.md => CoreNodeModels.FormattedStringFromObject.md} (85%) diff --git a/test/Tools/NodeDocumentationMarkdownGeneratorTests/MarkdownGeneratorCommandTests.cs b/test/Tools/NodeDocumentationMarkdownGeneratorTests/MarkdownGeneratorCommandTests.cs index 67dceab776f..33cadecacdf 100644 --- a/test/Tools/NodeDocumentationMarkdownGeneratorTests/MarkdownGeneratorCommandTests.cs +++ b/test/Tools/NodeDocumentationMarkdownGeneratorTests/MarkdownGeneratorCommandTests.cs @@ -226,7 +226,7 @@ public void DictionaryContentIsFoundCorrectlyForCoreNodes() // Arrange var testOutputDirName = "TestMdOutput_CoreNodeModels"; //these are new files/nodes so there is no dictionary content fo them. - var filesToSkip = new string[] { "CoreNodeModels.StringFromArray", "CoreNodeModels.StringFromObject" }; + var filesToSkip = new string[] { "CoreNodeModels.FormattedStringFromObject", "CoreNodeModels.FormattedStringFromArray" }; var coreNodeModelsDll = Path.Combine(DynamoCoreNodesDir, CORENODEMODELS_DLL_NAME); Assert.That(File.Exists(coreNodeModelsDll)); diff --git a/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.StringFromArray.md b/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FormattedStringFromArray.md similarity index 100% rename from test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.StringFromArray.md rename to test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FormattedStringFromArray.md diff --git a/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.StringFromObject.md b/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FormattedStringFromObject.md similarity index 85% rename from test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.StringFromObject.md rename to test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FormattedStringFromObject.md index e06e675cc6e..1b39c296071 100644 --- a/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.StringFromObject.md +++ b/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FormattedStringFromObject.md @@ -1,4 +1,4 @@ -## String from Object And Format - Documentation +## Formatted String From Object - Documentation This documentation file is auto generated by NodeDocumentationMarkdownGenerator, Version=3.4.0.6676, Culture=neutral, PublicKeyToken=null. For more information about adding documentation to nodes see https://github.com/DynamoDS/Dynamo/wiki/Create-and-Add-Custom-Documentation-to-Nodes From f90f12e81dbed1c0a0cf2923bd2d848ae1388e39 Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" <508936+mjkkirschner@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:04:58 -0500 Subject: [PATCH 15/22] update node names from review comments --- .../TestNumberToString_normal_numericformat.dyn | 16 ++++++++-------- .../TestStringFromArrayPreview_numericformat.dyn | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/test/core/string/TestNumberToString_normal_numericformat.dyn b/test/core/string/TestNumberToString_normal_numericformat.dyn index dfb93e2d04a..bfc672d6e60 100644 --- a/test/core/string/TestNumberToString_normal_numericformat.dyn +++ b/test/core/string/TestNumberToString_normal_numericformat.dyn @@ -192,7 +192,7 @@ "Description": "Visualizes a node's output" }, { - "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "ConcreteType": "CoreNodeModels.FormattedStringFromObject, CoreNodeModels", "Id": "680caae1a3ea4095803b2493571cce7a", "NodeType": "ExtensionNode", "Inputs": [ @@ -352,7 +352,7 @@ "Code": "{\"key\":\"5\"};" }, { - "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "ConcreteType": "CoreNodeModels.FormattedStringFromObject, CoreNodeModels", "Id": "f776aa328bd043ee8ec082b49bffe6a3", "NodeType": "ExtensionNode", "Inputs": [ @@ -441,7 +441,7 @@ "Code": "5;" }, { - "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "ConcreteType": "CoreNodeModels.FormattedStringFromObject, CoreNodeModels", "Id": "9c16d38e96ad477dab6fad80d8f28f74", "NodeType": "ExtensionNode", "Inputs": [ @@ -479,7 +479,7 @@ "Description": "Converts an object to a string representation" }, { - "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "ConcreteType": "CoreNodeModels.FormattedStringFromObject, CoreNodeModels", "Id": "2451b0dca8e54fa98c17fbb6f5aa9c80", "NodeType": "ExtensionNode", "Inputs": [ @@ -517,7 +517,7 @@ "Description": "Converts an object to a string representation" }, { - "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "ConcreteType": "CoreNodeModels.FormattedStringFromObject, CoreNodeModels", "Id": "c8801f22da1943cab36bd03806cc20cd", "NodeType": "ExtensionNode", "Inputs": [ @@ -555,7 +555,7 @@ "Description": "Converts an object to a string representation" }, { - "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "ConcreteType": "CoreNodeModels.FormattedStringFromObject, CoreNodeModels", "Id": "1bbe9fbe696945ab801c0428693a34c1", "NodeType": "ExtensionNode", "Inputs": [ @@ -593,7 +593,7 @@ "Description": "Converts an object to a string representation" }, { - "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "ConcreteType": "CoreNodeModels.FormattedStringFromObject, CoreNodeModels", "Id": "2194d136e214459b8d04f11e5d39f0db", "NodeType": "ExtensionNode", "Inputs": [ @@ -652,7 +652,7 @@ "InputValue": 123456789.0 }, { - "ConcreteType": "CoreNodeModels.StringFromObject, CoreNodeModels", + "ConcreteType": "CoreNodeModels.FormattedStringFromObject, CoreNodeModels", "Id": "df29ded8e49c4755be88d57e4bda23d9", "NodeType": "ExtensionNode", "Inputs": [ diff --git a/test/core/string/TestStringFromArrayPreview_numericformat.dyn b/test/core/string/TestStringFromArrayPreview_numericformat.dyn index d4dabeccd35..bfdad40e514 100644 --- a/test/core/string/TestStringFromArrayPreview_numericformat.dyn +++ b/test/core/string/TestStringFromArrayPreview_numericformat.dyn @@ -2,7 +2,7 @@ "Uuid": "45732322-5b7c-4527-a7ff-2181708d3c04", "IsCustomNode": false, "Description": null, - "Name": "TestStringFromArrayPreview_numericformat", + "Name": "TestFormattedStringFromArrayPreview_numericformat", "ElementResolver": { "ResolutionMap": {} }, @@ -110,7 +110,7 @@ "Code": "[\"F1\",\"G\",\"B\"];" }, { - "ConcreteType": "CoreNodeModels.StringFromArray, CoreNodeModels", + "ConcreteType": "CoreNodeModels.FormattedStringFromArray, CoreNodeModels", "Id": "74f97ab047fa49eaaa8d77271ecb87e0", "NodeType": "ExtensionNode", "Inputs": [ @@ -241,7 +241,7 @@ "Description": "Visualizes a node's output" }, { - "ConcreteType": "CoreNodeModels.StringFromArray, CoreNodeModels", + "ConcreteType": "CoreNodeModels.FormattedStringFromArray, CoreNodeModels", "Id": "96271f95253f4524a95db2d7400c4f52", "NodeType": "ExtensionNode", "Inputs": [ @@ -279,7 +279,7 @@ "Description": "Converts an array to a string representation" }, { - "ConcreteType": "CoreNodeModels.StringFromArray, CoreNodeModels", + "ConcreteType": "CoreNodeModels.FormattedStringFromArray, CoreNodeModels", "Id": "24cdee3feeb04e09bcad4b0078581347", "NodeType": "ExtensionNode", "Inputs": [ From 6d6f5882e6c334689bfa75f04966adeca3fb9122 Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" <508936+mjkkirschner@users.noreply.github.com> Date: Wed, 6 Nov 2024 12:26:09 -0500 Subject: [PATCH 16/22] docs --- ...CoreNodeModels.FormattedStringFromArray.md | 17 ++++++ ...oreNodeModels.FormattedStringFromObject.md | 17 ++++++ .../Properties/Resources.Designer.cs | 12 ++++- .../Properties/Resources.en-US.resx | 6 ++- .../CoreNodeModels/Properties/Resources.resx | 6 ++- src/Libraries/CoreNodeModels/String.cs | 54 ++++++++++--------- test/DynamoCoreTests/Nodes/StringTests.cs | 4 +- 7 files changed, 85 insertions(+), 31 deletions(-) create mode 100644 doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromArray.md create mode 100644 doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromObject.md diff --git a/doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromArray.md b/doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromArray.md new file mode 100644 index 00000000000..ad28ddf72df --- /dev/null +++ b/doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromArray.md @@ -0,0 +1,17 @@ +## In Depth +This node will convert an oject to a string. The second input `format specifier` controls how numeric inputs are converted to their string representations. +This `format specifier` inputs should be one of the c# standard format numeric specifiers. + +format specifiers should be in the form: +`` for example F1 + +Some commonly used format specifiers are: +``` +G : general formatting G 1000.0 -> "1000" +F : fixed point notation F4 1000.0 -> "1.0000" +N : number N 1.0 -> 1000 -> "1,000.00" +``` + +The default for this node is `G`, which will output a compact, but variable representation. + +[see the microsoft documentation for more detailed information.](https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings#standard-format-specifiers) \ No newline at end of file diff --git a/doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromObject.md b/doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromObject.md new file mode 100644 index 00000000000..ad28ddf72df --- /dev/null +++ b/doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromObject.md @@ -0,0 +1,17 @@ +## In Depth +This node will convert an oject to a string. The second input `format specifier` controls how numeric inputs are converted to their string representations. +This `format specifier` inputs should be one of the c# standard format numeric specifiers. + +format specifiers should be in the form: +`` for example F1 + +Some commonly used format specifiers are: +``` +G : general formatting G 1000.0 -> "1000" +F : fixed point notation F4 1000.0 -> "1.0000" +N : number N 1.0 -> 1000 -> "1,000.00" +``` + +The default for this node is `G`, which will output a compact, but variable representation. + +[see the microsoft documentation for more detailed information.](https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings#standard-format-specifiers) \ No newline at end of file diff --git a/src/Libraries/CoreNodeModels/Properties/Resources.Designer.cs b/src/Libraries/CoreNodeModels/Properties/Resources.Designer.cs index 72bb75bd24a..42645747738 100644 --- a/src/Libraries/CoreNodeModels/Properties/Resources.Designer.cs +++ b/src/Libraries/CoreNodeModels/Properties/Resources.Designer.cs @@ -1,4 +1,4 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 @@ -655,6 +655,16 @@ public static string FromArraySearchTags { } } + /// + /// Looks up a localized string similar to Format specifier for numeric values, see extended node help for more info. + ///default value: G. (general formatting) + /// + public static string FromObjectPortDataFormatToolTip { + get { + return ResourceManager.GetString("FromObjectPortDataFormatToolTip", resourceCulture); + } + } + /// /// Looks up a localized string similar to Object to be serialized. /// diff --git a/src/Libraries/CoreNodeModels/Properties/Resources.en-US.resx b/src/Libraries/CoreNodeModels/Properties/Resources.en-US.resx index dcf7a16c40f..b11d5b442f1 100644 --- a/src/Libraries/CoreNodeModels/Properties/Resources.en-US.resx +++ b/src/Libraries/CoreNodeModels/Properties/Resources.en-US.resx @@ -676,4 +676,8 @@ In Generative Design workflows, this node should be used to control and block th Select Types - + + Format specifier for numeric values, see extended node help for more info. +default value: G + + \ No newline at end of file diff --git a/src/Libraries/CoreNodeModels/Properties/Resources.resx b/src/Libraries/CoreNodeModels/Properties/Resources.resx index aa29f8e175d..ce2eb25174b 100644 --- a/src/Libraries/CoreNodeModels/Properties/Resources.resx +++ b/src/Libraries/CoreNodeModels/Properties/Resources.resx @@ -676,4 +676,8 @@ In Generative Design workflows, this node should be used to control and block th Select Types - + + Format specifier for numeric values, see extended node help for more info. +default value: G + + \ No newline at end of file diff --git a/src/Libraries/CoreNodeModels/String.cs b/src/Libraries/CoreNodeModels/String.cs index dd743aac8d2..3a02b915a39 100644 --- a/src/Libraries/CoreNodeModels/String.cs +++ b/src/Libraries/CoreNodeModels/String.cs @@ -65,9 +65,14 @@ public override IEnumerable BuildOutputAst(List inPorts, IEnumerable 1) { - inPorts.ElementAt(1).DefaultValue = AstFactory.BuildStringNode("F6"); + inPorts.ElementAt(1).DefaultValue = AstFactory.BuildStringNode("G"); } } public FormattedStringFromObject() : base("__ToStringFromObjectAndFormat") { ArgumentLacing = LacingStrategy.Disabled; - InPorts.Add(new PortModel(PortType.Input, this, new PortData("object", Resources.FromObjectPortDataObjToolTip))); - InPorts.Add(new PortModel(PortType.Input, this, - new PortData("formatSpecifier", - //TODO add more info here in localized form. - "format specifier for numeric values", - AstFactory.BuildStringNode("F6")))); - OutPorts.Add(new PortModel(PortType.Output, this, new PortData("string", Resources.FromObjectPortDataResultToolTip))); + //TODO figure out how to add an inportDefaultValue attribute. + //it's not straightforward because ideally we'd have accesss to the parser. + if (InPorts?.Count() > 1) + { + InPorts.ElementAt(1).DefaultValue = AstFactory.BuildStringNode("G"); + InPorts.ElementAt(1).UsingDefaultValue = true; + } RegisterAllPorts(); } } @@ -104,8 +107,6 @@ public FormattedStringFromObject() : base("__ToStringFromObjectAndFormat") [OutPortTypes("string")] [IsDesignScriptCompatible] [AlsoKnownAs("DSCoreNodesUI.StringNodes.FromObject", "DSCoreNodesUI.FromObject")] - [Obsolete("this node is obsolete, please use the version of string from _ with numeric format option")] - [NodeDeprecated] public class FromObject: ToStringNodeBase { [JsonConstructor] @@ -127,9 +128,14 @@ public FromObject() : base("__ToStringFromObject") [NodeDescription("StringfromArrayDescription", typeof(Resources))] [NodeCategory("Core.String.Actions")] [NodeSearchTags("FromArraySearchTags", typeof(Resources))] - [OutPortTypes("string")] [IsDesignScriptCompatible] [System.Diagnostics.CodeAnalysis.Experimental("NEWNODE_FormattedStringFromArray")] + [InPortNames("object", "formatSpecifier")] + [InPortTypes("var", "string")] + [InPortDescriptions(typeof(Resources), "FromArrayPortDataArrayToolTip", "FromObjectPortDataFormatToolTip")] + [OutPortNames("string")] + [OutPortTypes("string")] + [OutPortDescriptions(typeof(Resources),"FromArrayPortDataResultToolTip")] public class FormattedStringFromArray : ToStringNodeBase { [JsonConstructor] @@ -137,25 +143,23 @@ private FormattedStringFromArray(IEnumerable inPorts, IEnumerable 1) { - inPorts.ElementAt(1).DefaultValue = AstFactory.BuildStringNode("F6"); + inPorts.ElementAt(1).DefaultValue = AstFactory.BuildStringNode("G"); } } public FormattedStringFromArray() : base("__ToStringFromArrayAndFormat") { ArgumentLacing = LacingStrategy.Disabled; - InPorts.Add(new PortModel(PortType.Input, this, new PortData("array", Resources.FromArrayPortDataArrayToolTip))); - InPorts.Add(new PortModel(PortType.Input, this, - new PortData("formatSpecifier", - //TODO add more info here in localized form. - "format specifier for numeric values", - AstFactory.BuildStringNode("F6")))); - OutPorts.Add(new PortModel(PortType.Output, this, new PortData("string", Resources.FromArrayPortDataResultToolTip))); RegisterAllPorts(); + //TODO figure out how to add an inportDefaultValue attribute. + //it's not straightforward because ideally we'd have accesss to the parser. + if (InPorts?.Count() > 1) + { + InPorts.ElementAt(1).DefaultValue = AstFactory.BuildStringNode("G"); + InPorts.ElementAt(1).UsingDefaultValue = true; + } } } @@ -166,8 +170,6 @@ public FormattedStringFromArray() : base("__ToStringFromArrayAndFormat") [OutPortTypes("string")] [IsDesignScriptCompatible] [AlsoKnownAs("DSCoreNodesUI.StringNodes.FromArray", "DSCoreNodesUI.FromArray")] - [Obsolete("TODO update to resx - please use string from object overload with numeric format option")] - [NodeDeprecated] public class FromArray : ToStringNodeBase { [JsonConstructor] diff --git a/test/DynamoCoreTests/Nodes/StringTests.cs b/test/DynamoCoreTests/Nodes/StringTests.cs index b91e55c8817..77cad9ec491 100644 --- a/test/DynamoCoreTests/Nodes/StringTests.cs +++ b/test/DynamoCoreTests/Nodes/StringTests.cs @@ -460,7 +460,7 @@ public void TestStringToNumberWithFormat() var watch6 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch6").FirstOrDefault().GUID.ToString(); var watch7 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch7").FirstOrDefault().GUID.ToString(); - AssertPreviewValue(watch0, "123456789.000000"); + AssertPreviewValue(watch0, "123456789"); AssertPreviewValue(watch1, new string[]{ "123456789.000", "123456789.0", "123456789", "111010110111100110100010101" }); AssertPreviewValue(watch2, new string[] { "-123456789.000", "-123456789.0", "-123456789", "1111111111111111111111111111111111111000101001000011001011101011" }); AssertPreviewValue(watch3, new string[] { "3.460", "3.5", "3.46", "Format specifier was invalid." }); @@ -912,7 +912,7 @@ public void TestStringFromArrayWithFormat() var watch4 = CurrentDynamoModel.CurrentWorkspace.Nodes.Where(x => x.Name.ToLower() == "watch4").FirstOrDefault().GUID.ToString(); AssertPreviewValue(watch1, "[1.000000,1.666667,2.333333,3.000000]"); - AssertPreviewValue(watch2, "[1.000000,1.666667,2.333333,3.000000]"); + AssertPreviewValue(watch2, "[1,1.6666666666666667,2.3333333333333335,3]"); AssertPreviewValue(watch3, new string[] { "[1.0,1.7,2.3,3.0]", "[1,1.6666666666666667,2.3333333333333335,3]", "Format specifier was invalid." }); AssertPreviewValue(watch4, "Function"); From 2f0692fa0de789ffdde3c318450306f24c4ea823 Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" <508936+mjkkirschner@users.noreply.github.com> Date: Wed, 6 Nov 2024 17:03:53 -0500 Subject: [PATCH 17/22] add experimental glyph on nodeview --- src/DynamoCore/Graph/Nodes/NodeModel.cs | 19 ++++++++++++++++++- src/DynamoCore/Graph/Nodes/TypeLoadData.cs | 7 +++++-- .../Properties/Resources.Designer.cs | 19 ++++++++++++++----- .../Properties/Resources.en-US.resx | 5 ++++- src/DynamoCore/Properties/Resources.resx | 5 ++++- .../SearchElements/NodeSearchElement.cs | 5 +++-- .../ViewModels/Core/NodeViewModel.cs | 17 ++++++++++++++--- src/DynamoCoreWpf/Views/Core/NodeView.xaml | 12 ++++++++++++ 8 files changed, 74 insertions(+), 15 deletions(-) diff --git a/src/DynamoCore/Graph/Nodes/NodeModel.cs b/src/DynamoCore/Graph/Nodes/NodeModel.cs index 8131c81469a..084a2dd8030 100644 --- a/src/DynamoCore/Graph/Nodes/NodeModel.cs +++ b/src/DynamoCore/Graph/Nodes/NodeModel.cs @@ -2,17 +2,18 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.Serialization; using System.Xml; -using Autodesk.DesignScript.Runtime; using Dynamo.Configuration; using Dynamo.Engine; using Dynamo.Engine.CodeGeneration; using Dynamo.Graph.Connectors; using Dynamo.Graph.Nodes.CustomNodes; +using Dynamo.Graph.Nodes.ZeroTouch; using Dynamo.Graph.Workspaces; using Dynamo.Migration; using Dynamo.Scheduler; @@ -2869,6 +2870,22 @@ public bool ShouldDisplayPreview protected bool ShouldDisplayPreviewCore { get; set; } + [Experimental("NM_ISEXPERIMENTAL_GLPYH")] + internal bool IsExperimental + { + get + { + //TODO switch on model type? + if (this is DSFunction ztnm) + { + return ztnm.Controller.Definition.IsExperimental; + } + else + { + return TypeLoadData.CheckExperimentalFromAttribute(GetType()); + } + } + } public event Action RenderPackagesUpdated; private void OnRenderPackagesUpdated(RenderPackageCache packages) diff --git a/src/DynamoCore/Graph/Nodes/TypeLoadData.cs b/src/DynamoCore/Graph/Nodes/TypeLoadData.cs index e2771910c12..6dc3ce431a7 100644 --- a/src/DynamoCore/Graph/Nodes/TypeLoadData.cs +++ b/src/DynamoCore/Graph/Nodes/TypeLoadData.cs @@ -95,9 +95,12 @@ public TypeLoadData(Type typeIn) OutputParameters = Type.GetCustomAttributes(false) .SelectMany(x => x.PortTypes); + IsExperimental = CheckExperimentalFromAttribute(Type); + } - - IsExperimental = Type.GetCustomAttributes(false).Any(); + internal static bool CheckExperimentalFromAttribute(System.Type type) + { + return type.GetCustomAttributes(false).Any(); } /// diff --git a/src/DynamoCore/Properties/Resources.Designer.cs b/src/DynamoCore/Properties/Resources.Designer.cs index 61cfe00c6b3..2a1d19e2f9d 100644 --- a/src/DynamoCore/Properties/Resources.Designer.cs +++ b/src/DynamoCore/Properties/Resources.Designer.cs @@ -1,4 +1,4 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 @@ -8,10 +8,10 @@ // //------------------------------------------------------------------------------ -namespace Dynamo.Properties -{ - - +namespace Dynamo.Properties { + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -497,6 +497,15 @@ public static string DllLoadException { } } + /// + /// Looks up a localized string similar to This node is marked experimental, its behavior, name, and signature may change!. + /// + public static string DocsExperimentalPrefixMessage { + get { + return ResourceManager.GetString("DocsExperimentalPrefixMessage", resourceCulture); + } + } + /// /// Looks up a localized string similar to Download latest version. /// diff --git a/src/DynamoCore/Properties/Resources.en-US.resx b/src/DynamoCore/Properties/Resources.en-US.resx index 6af0906a03e..9d22e892700 100644 --- a/src/DynamoCore/Properties/Resources.en-US.resx +++ b/src/DynamoCore/Properties/Resources.en-US.resx @@ -920,4 +920,7 @@ This package likely contains an assembly that is blocked. You will need to load default input name, rename me! - + + This node is marked experimental, its behavior, name, and signature may change! + + \ No newline at end of file diff --git a/src/DynamoCore/Properties/Resources.resx b/src/DynamoCore/Properties/Resources.resx index 0b04d7adc50..fad93c025fe 100644 --- a/src/DynamoCore/Properties/Resources.resx +++ b/src/DynamoCore/Properties/Resources.resx @@ -923,4 +923,7 @@ This package likely contains an assembly that is blocked. You will need to load default input name, rename me! - + + This node is marked experimental, its behavior, name, and signature may change! + + \ No newline at end of file diff --git a/src/DynamoCore/Search/SearchElements/NodeSearchElement.cs b/src/DynamoCore/Search/SearchElements/NodeSearchElement.cs index 9e3521216c0..d286e2ff02f 100644 --- a/src/DynamoCore/Search/SearchElements/NodeSearchElement.cs +++ b/src/DynamoCore/Search/SearchElements/NodeSearchElement.cs @@ -3,6 +3,7 @@ using System.Linq; using Dynamo.Configuration; using Dynamo.Graph.Nodes; +using Dynamo.Properties; namespace Dynamo.Search.SearchElements { @@ -147,8 +148,8 @@ public string Description } if (IsExperimental) { - //TODO localize - return "This node is marked experimental, it may change frequently!" + Environment.NewLine + Environment.NewLine + description; + return $"{Resources.DocsExperimentalPrefixMessage}" + + $"{Environment.NewLine}{Environment.NewLine}{description}"; } diff --git a/src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs b/src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs index e3c9a0eb99d..a2a2ec7df88 100644 --- a/src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs @@ -3,6 +3,7 @@ using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using System.Text.RegularExpressions; @@ -14,6 +15,7 @@ using Dynamo.Graph; using Dynamo.Graph.Nodes; using Dynamo.Graph.Nodes.CustomNodes; +using Dynamo.Graph.Nodes.ZeroTouch; using Dynamo.Graph.Workspaces; using Dynamo.Logging; using Dynamo.Models; @@ -269,7 +271,7 @@ public ElementState State { get { return nodeLogic.State; } } - + /// /// The total number of info/warnings/errors dismissed by the user on this node. /// This is displayed on the node by a little icon beside the Context Menu button. @@ -356,7 +358,7 @@ public bool IsInteractionEnabled get { return true; } } - [JsonProperty("ShowGeometry",Order = 6)] + [JsonProperty("ShowGeometry", Order = 6)] public bool IsVisible { get @@ -641,7 +643,16 @@ public bool IsFrozenExplicitly return false; } } - + [Experimental("NVM_ISEXPERIMENTAL_GLPYH")] + [JsonIgnore] + public bool IsExperimental + { + get + { + return NodeModel.IsExperimental; + } + } + /// /// A flag indicating whether the underlying NodeModel's IsFrozen property can be toggled. /// diff --git a/src/DynamoCoreWpf/Views/Core/NodeView.xaml b/src/DynamoCoreWpf/Views/Core/NodeView.xaml index 3febdf3b1e2..89d7716b8a1 100644 --- a/src/DynamoCoreWpf/Views/Core/NodeView.xaml +++ b/src/DynamoCoreWpf/Views/Core/NodeView.xaml @@ -5,7 +5,9 @@ xmlns:ui="clr-namespace:Dynamo.UI" xmlns:dynui="clr-namespace:Dynamo.UI.Controls" xmlns:p="clr-namespace:Dynamo.Wpf.Properties" + xmlns:dp="clr-namespace:Dynamo.Properties;assembly=DynamoCore" xmlns:controls="clr-namespace:Dynamo.Views" + xmlns:fa="clr-namespace:FontAwesome5;assembly=FontAwesome5.Net" xmlns:dp1="clr-namespace:Dynamo.Properties;assembly=DynamoCore" Name="topControl" Width="Auto" Height="Auto" @@ -449,6 +451,16 @@ Style="{StaticResource SZoomFadeOutFrameworkElement}" FlowDirection="LeftToRight" Orientation="Horizontal"> + + + Date: Thu, 7 Nov 2024 12:00:09 -0500 Subject: [PATCH 18/22] this works to set experimental namespaces as experimetnal --- .../Configuration/PreferenceSettings.cs | 12 +++++++----- src/DynamoCore/Graph/Nodes/TypeLoadData.cs | 2 +- src/DynamoCore/Library/FunctionDescriptor.cs | 2 +- src/DynamoCore/Library/LibraryServices.cs | 18 ++++++++++++++++-- src/DynamoCore/Models/DynamoModel.cs | 5 +++++ 5 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/DynamoCore/Configuration/PreferenceSettings.cs b/src/DynamoCore/Configuration/PreferenceSettings.cs index 6b42daeecaf..c221d401e92 100644 --- a/src/DynamoCore/Configuration/PreferenceSettings.cs +++ b/src/DynamoCore/Configuration/PreferenceSettings.cs @@ -112,6 +112,12 @@ private readonly static Lazy /// public static readonly DateTime DynamoDefaultTime = new DateTime(1977, 4, 12, 12, 12, 0, 0); + internal static readonly IEnumerable InitialExperimentalLib_Namespaces = + [ + //TODO remove tsplines - it's no longer experimental. + "ProtoGeometry.dll:Autodesk.DesignScript.Geometry.TSpline", + "ProtoGeometry.dll:Autodesk.DesignScript.Geometry.PanelSurface" + ]; #endregion // The following settings are persistent between Dynamo sessions and are user-controllable @@ -1186,11 +1192,7 @@ internal void InitializeNamespacesToExcludeFromLibrary() { if (!NamespacesToExcludeFromLibrarySpecified) { - NamespacesToExcludeFromLibrary = new List() - { - "ProtoGeometry.dll:Autodesk.DesignScript.Geometry.TSpline", - "ProtoGeometry.dll:Autodesk.DesignScript.Geometry.PanelSurface" - }; + NamespacesToExcludeFromLibrary = InitialExperimentalLib_Namespaces.ToList(); NamespacesToExcludeFromLibrarySpecified = true; } } diff --git a/src/DynamoCore/Graph/Nodes/TypeLoadData.cs b/src/DynamoCore/Graph/Nodes/TypeLoadData.cs index 6dc3ce431a7..06d2cf0df42 100644 --- a/src/DynamoCore/Graph/Nodes/TypeLoadData.cs +++ b/src/DynamoCore/Graph/Nodes/TypeLoadData.cs @@ -175,6 +175,6 @@ public string Category /// /// Is this type experimental/unstable. /// - internal readonly bool IsExperimental; + internal bool IsExperimental; } } diff --git a/src/DynamoCore/Library/FunctionDescriptor.cs b/src/DynamoCore/Library/FunctionDescriptor.cs index 716f9df76e8..8e23bd3b720 100644 --- a/src/DynamoCore/Library/FunctionDescriptor.cs +++ b/src/DynamoCore/Library/FunctionDescriptor.cs @@ -573,6 +573,6 @@ private string GetRootCategory() return string.IsNullOrEmpty(Namespace) ? filename : filename + "." + Namespace; } - internal bool IsExperimental {get;} + internal bool IsExperimental { get; set; } } } diff --git a/src/DynamoCore/Library/LibraryServices.cs b/src/DynamoCore/Library/LibraryServices.cs index 47c2ca7801c..014d1d49197 100644 --- a/src/DynamoCore/Library/LibraryServices.cs +++ b/src/DynamoCore/Library/LibraryServices.cs @@ -1084,12 +1084,26 @@ private void ImportProcedure(string library, ProcedureNode proc) || library.StartsWith(PathManager.BuiltinPackagesDirectory), IsPackageMember = packagedLibraries.Contains(library), IsLacingDisabled = isLacingDisabled, - IsExperimental = (methodAttribute?.IsExperimental).GetValueOrDefault() || (classAttribute?.IsExperimental).GetValueOrDefault() + IsExperimental = (methodAttribute?.IsExperimental).GetValueOrDefault()|| (classAttribute?.IsExperimental).GetValueOrDefault() }); - + //TODO //consider moving to funcdescriptor constructor. + if(CheckIfFunctionIsMarkedExperimentalByPrefs(function)) + { + function.IsExperimental = true; + } AddImportedFunctions(library, new[] { function }); } + private bool CheckIfFunctionIsMarkedExperimentalByPrefs(FunctionDescriptor fd) + { + if (PreferenceSettings.InitialExperimentalLib_Namespaces. + Where(x => x.StartsWith(fd.Assembly+":")).Select(x=>x.Split(":").LastOrDefault()).Any(nsp=>fd.QualifiedName.StartsWith(nsp))) + { + return true; + } + return false; + } + private void ImportClass(string library, ClassNode classNode) { foreach (ProcedureNode proc in classNode.ProcTable.Procedures) diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index c1b267cd378..349ceb8a112 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -3399,6 +3399,11 @@ private NodeModelSearchElement AddNodeTypeToSearch(TypeLoadData typeLoadData) { return null; } + if(PreferenceSettings.InitialExperimentalLib_Namespaces. + Select(x => x.Split(":").LastOrDefault()).Any(x => x.Contains(typeLoadData.Category))){ + //TODO safer way to set this? + typeLoadData.IsExperimental = true; + } var node = new NodeModelSearchElement(typeLoadData); SearchModel?.Add(node); From 81d0400e08b98cd3748e3410594b41a4349aaa99 Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" <508936+mjkkirschner@users.noreply.github.com> Date: Thu, 7 Nov 2024 17:46:13 -0500 Subject: [PATCH 19/22] add feature flag check for ui review comments --- src/DynamoCore/Library/FunctionDescriptor.cs | 15 +++++++- src/DynamoCore/Library/LibraryServices.cs | 15 -------- .../ViewModels/Core/NodeViewModel.cs | 2 +- .../ProtoCore/DSASM/Mirror/ExecutionMirror.cs | 8 +--- src/Engine/ProtoCore/Utils/StringUtils.cs | 33 +++-------------- .../DynamoCoreTests/ExperimentalNodesTests.cs | 37 +++++++++++++++++++ test/DynamoCoreTests/LibraryTests.cs | 20 +++++++++- test/DynamoCoreTests/Nodes/StringTests.cs | 14 +++++++ test/Engine/FFITarget/ExperimentalNodes.cs | 24 ++++++++++++ 9 files changed, 114 insertions(+), 54 deletions(-) create mode 100644 test/DynamoCoreTests/ExperimentalNodesTests.cs create mode 100644 test/Engine/FFITarget/ExperimentalNodes.cs diff --git a/src/DynamoCore/Library/FunctionDescriptor.cs b/src/DynamoCore/Library/FunctionDescriptor.cs index 8e23bd3b720..15d3dc83ef4 100644 --- a/src/DynamoCore/Library/FunctionDescriptor.cs +++ b/src/DynamoCore/Library/FunctionDescriptor.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Reflection; using System.Text; +using Dynamo.Configuration; using Dynamo.Graph.Nodes; using Dynamo.Interfaces; using Dynamo.Library; @@ -211,7 +212,7 @@ public FunctionDescriptor(FunctionDescriptorParams funcDescParams) IsBuiltIn = funcDescParams.IsBuiltIn; IsPackageMember = funcDescParams.IsPackageMember; IsLacingDisabled = funcDescParams.IsLacingDisabled; - IsExperimental = funcDescParams.IsExperimental; + IsExperimental = funcDescParams.IsExperimental || CheckIfFunctionIsMarkedExperimentalByPrefs(this); } /// @@ -573,6 +574,16 @@ private string GetRootCategory() return string.IsNullOrEmpty(Namespace) ? filename : filename + "." + Namespace; } - internal bool IsExperimental { get; set; } + private bool CheckIfFunctionIsMarkedExperimentalByPrefs(FunctionDescriptor fd) + { + if (PreferenceSettings.InitialExperimentalLib_Namespaces. + Where(x => x.StartsWith(fd.Assembly + ":")).Select(x => x.Split(":").LastOrDefault()).Any(nsp => fd.QualifiedName.StartsWith(nsp))) + { + return true; + } + return false; + } + internal bool IsExperimental { get;} } + } diff --git a/src/DynamoCore/Library/LibraryServices.cs b/src/DynamoCore/Library/LibraryServices.cs index 014d1d49197..f48cf117c20 100644 --- a/src/DynamoCore/Library/LibraryServices.cs +++ b/src/DynamoCore/Library/LibraryServices.cs @@ -1086,24 +1086,9 @@ private void ImportProcedure(string library, ProcedureNode proc) IsLacingDisabled = isLacingDisabled, IsExperimental = (methodAttribute?.IsExperimental).GetValueOrDefault()|| (classAttribute?.IsExperimental).GetValueOrDefault() }); - //TODO //consider moving to funcdescriptor constructor. - if(CheckIfFunctionIsMarkedExperimentalByPrefs(function)) - { - function.IsExperimental = true; - } AddImportedFunctions(library, new[] { function }); } - private bool CheckIfFunctionIsMarkedExperimentalByPrefs(FunctionDescriptor fd) - { - if (PreferenceSettings.InitialExperimentalLib_Namespaces. - Where(x => x.StartsWith(fd.Assembly+":")).Select(x=>x.Split(":").LastOrDefault()).Any(nsp=>fd.QualifiedName.StartsWith(nsp))) - { - return true; - } - return false; - } - private void ImportClass(string library, ClassNode classNode) { foreach (ProcedureNode proc in classNode.ProcTable.Procedures) diff --git a/src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs b/src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs index a2a2ec7df88..e45034ac7e0 100644 --- a/src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs @@ -649,7 +649,7 @@ public bool IsExperimental { get { - return NodeModel.IsExperimental; + return NodeModel.IsExperimental && (DynamoModel.FeatureFlags?.CheckFeatureFlag("experimentalGlyphIsVisible", false) ?? false); } } diff --git a/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs b/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs index b4297e44b9e..9de47eb8bd4 100644 --- a/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs +++ b/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs @@ -54,7 +54,7 @@ public ExecutionMirror(ProtoCore.DSASM.Executive exec, ProtoCore.RuntimeCore cor /// /// /// - public string GetStringValueUsingFormat(StackValue val,string formatSpecifier, Heap heap, int langblock, bool forPrint = false) + internal string GetStringValueUsingFormat(StackValue val,string formatSpecifier, Heap heap, int langblock, bool forPrint = false) { return GetStringValueImplementation(val,formatSpecifier, heap, langblock, -1, -1, forPrint); } @@ -112,11 +112,6 @@ private string GetStringValueImplementation(StackValue val, string formatSpecifi { return val.IntegerValue.ToString(); } - //TODO I am not sure if it's best to just return null or some message here - //or if we should catch the error higher up where we can log a runtime warning. - //currently we are doing the latter. - - //return val.IntegerValue.SafeToStringWithFormat(formatSpecifier); return val.IntegerValue.ToString(formatSpecifier); } @@ -128,7 +123,6 @@ private string GetStringValueImplementation(StackValue val, string formatSpecifi { return val.DoubleValue.ToString("F6"); } - //return val.DoubleValue.SafeToStringWithFormat(formatSpecifier); return val.DoubleValue.ToString(formatSpecifier); } diff --git a/src/Engine/ProtoCore/Utils/StringUtils.cs b/src/Engine/ProtoCore/Utils/StringUtils.cs index 7ffbcd31e90..0fcdbcde9f4 100644 --- a/src/Engine/ProtoCore/Utils/StringUtils.cs +++ b/src/Engine/ProtoCore/Utils/StringUtils.cs @@ -25,26 +25,6 @@ public static int CompareString(StackValue s1, StackValue s2, RuntimeCore runtim return string.Compare(str1, str2); } - /// - /// Wraps ToString(format) in a try catch. Will return empty string if format is not valid for the target type. - /// - /// - /// - /// - /// Will return empty string if format is not valid for the target type. - internal static string SafeToStringWithFormat(this T target, string Format) - where T : IFormattable - { - try - { - return target.ToString(Format, null); - } - catch - { - return string.Empty; - } - } - public static string GetStringValue(StackValue sv, RuntimeCore runtimeCore) { ProtoCore.DSASM.Mirror.ExecutionMirror mirror = new DSASM.Mirror.ExecutionMirror(new ProtoCore.DSASM.Executive(runtimeCore), runtimeCore); @@ -60,13 +40,12 @@ public static StackValue ConvertToString(StackValue sv, RuntimeCore runtimeCore, //used by new ToString methods with format specifier. internal static StackValue ConvertToString(IEnumerable args, RuntimeCore runtimeCore, ProtoCore.Runtime.RuntimeMemory rmem) { - //TODO dislike this as a default... - var formatSpecifier = DynamoPreferencesNumberFormat; - var sv = args.ElementAt(0); - if (args.Count() > 1) - { //TODO performance concern? - formatSpecifier = GetStringValue(args.ElementAt(1),runtimeCore); + if (args.Count() < 2) + { + throw new ArgumentException($"format specifier argument not defined while converting string, please report!"); } + var sv = args.ElementAt(0); + var formatSpecifier = GetStringValue(args.ElementAt(1),runtimeCore); return ConvertToStringInternal(sv, runtimeCore, formatSpecifier); } @@ -89,8 +68,6 @@ private static StackValue ConvertToStringInternal(StackValue sv, RuntimeCore run return returnSV; } - - public static StackValue ConcatString(StackValue op1, StackValue op2, RuntimeCore runtimeCore) { var v1 = runtimeCore.RuntimeMemory.Heap.ToHeapObject(op1).Value; diff --git a/test/DynamoCoreTests/ExperimentalNodesTests.cs b/test/DynamoCoreTests/ExperimentalNodesTests.cs new file mode 100644 index 00000000000..0bc68ca3051 --- /dev/null +++ b/test/DynamoCoreTests/ExperimentalNodesTests.cs @@ -0,0 +1,37 @@ +using Dynamo.Engine; +using NUnit.Framework; + + +namespace Dynamo.Tests +{ + [TestFixture] + internal class ExperimentalNodesTests + { + [Test] + public void FunctionDescriptorIsMarkedExperimentalByExperimentalPrefsSection() + { + var x = new FunctionDescriptor(new FunctionDescriptorParams + { + Assembly = "ProtoGeometry.dll", + ClassName = "Autodesk.DesignScript.Geometry.PanelSurface", + FunctionName = "somefunc", + Parameters = [], + ReturnType = ProtoCore.TypeSystem.BuildPrimitiveTypeObject(ProtoCore.PrimitiveType.Void), + FunctionType = FunctionType.InstanceMethod, + IsVisibleInLibrary = true, + ReturnKeys = [], + PathManager = null, + IsVarArg = false, + ObsoleteMsg = null, + CanUpdatePeriodically = false, + IsBuiltIn = false, + IsPackageMember = false, + IsLacingDisabled = false, + //even though this is set to false, the function should be marked as experimental + //because the assembly/classname combination is marked as experimental in the experimental prefs section + IsExperimental = false, + }); + Assert.That(x.IsExperimental, Is.True); + } + } +} diff --git a/test/DynamoCoreTests/LibraryTests.cs b/test/DynamoCoreTests/LibraryTests.cs index 24aefe334bd..1bf322b11d2 100644 --- a/test/DynamoCoreTests/LibraryTests.cs +++ b/test/DynamoCoreTests/LibraryTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Linq; using System.Xml; @@ -111,6 +111,24 @@ public void TestLoadNoNamespaceClass() } } + [Test] + public void FunctionDescriptorIsMarkedExperimentalByAttr() + { + string libraryPath = "FFITarget.dll"; + if (!libraryServices.IsLibraryLoaded(libraryPath)) + { + libraryServices.ImportLibrary(libraryPath); + Assert.IsTrue(LibraryLoaded); + } + //get our function descriptor that is marked experimental + var functions = libraryServices.GetFunctionGroups(libraryPath).SelectMany(x => x.Functions.Where(x => x.IsExperimental)); + Assert.AreEqual(2,functions.Count()); + + //marked experimental because method is experimental + Assert.AreEqual("ExperimentalMethod", functions.ElementAt(0).FunctionName); + //implicitly marked experimental because owning class is experimental + Assert.AreEqual("Method", functions.ElementAt(1).FunctionName); + } [Test] [Category("UnitTests")] diff --git a/test/DynamoCoreTests/Nodes/StringTests.cs b/test/DynamoCoreTests/Nodes/StringTests.cs index 77cad9ec491..549a7fb792e 100644 --- a/test/DynamoCoreTests/Nodes/StringTests.cs +++ b/test/DynamoCoreTests/Nodes/StringTests.cs @@ -916,6 +916,20 @@ public void TestStringFromArrayWithFormat() AssertPreviewValue(watch3, new string[] { "[1.0,1.7,2.3,3.0]", "[1,1.6666666666666667,2.3333333333333335,3]", "Format specifier was invalid." }); AssertPreviewValue(watch4, "Function"); + } + + [Test] + public void StringFormatNodesAreCurrentlyExperimental() + { +#pragma warning disable NEWNODE_FormattedStringFromObject +#pragma warning disable NM_ISEXPERIMENTAL_GLPYH + + var formatString = new FormattedStringFromObject(); + Assert.AreEqual(true,formatString.IsExperimental); + +#pragma warning restore NM_ISEXPERIMENTAL_GLPYH +#pragma warning restore NEWNODE_FormattedStringFromObject + } #endregion } diff --git a/test/Engine/FFITarget/ExperimentalNodes.cs b/test/Engine/FFITarget/ExperimentalNodes.cs new file mode 100644 index 00000000000..585de86ff6f --- /dev/null +++ b/test/Engine/FFITarget/ExperimentalNodes.cs @@ -0,0 +1,24 @@ + +using System.Diagnostics.CodeAnalysis; + + +namespace FFITarget +{ + public static class ClassWithExperimentalMethod + { + [Experimental("FFI_1")] + public static string ExperimentalMethod() + { + return "I am an experimental node!"; + } + } + [Experimental("FFI_2")] + public static class ExperimentalClass + { + + public static string Method() + { + return "my owning class is experimental"; + } + } +} From a8779513b44da2d52a94b477bbbda60c712a3a03 Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" <508936+mjkkirschner@users.noreply.github.com> Date: Fri, 8 Nov 2024 09:18:27 -0500 Subject: [PATCH 20/22] api --- src/DynamoCore/PublicAPI.Unshipped.txt | 1 + src/DynamoCoreWpf/PublicAPI.Unshipped.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/src/DynamoCore/PublicAPI.Unshipped.txt b/src/DynamoCore/PublicAPI.Unshipped.txt index bb911e51714..a0b5b30c8af 100644 --- a/src/DynamoCore/PublicAPI.Unshipped.txt +++ b/src/DynamoCore/PublicAPI.Unshipped.txt @@ -2782,6 +2782,7 @@ static Dynamo.Properties.Resources.DescriptionResource1.get -> string static Dynamo.Properties.Resources.DirectoryNotFound.get -> string static Dynamo.Properties.Resources.DisplayEngineFailureMessageDescription.get -> string static Dynamo.Properties.Resources.DllLoadException.get -> string +static Dynamo.Properties.Resources.DocsExperimentalPrefixMessage.get -> string static Dynamo.Properties.Resources.DownloadLatestButton.get -> string static Dynamo.Properties.Resources.DSFunctionNodeDescription.get -> string static Dynamo.Properties.Resources.DulicatedPackage.get -> string diff --git a/src/DynamoCoreWpf/PublicAPI.Unshipped.txt b/src/DynamoCoreWpf/PublicAPI.Unshipped.txt index cab36cb3875..aa474071d4f 100644 --- a/src/DynamoCoreWpf/PublicAPI.Unshipped.txt +++ b/src/DynamoCoreWpf/PublicAPI.Unshipped.txt @@ -2412,6 +2412,7 @@ Dynamo.ViewModels.NodeViewModel.InPorts.set -> void Dynamo.ViewModels.NodeViewModel.IsCustomFunction.get -> bool Dynamo.ViewModels.NodeViewModel.IsDisplayingLabels.get -> bool Dynamo.ViewModels.NodeViewModel.IsDisplayingLabels.set -> void +Dynamo.ViewModels.NodeViewModel.IsExperimental.get -> bool Dynamo.ViewModels.NodeViewModel.IsFrozen.get -> bool Dynamo.ViewModels.NodeViewModel.IsFrozen.set -> void Dynamo.ViewModels.NodeViewModel.IsFrozenExplicitly.get -> bool From d11ed9f5c8500a5e2a4b2b0492146e19eeb2e4fb Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" <508936+mjkkirschner@users.noreply.github.com> Date: Fri, 8 Nov 2024 09:29:16 -0500 Subject: [PATCH 21/22] update tests --- test/DynamoCoreTests/CodeBlockNodeTests.cs | 11 +++++++---- test/DynamoCoreWpfTests/NodeViewCustomizationTests.cs | 4 ++-- .../MarkdownGeneratorCommandTests.cs | 2 +- .../CoreNodeModels.FromArray.md | 5 +++++ .../CoreNodeModels.FromObject.md | 5 +++++ 5 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FromArray.md create mode 100644 test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FromObject.md diff --git a/test/DynamoCoreTests/CodeBlockNodeTests.cs b/test/DynamoCoreTests/CodeBlockNodeTests.cs index 43876539ca7..60e4eacf25d 100644 --- a/test/DynamoCoreTests/CodeBlockNodeTests.cs +++ b/test/DynamoCoreTests/CodeBlockNodeTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -2458,10 +2458,13 @@ public void TestMethodKeywordCompletionWhenTyping() string code = "im"; var completions = codeCompletionServices.SearchCompletions(code, Guid.Empty); - // Expected 3 completion items - Assert.AreEqual(3, completions.Count()); + Assert.AreEqual(5, completions.Count()); - string[] expected = { "Imperative", "Minimal", "MinimalTracedClass" }; + string[] expected = { "ClassWithExperimentalMethod", + "ExperimentalClass", + "Imperative", + "Minimal", + "MinimalTracedClass" }; var actual = completions.Select(x => x.Text).OrderBy(x => x); Assert.AreEqual(expected, actual); diff --git a/test/DynamoCoreWpfTests/NodeViewCustomizationTests.cs b/test/DynamoCoreWpfTests/NodeViewCustomizationTests.cs index 2aaae5a5534..1fd807650d2 100644 --- a/test/DynamoCoreWpfTests/NodeViewCustomizationTests.cs +++ b/test/DynamoCoreWpfTests/NodeViewCustomizationTests.cs @@ -312,9 +312,9 @@ public void WatchImageCoreContainsImage() // Starting from Dynamo 2.13, node view now comes with // images like node icon, lacing image etc - // As of March 2022, we have 7 images per NodeView + // As of Nov 2024, we have 8 images per NodeView // Images are named for ease of use - Assert.AreEqual(7, imgs.Count()); + Assert.AreEqual(8, imgs.Count()); var img = imgs.First(x => x.Name == "DotsImage"); diff --git a/test/Tools/NodeDocumentationMarkdownGeneratorTests/MarkdownGeneratorCommandTests.cs b/test/Tools/NodeDocumentationMarkdownGeneratorTests/MarkdownGeneratorCommandTests.cs index 33cadecacdf..a22d4d95dac 100644 --- a/test/Tools/NodeDocumentationMarkdownGeneratorTests/MarkdownGeneratorCommandTests.cs +++ b/test/Tools/NodeDocumentationMarkdownGeneratorTests/MarkdownGeneratorCommandTests.cs @@ -164,7 +164,7 @@ public void ProducesCorrectOutputFromCoreDirectory_preloadedbinaries() FromDirectoryCommand.HandleDocumentationFromDirectory(opts); var generatedFileNames = tempDirectory.GetFiles().Select(x => x.Name); - Assert.AreEqual(707, generatedFileNames.Count()); + Assert.AreEqual(709, generatedFileNames.Count()); } [Test] diff --git a/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FromArray.md b/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FromArray.md new file mode 100644 index 00000000000..0b7f7c81296 --- /dev/null +++ b/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FromArray.md @@ -0,0 +1,5 @@ +## String From Array - Documentation +This documentation file is auto generated by NodeDocumentationMarkdownGenerator, Version=3.4.0.6676, Culture=neutral, PublicKeyToken=null. + +For more information about adding documentation to nodes see https://github.com/DynamoDS/Dynamo/wiki/Create-and-Add-Custom-Documentation-to-Nodes + diff --git a/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FromObject.md b/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FromObject.md new file mode 100644 index 00000000000..b8f0f9e51f5 --- /dev/null +++ b/test/Tools/docGeneratorTestFiles/TestMdOutput_CoreNodeModels/CoreNodeModels.FromObject.md @@ -0,0 +1,5 @@ +## String From Object - Documentation +This documentation file is auto generated by NodeDocumentationMarkdownGenerator, Version=3.4.0.6676, Culture=neutral, PublicKeyToken=null. + +For more information about adding documentation to nodes see https://github.com/DynamoDS/Dynamo/wiki/Create-and-Add-Custom-Documentation-to-Nodes + From e3d33e8e49bde5dc75323bf8a0a4ab085203ce3b Mon Sep 17 00:00:00 2001 From: "mjk.kirschner" <508936+mjkkirschner@users.noreply.github.com> Date: Mon, 11 Nov 2024 16:36:55 -0500 Subject: [PATCH 22/22] review comments --- .../CoreNodeModels.FormattedStringFromArray.md | 6 +++--- .../CoreNodeModels.FormattedStringFromObject.md | 6 +++--- src/DynamoCore/Configuration/PreferenceSettings.cs | 2 -- src/DynamoCore/Properties/Resources.Designer.cs | 2 +- src/DynamoCore/Properties/Resources.en-US.resx | 2 +- src/DynamoCore/Properties/Resources.resx | 2 +- src/DynamoCoreWpf/Views/Core/NodeView.xaml | 9 ++++++--- .../ProtoCore/DSASM/Mirror/ExecutionMirror.cs | 4 ++-- src/Libraries/CoreNodeModels/String.cs | 2 +- test/DynamoCoreTests/Nodes/StringTests.cs | 14 +++++++++++--- 10 files changed, 29 insertions(+), 20 deletions(-) diff --git a/doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromArray.md b/doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromArray.md index ad28ddf72df..76a62492255 100644 --- a/doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromArray.md +++ b/doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromArray.md @@ -8,10 +8,10 @@ format specifiers should be in the form: Some commonly used format specifiers are: ``` G : general formatting G 1000.0 -> "1000" -F : fixed point notation F4 1000.0 -> "1.0000" -N : number N 1.0 -> 1000 -> "1,000.00" +F : fixed point notation F4 1000.0 -> "1000.0000" +N : number N2 1000 -> "1,000.00" ``` The default for this node is `G`, which will output a compact, but variable representation. -[see the microsoft documentation for more detailed information.](https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings#standard-format-specifiers) \ No newline at end of file +[see the microsoft documentation for more detailed information.](https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings#standard-format-specifiers) diff --git a/doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromObject.md b/doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromObject.md index ad28ddf72df..76a62492255 100644 --- a/doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromObject.md +++ b/doc/distrib/NodeHelpFiles/CoreNodeModels.FormattedStringFromObject.md @@ -8,10 +8,10 @@ format specifiers should be in the form: Some commonly used format specifiers are: ``` G : general formatting G 1000.0 -> "1000" -F : fixed point notation F4 1000.0 -> "1.0000" -N : number N 1.0 -> 1000 -> "1,000.00" +F : fixed point notation F4 1000.0 -> "1000.0000" +N : number N2 1000 -> "1,000.00" ``` The default for this node is `G`, which will output a compact, but variable representation. -[see the microsoft documentation for more detailed information.](https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings#standard-format-specifiers) \ No newline at end of file +[see the microsoft documentation for more detailed information.](https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings#standard-format-specifiers) diff --git a/src/DynamoCore/Configuration/PreferenceSettings.cs b/src/DynamoCore/Configuration/PreferenceSettings.cs index c569f00f51e..8dfbf926447 100644 --- a/src/DynamoCore/Configuration/PreferenceSettings.cs +++ b/src/DynamoCore/Configuration/PreferenceSettings.cs @@ -114,8 +114,6 @@ private readonly static Lazy internal static readonly IEnumerable InitialExperimentalLib_Namespaces = [ - //TODO remove tsplines - it's no longer experimental. - "ProtoGeometry.dll:Autodesk.DesignScript.Geometry.TSpline", "ProtoGeometry.dll:Autodesk.DesignScript.Geometry.PanelSurface" ]; #endregion diff --git a/src/DynamoCore/Properties/Resources.Designer.cs b/src/DynamoCore/Properties/Resources.Designer.cs index 2a1d19e2f9d..7935c0f1ab3 100644 --- a/src/DynamoCore/Properties/Resources.Designer.cs +++ b/src/DynamoCore/Properties/Resources.Designer.cs @@ -498,7 +498,7 @@ public static string DllLoadException { } /// - /// Looks up a localized string similar to This node is marked experimental, its behavior, name, and signature may change!. + /// Looks up a localized string similar to This node is currently experimental. Its behavior, name, and signature are subject to change.. /// public static string DocsExperimentalPrefixMessage { get { diff --git a/src/DynamoCore/Properties/Resources.en-US.resx b/src/DynamoCore/Properties/Resources.en-US.resx index 9d22e892700..95a14871ccd 100644 --- a/src/DynamoCore/Properties/Resources.en-US.resx +++ b/src/DynamoCore/Properties/Resources.en-US.resx @@ -921,6 +921,6 @@ This package likely contains an assembly that is blocked. You will need to load default input name, rename me! - This node is marked experimental, its behavior, name, and signature may change! + This node is currently experimental. Its behavior, name, and signature are subject to change. \ No newline at end of file diff --git a/src/DynamoCore/Properties/Resources.resx b/src/DynamoCore/Properties/Resources.resx index fad93c025fe..bef1c049ee2 100644 --- a/src/DynamoCore/Properties/Resources.resx +++ b/src/DynamoCore/Properties/Resources.resx @@ -924,6 +924,6 @@ This package likely contains an assembly that is blocked. You will need to load default input name, rename me! - This node is marked experimental, its behavior, name, and signature may change! + This node is currently experimental. Its behavior, name, and signature are subject to change. \ No newline at end of file diff --git a/src/DynamoCoreWpf/Views/Core/NodeView.xaml b/src/DynamoCoreWpf/Views/Core/NodeView.xaml index 89d7716b8a1..b2f5a5f9ec1 100644 --- a/src/DynamoCoreWpf/Views/Core/NodeView.xaml +++ b/src/DynamoCoreWpf/Views/Core/NodeView.xaml @@ -456,10 +456,13 @@ + HorizontalAlignment="Center"> + + + + diff --git a/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs b/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs index 9de47eb8bd4..534610d1e9f 100644 --- a/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs +++ b/src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs @@ -187,8 +187,8 @@ private string GetStringValueImplementation(StackValue val, string formatSpecifi return "null"; // "Value not yet supported for tracing"; } - //TODO - use format specifier when converting to string - //obsolete this method and introduce another. + //TODO - use format specifier when converting classes to string + [Obsolete("This will be made internal")] public string GetClassTrace(StackValue val, Heap heap, int langblock, bool forPrint) { if (!formatParams.ContinueOutputTrace()) diff --git a/src/Libraries/CoreNodeModels/String.cs b/src/Libraries/CoreNodeModels/String.cs index 3a02b915a39..9db486e94e6 100644 --- a/src/Libraries/CoreNodeModels/String.cs +++ b/src/Libraries/CoreNodeModels/String.cs @@ -89,6 +89,7 @@ private FormattedStringFromObject(IEnumerable inPorts, IEnumerable 1) @@ -96,7 +97,6 @@ public FormattedStringFromObject() : base("__ToStringFromObjectAndFormat") InPorts.ElementAt(1).DefaultValue = AstFactory.BuildStringNode("G"); InPorts.ElementAt(1).UsingDefaultValue = true; } - RegisterAllPorts(); } } diff --git a/test/DynamoCoreTests/Nodes/StringTests.cs b/test/DynamoCoreTests/Nodes/StringTests.cs index 549a7fb792e..7d164f2316a 100644 --- a/test/DynamoCoreTests/Nodes/StringTests.cs +++ b/test/DynamoCoreTests/Nodes/StringTests.cs @@ -921,14 +921,22 @@ public void TestStringFromArrayWithFormat() [Test] public void StringFormatNodesAreCurrentlyExperimental() { -#pragma warning disable NEWNODE_FormattedStringFromObject -#pragma warning disable NM_ISEXPERIMENTAL_GLPYH +#pragma warning disable NEWNODE_FormattedStringFromObject +#pragma warning disable NEWNODE_FormattedStringFromArray + +#pragma warning disable NM_ISEXPERIMENTAL_GLPYH var formatString = new FormattedStringFromObject(); + var formatStringArr = new FormattedStringFromArray(); Assert.AreEqual(true,formatString.IsExperimental); + Assert.AreEqual(true, formatStringArr.IsExperimental); + Assert.IsTrue(formatString.InPorts[1].DefaultValue.Kind == ProtoCore.AST.AssociativeAST.AstKind.String && formatString.InPorts[1].UsingDefaultValue == true); + Assert.IsTrue(formatStringArr.InPorts[1].DefaultValue.Kind == ProtoCore.AST.AssociativeAST.AstKind.String && formatStringArr.InPorts[1].UsingDefaultValue == true); -#pragma warning restore NM_ISEXPERIMENTAL_GLPYH +#pragma warning restore NM_ISEXPERIMENTAL_GLPYH #pragma warning restore NEWNODE_FormattedStringFromObject +#pragma warning restore NEWNODE_FormattedStringFromArray + } #endregion