Skip to content

DYN-5965: introduce new string from nodes that accept numeric format specifiers #14369

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
38a0567
fix most memory leaks from opening and closing Dynamo Splash Screen (…
mjkkirschner Sep 1, 2023
bd9071a
Merge branch 'master' of https://github.com/DynamoDS/Dynamo
mjkkirschner Sep 1, 2023
06e24bf
works and old graphs find method
mjkkirschner Sep 1, 2023
7a1a344
try to get tests passing
mjkkirschner Sep 5, 2023
bd25c84
fix default values
mjkkirschner Sep 5, 2023
17de8d6
remove duplicated builtin function endpoint
mjkkirschner Sep 5, 2023
6026229
save status
mjkkirschner Sep 5, 2023
22fcb33
merge conflict
mjkkirschner Oct 29, 2024
f981a14
builtin method tests are passing
mjkkirschner Oct 30, 2024
8fe9ebe
Merge branch 'master' of https://github.com/DynamoDS/Dynamo into code…
mjkkirschner Oct 31, 2024
dcc9d41
update graph tests
mjkkirschner Oct 31, 2024
45753f0
new builtin tests
mjkkirschner Oct 31, 2024
74a0b94
fix node doc tests
mjkkirschner Oct 31, 2024
91b7147
test dynpref format
mjkkirschner Nov 1, 2024
c21ba95
check for warning state
mjkkirschner Nov 1, 2024
8236398
add experimental flag to typeload data for node models
mjkkirschner Nov 4, 2024
ad3ff1b
fix docs tests
mjkkirschner Nov 5, 2024
f90f12e
update node names from review comments
mjkkirschner Nov 5, 2024
6d6f588
docs
mjkkirschner Nov 6, 2024
2f0692f
add experimental glyph on nodeview
mjkkirschner Nov 6, 2024
4f7e142
this works to set experimental namespaces as experimetnal
mjkkirschner Nov 7, 2024
81d0400
add feature flag check for ui
mjkkirschner Nov 7, 2024
a877951
api
mjkkirschner Nov 8, 2024
d11ed9f
update tests
mjkkirschner Nov 8, 2024
0e73d61
conflict
mjkkirschner Nov 8, 2024
e3d33e8
review comments
mjkkirschner Nov 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/DynamoCoreWpf/ViewModels/Preview/WatchViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
}
Expand Down
63 changes: 54 additions & 9 deletions src/Engine/ProtoCore/DSASM/Mirror/ExecutionMirror.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using ProtoCore.Lang;
Expand Down Expand Up @@ -44,15 +45,55 @@ public ExecutionMirror(ProtoCore.DSASM.Executive exec, ProtoCore.RuntimeCore cor
MirrorTarget = exec;
}

/// <summary>
///
/// </summary>
/// <param name="val"></param>
/// <param name="heap"></param>
/// <param name="langblock"></param>
/// <param name="forPrint"></param>
/// <param name="useNumericFormat"></param>
/// <returns></returns>
public string GetStringValue2(StackValue val, Heap heap, int langblock, bool forPrint = false,
bool useNumericFormat = false)
{
return GetStringValueImplementation(val, heap, langblock, -1, -1, forPrint, useNumericFormat);
}

/// <summary>
///
/// </summary>
/// <param name="val"></param>
/// <param name="heap"></param>
/// <param name="langblock"></param>
/// <param name="forPrint"></param>
/// <returns></returns>
[Obsolete]
public string GetStringValue(StackValue val, Heap heap, int langblock, bool forPrint = false)
{
return GetStringValue(val, heap, langblock, -1, -1, forPrint);
}

/// <summary>
///
/// </summary>
/// <param name="val"></param>
/// <param name="heap"></param>
/// <param name="langblock"></param>
/// <param name="maxArraySize"></param>
/// <param name="maxOutputDepth"></param>
/// <param name="forPrint"></param>
/// <returns></returns>
[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)
{
Expand All @@ -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");
}

