Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 7 additions & 1 deletion doc/distrib/xml/en-US/DSCoreNodes.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions src/DynamoCore/Graph/Nodes/IValueSchemaProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace Dynamo.Graph.Nodes
{
/// <summary>
/// Implemented by NodeModels that can describe their value type
/// for external consumers (DynamoPlayer, MCP, etc.).
/// Returns a canonical Forge Data Schema type identifier and list context.
/// </summary>
public interface IValueSchemaProvider
{
/// <summary>
/// Type identifier matching the Player ValueSchema.TypeId wire format.
/// For geometry/complex types: Forge Data Schema URN (e.g. "autodesk.math:point3d-1.0.0").
/// For primitives: ForgeDataSchemaType values (e.g. "Float64", "String", "Bool", "Int64").
/// Returns a non-null type identifier. If the type is not yet determined,
/// implementations should return their existing non-null fallback value.
/// </summary>
string ValueTypeId { get; }

/// <summary>
/// Whether the value is a list (array) of the declared type.
/// </summary>
bool IsListValue { get; }
}
}
3 changes: 3 additions & 0 deletions src/DynamoCore/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
Dynamo.Graph.Nodes.IValueSchemaProvider
Dynamo.Graph.Nodes.IValueSchemaProvider.IsListValue.get -> bool
Dynamo.Graph.Nodes.IValueSchemaProvider.ValueTypeId.get -> string
Dynamo.Models.DynamoModel.DefaultStartConfiguration.EnableUnTrustedLocationsNotifications.get -> bool
Dynamo.Models.DynamoModel.DefaultStartConfiguration.EnableUnTrustedLocationsNotifications.set -> void
Dynamo.Models.DynamoModel.IStartConfiguration.EnableUnTrustedLocationsNotifications.get -> bool
19 changes: 18 additions & 1 deletion src/Libraries/CoreNodeModels/DefineData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,25 @@ namespace CoreNodeModels
[OutPortDescriptions(typeof(Properties.Resources), nameof(Properties.Resources.DefineDataOutputTooltip))]
[IsDesignScriptCompatible]
[AlsoKnownAs("Data.DefineData")]
public class DefineData : DSDropDownBase
public class DefineData : DSDropDownBase, IValueSchemaProvider
{
/// <inheritdoc/>
[JsonIgnore]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a use case for serializing these values?

public string ValueTypeId
Comment thread
johnpierson marked this conversation as resolved.
{
get
{
if (SelectedIndex < 0 || SelectedIndex >= Items.Count)
return SelectedString;

return (Items[SelectedIndex].Item as Data.DataNodeDynamoType)?.TypeId ?? SelectedString;
}
}

/// <inheritdoc/>
[JsonIgnore]
public bool IsListValue => IsList;
Comment thread
kalunkuo marked this conversation as resolved.

private bool isAutoMode = true; // default start with auto-detect 'on'
private bool isList;
private string displayValue = Properties.Resources.DefineDataDisplayValueMessage;
Expand Down
81 changes: 44 additions & 37 deletions src/Libraries/CoreNodes/Data.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@

//types supported by Geometry.FromJson
case "autodesk.math:point3d-1.0.0":
case "dynamo.geometry:sab-1.0.0":

Check warning on line 110 in src/Libraries/CoreNodes/Data.cs

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define a constant instead of using this literal 'dynamo.geometry:sab-1.0.0' 6 times.

See more on https://sonarcloud.io/project/issues?id=DynamoDS_Dynamo&issues=AZ2Hra2fz0UVeFxneQn4&open=AZ2Hra2fz0UVeFxneQn4&pullRequest=17040
case "dynamo.geometry:tsm-1.0.0":
case "dynamo.geometry:rectangle-1.0.0":
case "dynamo.geometry:cuboid-1.0.0":
Expand Down Expand Up @@ -534,7 +534,7 @@
/// <summary>
/// A class representing a DataType supported by Dynamo
/// </summary>
internal class DataNodeDynamoType(Type type, string name = null)
internal class DataNodeDynamoType(Type type, string name = null, string typeId = null)
{
/// <summary>
/// The underlying Type
Expand All @@ -545,6 +545,11 @@
/// </summary>
public string Name { get; private set; } = name ?? type.Name;
/// <summary>
/// Wire-format $typeid (e.g. "autodesk.math:point3d-1.0.0").
/// Null for primitive types that don't use $typeid serialization.
/// </summary>
public string TypeId { get; private set; } = typeId;
/// <summary>
/// The hierarchical level to be displayed in the UI
/// </summary>
public int Level { get; private set; } = 0;
Expand All @@ -557,8 +562,8 @@
/// </summary>
public DataNodeDynamoType Parent { get; private set; }

public DataNodeDynamoType(Type type, int level, bool isLastChild = false, string name = null, DataNodeDynamoType parent = null)
: this(type, name)
public DataNodeDynamoType(Type type, int level, bool isLastChild = false, string name = null, DataNodeDynamoType parent = null, string typeId = null)
: this(type, name, typeId)
{
Level = level;
IsLastChild = isLastChild;
Expand All @@ -577,53 +582,55 @@
/// </summary>
static Data()
{
var curve = new DataNodeDynamoType(typeof(Curve), 0, false, null, null);
var polyCurve = new DataNodeDynamoType(typeof(PolyCurve), 1, false, null, curve);
var polygon = new DataNodeDynamoType(typeof(Polygon), 2, false, null, polyCurve); // polygon is subtype of polyCurve
var rectangle = new DataNodeDynamoType(typeof(Autodesk.DesignScript.Geometry.Rectangle), 3, true, null, polyCurve); // rectangle is subtype of polygon
var solid = new DataNodeDynamoType(typeof(Solid), 0, false, null, null);
var cone = new DataNodeDynamoType(typeof(Cone), 1, false, null, solid); // cone is subtype of solid
var cylinder = new DataNodeDynamoType(typeof(Cylinder), 2, false, null, cone); // cylinder is subtype of cone
var cuboid = new DataNodeDynamoType(typeof(Cuboid), 1, false, null, solid); // cuboid is subtype of solid
var sphere = new DataNodeDynamoType(typeof(Sphere), 1, true, null, solid); // sphere is subtype of solid

var surface = new DataNodeDynamoType(typeof(Surface), 0, false, null, null);
var curve = new DataNodeDynamoType(typeof(Curve), 0, false, null, null, "dynamo.geometry:sab-1.0.0");
var polyCurve = new DataNodeDynamoType(typeof(PolyCurve), 1, false, null, curve, "autodesk.geometry.curve:compositecurve-1.0.0");
var polygon = new DataNodeDynamoType(typeof(Polygon), 2, false, null, polyCurve, "autodesk.geometry.curve:polyline-1.0.0");
var rectangle = new DataNodeDynamoType(typeof(Autodesk.DesignScript.Geometry.Rectangle), 3, true, null, polyCurve, "dynamo.geometry:rectangle-1.0.0");
var solid = new DataNodeDynamoType(typeof(Solid), 0, false, null, null, "dynamo.geometry:sab-1.0.0");
var cone = new DataNodeDynamoType(typeof(Cone), 1, false, null, solid, "dynamo.geometry:cone-1.0.0");
Comment thread
kalunkuo marked this conversation as resolved.
var cylinder = new DataNodeDynamoType(typeof(Cylinder), 2, false, null, cone, "autodesk.geometry.surface:cylinder-2.0.0");
var cuboid = new DataNodeDynamoType(typeof(Cuboid), 1, false, null, solid, "dynamo.geometry:cuboid-1.0.0");
var sphere = new DataNodeDynamoType(typeof(Sphere), 1, true, null, solid, "autodesk.geometry.surface:sphere-1.0.0");

var surface = new DataNodeDynamoType(typeof(Surface), 0, false, null, null, "dynamo.geometry:sab-1.0.0");

var typeList = new List<DataNodeDynamoType>
{
new(typeof(bool)),
new(typeof(BoundingBox)),
new(typeof(CoordinateSystem)),
new(typeof(bool), typeId: "Bool"),
new(typeof(BoundingBox), typeId: "autodesk.geometry:boundingbox3d-1.0.0"),
new(typeof(CoordinateSystem), typeId: "autodesk.math:matrix44d-1.0.0"),
new(typeof(DSCore.Color), typeId: "dynamo.graphics:color-1.0.0"),
curve,
new(typeof(Arc), 1, false, null, curve),
new(typeof(Circle), 1, false, null, curve),
new(typeof(Ellipse), 1, false, null, curve),
new(typeof(EllipseArc), 1, false, null, curve),
new(typeof(Helix), 1, false, null, curve),
new(typeof(Line), 1, false, null, curve),
new(typeof(NurbsCurve), 1, false, null, curve),
new(typeof(Arc), 1, false, null, curve, "autodesk.geometry.curve:circle-1.0.0"),
new(typeof(Circle), 1, false, null, curve, "autodesk.geometry.curve:circle-1.0.0"),
new(typeof(Ellipse), 1, false, null, curve, "autodesk.geometry.curve:ellipse-1.0.0"),
new(typeof(EllipseArc), 1, false, null, curve, "autodesk.geometry.curve:ellipse-1.0.0"),
new(typeof(Helix), 1, false, null, curve, "dynamo.geometry:sab-1.0.0"),
new(typeof(System.Drawing.Bitmap), "Image", typeId: "dynamo.graphics:png-1.0.0"),
new(typeof(Line), 1, false, null, curve, "autodesk.geometry.curve:line-1.0.0"),
new(typeof(NurbsCurve), 1, false, null, curve, "autodesk.geometry.curve:bcurve-1.0.0"),
polyCurve,
polygon,
rectangle,
new(typeof(System.DateTime)),
new(typeof(double), "Number"),
new(typeof(long), "Integer"),
new(typeof(Location)),
new(typeof(Mesh)),
new(typeof(Plane)),
new(typeof(Autodesk.DesignScript.Geometry.Point)),
new(typeof(System.DateTime), typeId: "DateTime"),
new(typeof(double), "Number", typeId: "Float64"),
new(typeof(long), "Integer", typeId: "Int64"),
new(typeof(Location), typeId: "dynamo.data:location-1.0.0"),
new(typeof(Mesh), typeId: "dynamo.geometry:mesh-1.0.0"),
new(typeof(Plane), typeId: "autodesk.geometry.surface:plane-1.0.0"),
new(typeof(Autodesk.DesignScript.Geometry.Point), typeId: "autodesk.math:point3d-1.0.0"),
solid,
cone,
cylinder,
cuboid,
sphere,
new(typeof(string)),
new(typeof(string), typeId: "String"),
surface,
new(typeof(NurbsSurface), 1, false, null, surface),
new(typeof(PolySurface), 1, true, null, surface),
new(typeof(System.TimeSpan)),
new(typeof(UV)),
new(typeof(Vector))
new(typeof(NurbsSurface), 1, false, null, surface, "autodesk.geometry.curve:bsurface-1.0.0"),
new(typeof(PolySurface), 1, true, null, surface, "dynamo.geometry:sab-1.0.0"),
new(typeof(System.TimeSpan), typeId: "TimeSpan"),
new(typeof(UV), typeId: "autodesk.math:uv-1.0.0"),
new(typeof(Vector), typeId: "autodesk.math:vector3d-1.0.0")
};

DataNodeDynamoTypeList = new ReadOnlyCollection<DataNodeDynamoType>(typeList);
Expand Down
70 changes: 70 additions & 0 deletions test/DynamoCoreTests/Nodes/DefineDataTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System.Collections.Generic;
using System.Linq;
using CoreNodeModels;
using NUnit.Framework;

namespace Dynamo.Tests.Nodes
{
[TestFixture]
internal class DefineDataTests : DynamoModelTestBase
{
protected override void GetLibrariesToPreload(List<string> libraries)
{
libraries.Add("DSCoreNodes.dll");
base.GetLibrariesToPreload(libraries);
}

[Test]
[Category("UnitTests")]
public void ValueSchemaProviderReturnsTypeId()
{
var node = new DefineData();
CurrentDynamoModel.CurrentWorkspace.AddAndRegisterNode(node, false);

// Find a type with a non-null TypeId for testing
var pointType = DSCore.Data.DataNodeDynamoTypeList.First(t => t.Type == typeof(Autodesk.DesignScript.Geometry.Point));
Assert.IsNotNull(pointType.TypeId, "Point type should have a valid TypeId");

// Set the node to Point type
node.SelectedIndex = DSCore.Data.DataNodeDynamoTypeList.IndexOf(pointType);

Assert.AreEqual(pointType.TypeId, node.ValueTypeId);
Assert.IsFalse(node.IsListValue);
}

[Test]
[Category("UnitTests")]
public void ValueTypeIdSafeWhenNoSelection()
{
var node = new DefineData();
Assert.DoesNotThrow(() => { var _ = node.ValueTypeId; });
Assert.AreEqual(node.SelectedString, node.ValueTypeId);
}

[Test]
[Category("UnitTests")]
public void ValueTypeIdReturnsPrimitiveTypeId()
{
var node = new DefineData();
CurrentDynamoModel.CurrentWorkspace.AddAndRegisterNode(node, false);

var boolType = DSCore.Data.DataNodeDynamoTypeList.First(t => t.Type == typeof(bool));
node.SelectedIndex = DSCore.Data.DataNodeDynamoTypeList.IndexOf(boolType);

Assert.AreEqual("Bool", node.ValueTypeId);
}

[Test]
[Category("UnitTests")]
public void ValueTypeIdReturnsFloat64ForNumber()
{
var node = new DefineData();
CurrentDynamoModel.CurrentWorkspace.AddAndRegisterNode(node, false);

var numberType = DSCore.Data.DataNodeDynamoTypeList.First(t => t.Type == typeof(double));
node.SelectedIndex = DSCore.Data.DataNodeDynamoTypeList.IndexOf(numberType);

Assert.AreEqual("Float64", node.ValueTypeId);
}
}
}
Loading