Skip to content
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

DYN-6365 Promote Gate node from GD Extension to Dynamo Core. #14528

Merged
merged 8 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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
23 changes: 23 additions & 0 deletions src/Libraries/CoreNodeModels/CoreNodeModelsImages.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,29 @@
f66KxdT5Mc9gSmp03qAW9gD5lfwobNUbvjVjAU0UNacLobgfWBUOJrhkXnc2pc08O3uXcsnTdV1Kw+dw
IPQxh9M1WA0uyLqE0AAGIW/Key8ihlALTQmXWtgG1VZGV7BDhxVyKQowQnFEcOlzsDI4jR14HIzwmO9p
2zaJFT8arCiKovwdxnwAzk7Zcq1S2RAAAAAASUVORK5CYII=
</value>
</data>
<data name="CoreNodeModels.Gate.Logic.Large" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wgAADsIBFShKgAAAAZxJREFUeF7t2L1t22AQBmAN4kVcugyQ1oN4kRQZw60nSJMdUrjyAB6BvpPPAJF8
OssIfyz4eYCDBIn6CL56IZI6AAAAAAAAAAAAAMBnN03TVc11PtbLbCECv415ipm7rrdZS4Scjb8/xv2v
+9qMNUTAo9bP3damLCmC7Vr/5qk2Z0kRbLb+PfnlOAkvKQOtYDv5c+RnZ2kZ6jHentYvLQON+Z3pNrR+
DRHq3THensvMpUWoWr+XCFXr9xChZuu7G6qU7/trYWkRqtbvIULV+q1EiBn2QyZaHuux86M+zv+KMJ9f
Mz1Ltn6VG6pcN2ZehHx+WTdvv75/mz4y4b2/D+ZWbX2sPypCvnY5X8Io5G7OtFrr38T6XREebn7+mT4y
tez2RiF3c4a7WnpVta9Tnkchd1PLbm8Ucjd5cMdDPKGWXV3t7qRRyN3UstsbhdxNmJ/0/rbZ9X3sqy3C
KORuatnPL44trzyGJ7/aZBOxv7YIo5C7qWUvQxzg7pd/ub+Y3YvwpUXYl38fAAAAAAAAAAAAAAAAAAAA
AHwth8MLYH2lDRT2bNoAAAAASUVORK5CYII=
</value>
</data>
<data name="CoreNodeModels.Logic.Gate.Small" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wgAADsIBFShKgAAAANNJREFUWEftkq0KAlEQRhc2CloFi/ocli2CP/gAVovBZvcNNJhtgk2228SnUIOI
2bZ9PHd3wgrqYrgGmQOnzHzcj4EbGIZh/AUiUsIh1nT0Oyht4QkdYx37hzJ39SKtFUlwiqGu/UJRhBd0
HLCpK79QVMaVawV39URXfqFogFu8omOHdV0/wTzEHlZ09D37fkfygrvWcceRxl7Cfp4mRc7R8hjn1Ugx
lMZ5eeyWvSkzjbyFzDqLSkKp5NXI9/BYFdtY+MvJNHCDXR0ZhmEYhvGBIHgAduXaGHqoIxcAAAAASUVO
RK5CYII=
</value>
</data>
</root>
72 changes: 72 additions & 0 deletions src/Libraries/CoreNodeModels/Logic/Gate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using CoreNodeModels.Properties;
using Dynamo.Graph.Nodes;
using Newtonsoft.Json;
using ProtoCore.AST.AssociativeAST;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CoreNodeModels.Logic
{
[NodeName("Gate")]
[NodeDescription(nameof(Resources.GateDescription), typeof(Resources))]
[NodeCategory(BuiltinNodeCategories.LOGIC)]
[NodeSearchTags(nameof(Resources.GateSearchTags), typeof(Resources))]
[InPortNames(">")]
[InPortTypes("object")]
[InPortDescriptions(nameof(Resources.GateInPortToolTip), nameof(Resources))]
[OutPortNames(">")]
[OutPortTypes("object")]
[OutPortDescriptions(nameof(Resources.GateOutPortToolTip), nameof(Resources))]
[IsDesignScriptCompatible]
public class Gate : NodeModel
{
private bool value;

[JsonProperty("InputValue")]
public virtual bool Value
{
get
{
return value;
}
set
{
if (!this.value.Equals(value))
{
this.value = value;
ClearDirtyFlag();
OnNodeModified();
RaisePropertyChanged(nameof(Value));
}
}
}

[JsonConstructor]
private Gate(IEnumerable<PortModel> inPorts, IEnumerable<PortModel> outPorts) : base(inPorts, outPorts)
{
ShouldDisplayPreviewCore = false;
}

public Gate()
{
Value = false;
RegisterAllPorts();
ShouldDisplayPreviewCore = false;
}

public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes)
{
// Check that node can run
if (!Value)
{
return new[]
{AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildNullNode())};
}

return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), inputAstNodes[0]) };
}
}
}
38 changes: 38 additions & 0 deletions src/Libraries/CoreNodeModels/Properties/Resources.Designer.cs

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