Expand All @@ -77,7 +122,7 @@ public string GetStringValue(StackValue val, Heap heap, int langblock, int maxAr
if (val.IsArray)
{
HashSet<int> pointers = new HashSet<int> { val.ArrayPointer };
string arrTrace = GetArrayTrace(val, heap, langblock, pointers, forPrint);
string arrTrace = GetArrayTrace(val, heap, langblock, pointers, forPrint, useNumericFormat);
if (forPrint)
return "[" + arrTrace + "]";

Expand Down Expand Up @@ -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<int> pointers, bool forPrint)
private string GetPointerTrace(StackValue ptr, Heap heap, int langblock, HashSet<int> pointers, bool forPrint, bool useNumericFormat)
{
if (pointers.Contains(ptr.ArrayPointer))
{
Expand All @@ -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<int> pointers, bool forPrint)
private string GetArrayTrace(StackValue svArray, Heap heap, int langblock, HashSet<int> pointers, bool forPrint, bool useNumericFormat)
{
if (!formatParams.ContinueOutputTrace())
return "...";
Expand Down Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions src/Engine/ProtoCore/Lang/BuiltInFunctionEndPoint.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -373,7 +373,9 @@ public override StackValue Execute(ProtoCore.Runtime.Context c, List<StackValue>
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);
Expand Down
16 changes: 14 additions & 2 deletions src/Engine/ProtoCore/Lang/BuiltInMethods.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using ProtoCore.AST.AssociativeAST;
using ProtoCore.DSASM;
Expand Down Expand Up @@ -795,6 +795,17 @@ public BuiltInMethods(Core core)
Parameters = new List<KeyValuePair<string, ProtoCore.Type>>
{
new KeyValuePair<string, ProtoCore.Type>("object", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var, 0)),
new KeyValuePair<string, ProtoCore.Type>("useNumericFormat", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Bool, 0)),
},
ID = BuiltInMethods.MethodID.ToStringFromObject,
},
new BuiltInMethod
{
ReturnType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.String, 0),
Parameters = new List<KeyValuePair<string, ProtoCore.Type>>
{
new KeyValuePair<string, ProtoCore.Type>("object", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var, 0)),
new KeyValuePair<string, ProtoCore.Type>("useNumericFormat", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Bool, 0)),
},
ID = BuiltInMethods.MethodID.ToStringFromObject,
},
Expand All @@ -806,6 +817,7 @@ public BuiltInMethods(Core core)
Parameters = new []
{
new KeyValuePair<string, Type>("list", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Var)),
new KeyValuePair<string, ProtoCore.Type>("useNumericFormat", TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.Bool, 0)),
}.ToList(),
ID = BuiltInMethods.MethodID.ToStringFromArray
},
Expand Down Expand Up @@ -915,4 +927,4 @@ public BuiltInMethods(Core core)
};
}
}
}
}
21 changes: 3 additions & 18 deletions src/Engine/ProtoCore/Reflection/MirrorData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,36 +224,21 @@ 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()
// https://msdn.microsoft.com/en-us/library/3hfd35ad(v=vs.110).aspx
// 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();
}
}

Expand Down
24 changes: 22 additions & 2 deletions src/Engine/ProtoCore/Utils/StringUtils.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using ProtoCore.DSASM;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

Expand Down Expand Up @@ -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<StackValue> 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<DSString>(op1).Value;
Expand Down
10 changes: 8 additions & 2 deletions src/Libraries/CoreNodeModels/String.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -8,7 +9,7 @@ namespace CoreNodeModels
{
/// <summary>
/// Base class to represent a single input string node. It supports
/// partiallied applied function.
/// partially applied function.
/// </summary>
public class ToStringNodeBase : NodeModel
{
Expand Down Expand Up @@ -72,13 +73,18 @@ public class FromObject: ToStringNodeBase
private FromObject(IEnumerable<PortModel> inPorts, IEnumerable<PortModel> 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();
}
Expand Down