14 changes: 14 additions & 0 deletions src/Libraries/CoreNodeModels/Properties/Resources.en-US.resx
Original file line number Diff line number Diff line change
Expand Up @@ -641,4 +641,18 @@ Default value: {0}</value>
<data name="TooltipTextQuery" xml:space="preserve">
<value>Nodes that query data</value>
</data>
<data name="GateDescription" xml:space="preserve">
<value>Block data passing through this node to downstream nodes. Node returns the input data only if the node value is set to Open.

In Generative Design workflows, this node should be used to control and block the behavior of nodes that will place elements in Revit</value>
</data>
<data name="GateInPortToolTip" xml:space="preserve">
<value>Data to pass to a downstream node with gated controls.</value>
</data>
<data name="GateOutPortToolTip" xml:space="preserve">
<value>Data</value>
</data>
<data name="GateSearchTags" xml:space="preserve">
<value>gate;stop;data</value>
</data>
</root>
14 changes: 14 additions & 0 deletions src/Libraries/CoreNodeModels/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -641,4 +641,18 @@ Default value: {0}</value>
<data name="TooltipTextQuery" xml:space="preserve">
<value>Nodes that query data</value>
</data>
<data name="GateDescription" xml:space="preserve">
<value>Block data passing through this node to downstream nodes. Node returns the input data only if the node value is set to Open.

In Generative Design workflows, this node should be used to control and block the behavior of nodes that will place elements in Revit</value>
</data>
<data name="GateInPortToolTip" xml:space="preserve">
<value>Data to pass to a downstream node with gated controls.</value>
</data>
<data name="GateOutPortToolTip" xml:space="preserve">
<value>Data</value>
</data>
<data name="GateSearchTags" xml:space="preserve">
<value>gate;stop;data</value>
</data>
</root>
70 changes: 70 additions & 0 deletions src/Libraries/CoreNodeModelsWpf/NodeViewCustomizations/Gate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using CoreNodeModels;
using CoreNodeModels.Logic;
using CoreNodeModels.Properties;
using Dynamo.Controls;
using Dynamo.UI;
using Dynamo.Wpf;
using Dynamo.Wpf.Properties;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;

namespace CoreNodeModelsWpf.Nodes
{
public class GateNodeViewCustomization : INodeViewCustomization<Gate>
{
public void CustomizeView(Gate model, NodeView nodeView)
{
//add a text box to the input grid of the control
var rbTrue = new RadioButton();
var rbFalse = new RadioButton();
rbTrue.Style = rbFalse.Style = (Style)SharedDictionaryManager.DynamoModernDictionary["RadioButton"];

//use a unique name for the button group
//so other instances of this element don't get confused
string groupName = Guid.NewGuid().ToString();
rbTrue.GroupName = groupName;
rbFalse.GroupName = groupName;

rbTrue.Content = CoreNodeModelWpfResources.GateOpen;
rbTrue.Padding = new Thickness(0, 0, 12, 0);
rbFalse.Content = CoreNodeModelWpfResources.GateClose;
rbFalse.Padding = new Thickness(0);
var wp = new WrapPanel
{
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Stretch,
Margin = new Thickness(10, 5, 10, 0),
Orientation = Orientation.Horizontal
};

wp.Children.Add(rbTrue);
wp.Children.Add(rbFalse);
nodeView.inputGrid.Children.Add(wp);

rbFalse.DataContext = model;
rbTrue.DataContext = model;

var rbTrueBinding = new Binding("Value") { Mode = BindingMode.TwoWay, };
rbTrue.SetBinding(ToggleButton.IsCheckedProperty, rbTrueBinding);

var rbFalseBinding = new Binding("Value")
{
Mode = BindingMode.TwoWay,
Converter = new InverseBoolDisplay()
};
rbFalse.SetBinding(ToggleButton.IsCheckedProperty, rbFalseBinding);
}

public void Dispose()
{
// Nothing to dispose
}
}
}

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

Original file line number Diff line number Diff line change
Expand Up @@ -315,4 +315,10 @@ Dictionary&lt;string, List&lt;List&lt;double&gt;&gt;&gt;</value>
<data name="ResizeThumbToolTip" xml:space="preserve">
<value>Drag to modify the size of the chart</value>
</data>
<data name="GateClose" xml:space="preserve">
<value>Close</value>
</data>
<data name="GateOpen" xml:space="preserve">
<value>Open</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -315,4 +315,10 @@ Dictionary&lt;string, List&lt;List&lt;double&gt;&gt;&gt;</value>
<data name="ResizeThumbToolTip" xml:space="preserve">
<value>Drag to modify the size of the chart</value>
</data>
<data name="GateClose" xml:space="preserve">
<value>Close</value>
</data>
<data name="GateOpen" xml:space="preserve">
<value>Open</value>
</data>
</root>
3 changes: 3 additions & 0 deletions src/LibraryViewExtensionWebView2/web/library/layoutSpecs.json
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,9 @@
"iconUrl": "",
"elementType": "group",
"include": [
{
"path": "Core.Logic.Gate"
},
{
"path": "BuiltIn.LoopWhile"
},
Expand Down
75 changes: 75 additions & 0 deletions test/DynamoCoreWpfTests/GateTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using CoreNodeModels.Input;
using CoreNodeModels.Logic;
using Dynamo;
using Dynamo.Graph.Workspaces;
using Dynamo.Tests;
using DynamoCoreWpfTests.Utility;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SystemTestServices;

namespace DynamoCoreWpfTests
{
internal class GateTests : DynamoModelTestBase
{
protected override void GetLibrariesToPreload(List<string> libraries)
{
libraries.Add("FunctionObject.ds");
libraries.Add("DesignScriptBuiltin.dll");
libraries.Add("BuiltIn.ds");
libraries.Add("DSCPython.dll");
libraries.Add("FFITarget.dll");
}

[Test]
public void SettingNodeAsOpenPassesData()
{
string openPath = Path.Combine(TestDirectory, @"UI\UIGateNode.dyn");
RunModel(openPath);

Guid gateNodeGuid = Guid.Parse("0a4e291d93a84260bd9f37fde3158d83");
var gateNode = CurrentDynamoModel.CurrentWorkspace.NodeFromWorkspace(gateNodeGuid) as Gate;

Assert.AreEqual(false, gateNode.Value);

//Test that the downstream connected node IsNull is true
AssertPreviewValue("448ad21ed4af42b4ae71c45961a173ff", true);

//Open the gate node
gateNode.Value = true;

BeginRun();

//Test that the downstream connected node IsNull is now not null
AssertPreviewValue("448ad21ed4af42b4ae71c45961a173ff", false);
}

[Test]
public void SettingNodeAsClosedBlocksData()
{
string openPath = Path.Combine(TestDirectory, @"UI\UIGateNode.dyn");
RunModel(openPath);

Guid gateNodeGuid = Guid.Parse("e323a525bab546199c3635ce33c8c46b");
var gateNode = CurrentDynamoModel.CurrentWorkspace.NodeFromWorkspace(gateNodeGuid) as Gate;

Assert.AreEqual(true, gateNode.Value);

//Test that the downstream connected node IsNull is false
AssertPreviewValue("414438cdd24f4d74b08e462e0b17ddff", false);

//Open the gate node
gateNode.Value = false;

BeginRun();

//Test that the downstream connected node IsNull is now not null
AssertPreviewValue("414438cdd24f4d74b08e462e0b17ddff", true);
}
}
}
Loading
Loading