Skip to content

Commit

Permalink
Merge branch 'master' into AddNullableType
Browse files Browse the repository at this point in the history
  • Loading branch information
saintentropy authored Nov 13, 2023
2 parents 29f6136 + f0cd05c commit fc202fb
Show file tree
Hide file tree
Showing 23 changed files with 866 additions and 8 deletions.
17 changes: 17 additions & 0 deletions src/DynamoCore/Configuration/GraphChecksumItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.ObjectModel;
using Dynamo.Core;
using Dynamo.Properties;

namespace Dynamo.Configuration
{
/// <summary>
/// Represents the stringified version of the nodes connections from a graph
/// </summary>
public class GraphChecksumItem
{
public string GraphId { get; set; }

public string Checksum { get; set; }
}
}
6 changes: 6 additions & 0 deletions src/DynamoCore/Configuration/IPreferences.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Dynamo.Configuration;
using Dynamo.Graph.Connectors;

namespace Dynamo.Interfaces
Expand Down Expand Up @@ -146,6 +147,11 @@ public interface IPreferences
/// <param name="name">Background preview name</param>
/// <param name="value">Active state to set</param>
void SetIsBackgroundPreviewActive(string name, bool value);

/// <summary>
/// Return a list of GraphChecksumItems
/// </summary>
List<GraphChecksumItem> GraphChecksumItemsList { get; set; }
}

/// <summary>
Expand Down
13 changes: 13 additions & 0 deletions src/DynamoCore/Configuration/PreferenceSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,11 @@ public bool DisableTrustWarnings
/// </summary>
private List<string> trustedLocations { get; set; } = new List<string>();

/// <summary>
/// Return a list of GraphChecksumItems
/// </summary>
public List<GraphChecksumItem> GraphChecksumItemsList { get; set; }

// This function is used to deserialize the trusted locations manually
// so that the TrustedLocation propertie's setter does not need to be public.
private List<string> DeserializeTrustedLocations(XmlNode preferenceSettingsElement)
Expand Down Expand Up @@ -835,6 +840,12 @@ public string IronPythonResolveTargetVersion

#region Dynamo Player and Generative Design settings

/// <summary>
/// Enable legacy behavior for Dynamo Player to allow renamed Watch nodes to be seen as graph output.
/// This flag is for use in the 2024 product release year and can removed for 2025
/// </summary>
public bool EnableDynamoPlayerRenamedWatchAsOutput { get; set; }

/// <summary>
/// Collections of folders used by individual Dynamo Player or Generative Design as entry points.
/// </summary>
Expand Down Expand Up @@ -906,8 +917,10 @@ public PreferenceSettings()
ViewExtensionSettings = new List<ViewExtensionSettings>();
GroupStyleItemsList = new List<GroupStyleItem>();
ReadNotificationIds = new List<string>();
EnableDynamoPlayerRenamedWatchAsOutput = false;
DynamoPlayerFolderGroups = new List<DynamoPlayerFolderGroup>();
backupLocation = string.Empty;
GraphChecksumItemsList = new List<GraphChecksumItem>();
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2013,7 +2013,7 @@ internal bool IsValidForFDX
{
get
{
return !HasErrors && !HasNoneGeometryRelatedWarnings;
return Nodes.Count() > 1 && !HasErrors && !HasNoneGeometryRelatedWarnings;
}
}

Expand Down
43 changes: 40 additions & 3 deletions src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2090,15 +2090,52 @@ internal bool CanSaveAs(object parameters)
return (parameters != null);
}

/// <summary>
/// Indicates if the graph has been changed substantially bearing in mind the connections of its nodes and store the checksum value of the graph in the preferences to later comparison
/// </summary>
/// <returns></returns>
private bool HasSubstantialCheckSum()
{
bool substantialChecksum = false;
string graphId = Model.CurrentWorkspace.Guid.ToString();

GraphChecksumItem checksumItem = PreferenceSettings.GraphChecksumItemsList.Where(i => i.GraphId == graphId).FirstOrDefault();
if (checksumItem != null)
{
if (checksumItem.Checksum != currentWorkspaceViewModel.Checksum)
{
PreferenceSettings.GraphChecksumItemsList.Remove(checksumItem);
PreferenceSettings.GraphChecksumItemsList.Add(new GraphChecksumItem() { GraphId = graphId, Checksum = currentWorkspaceViewModel.Checksum });
substantialChecksum = true;
}
}
else
{
PreferenceSettings.GraphChecksumItemsList.Add(new GraphChecksumItem() { GraphId = graphId, Checksum = currentWorkspaceViewModel.Checksum });
substantialChecksum = true;
}
return substantialChecksum;
}

private void InternalSaveAs(string path, SaveContext saveContext, bool isBackup = false)
{
try
{
Model.Logger.Log(String.Format(Properties.Resources.SavingInProgress, path));
CurrentSpaceViewModel.Save(path, isBackup, Model.EngineController, saveContext);
if (!isBackup) AddToRecentFiles(path);
if (currentWorkspaceViewModel?.IsHomeSpace ?? true)
Model.Logger.Log("The Workspace is valid for FDX : " + (HomeSpace.HasRunWithoutCrash && Model.CurrentWorkspace.IsValidForFDX).ToString());

if (!isBackup)
{
AddToRecentFiles(path);

if ((currentWorkspaceViewModel?.IsHomeSpace ?? true) && HomeSpace.HasRunWithoutCrash && Model.CurrentWorkspace.IsValidForFDX && currentWorkspaceViewModel.Checksum != string.Empty)
{
Model.Logger.Log("The Workspace is valid for FDX");
Model.Logger.Log("The Workspace id is : " + currentWorkspaceViewModel.Model.Guid.ToString());
Model.Logger.Log("The Workspace checksum is : " + currentWorkspaceViewModel.Checksum);
Model.Logger.Log("The Workspace has Substantial checksum, so is ready to send to FDX : " + HasSubstantialCheckSum().ToString());
}
}
}
catch (Exception ex)
{
Expand Down
113 changes: 110 additions & 3 deletions src/DynamoCoreWpf/ViewModels/Core/WorkspaceViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,106 @@ public bool IsHomeSpace
get { return Model == DynamoViewModel.HomeSpace; }
}

/// <summary>
/// Returns the Json representation of the current graph
/// </summary>
[JsonIgnore]
internal JObject JsonRepresentation { get; set; }

/// <summary>
/// Returns the stringified representation of the connected nodes
/// </summary>
[JsonIgnore]
public string Checksum
{
get
{
List<string> nodeInfoConnections = new List<string>();
JObject jsonWorkspace = JsonRepresentation;
var nodes = jsonWorkspace["Nodes"];

List<string> nodeIds = new List<string>();
foreach (JObject node in nodes)
{
var nodeProperties = node.Children<JProperty>();
JProperty id = nodeProperties.FirstOrDefault(x => x.Name == "Id");
nodeIds.Add(id.Value.ToString());
}

nodeIds.Sort();

foreach (string nodeId in nodeIds)
{
List<string> outputIds = new List<string>();
var node = jsonWorkspace["Nodes"].Where(t => t.Value<string>("Id") == nodeId).Select(t => t).FirstOrDefault();
var outputsProperty = node.Children<JProperty>().FirstOrDefault(x => x.Name == "Outputs");
var outputs = (JArray)outputsProperty.Value;
int outputIndex = 1;

foreach (JObject output in outputs)
{
var outputProperties = output.Children<JProperty>();
JProperty outputId = outputProperties.FirstOrDefault(x => x.Name == "Id");
outputIds.Add(outputId.Value.ToString());

var connectorsProperty = jsonWorkspace["Connectors"].Where(t => t.Value<string>("Start") == outputId.Value.ToString());

foreach (var connector in connectorsProperty)
{
var connectorProperties = connector.Children<JProperty>();
JProperty endProperty = connectorProperties.FirstOrDefault(x => x.Name == "End");
string inputId = (String)endProperty.Value;

var outputConnectedNode = GetNodeByInputId(inputId, jsonWorkspace);
nodeInfoConnections.Add(nodeId + "|[" + outputIndex.ToString() + "|" + outputConnectedNode.Item1 + "|" + outputConnectedNode.Item2.ToString() + "]");
}
outputIndex++;
}
}
return nodeInfoConnections.Count > 0 ? string.Join(",", nodeInfoConnections) : string.Empty;
}
}

Tuple<string,int> GetNodeByInputId(string inputId, JObject jsonWorkspace)
{
var nodes = jsonWorkspace["Nodes"];

string nodeId = string.Empty;
int connectedInputIndex = 1;
bool foundNode = false;

foreach (var node in nodes)
{
if (!foundNode)
{
nodeId = string.Empty;
connectedInputIndex = 1;

var nodeProperties = node.Children<JProperty>();
JProperty nodeProperty = nodeProperties.FirstOrDefault(x => x.Name == "Id");
nodeId = (String)nodeProperty.Value;

JProperty nodeInputs = nodeProperties.FirstOrDefault(x => x.Name == "Inputs");
var inputs = (JArray)nodeInputs.Value;

foreach (JObject input in inputs)
{
var inputProperties = input.Children<JProperty>();
JProperty connectedNodeInputId = inputProperties.FirstOrDefault(x => x.Name == "Id");

if ((String)connectedNodeInputId.Value == inputId)
{
foundNode = true;
break;
}
connectedInputIndex++;
}
}
}

return new Tuple<string, int>(nodeId, connectedInputIndex);
}

[JsonIgnore]
public bool HasUnsavedChanges
{
Expand Down Expand Up @@ -652,19 +752,26 @@ internal void Save(string filePath, bool isBackup = false, EngineController engi
}
}
}

saveContent = GuidUtility.UpdateWorkspaceGUIDs(jo.ToString());
saveContent = GuidUtility.UpdateWorkspaceGUIDs(jo.ToString());
}
else
{
saveContent = jo.ToString();
}
}

File.WriteAllText(filePath, saveContent);

// Handle Workspace or CustomNodeWorkspace related non-serialization internal logic
// Only for actual save, update file path and recent file list
// The assignation of the JsonRepresentation and Guid is only for the checksum flow, it will grab info only from .dyn files
if (!isBackup)
{
if (Path.GetExtension(filePath).Equals(".dyn"))
{
JsonRepresentation = JObject.Parse(saveContent);
DynamoViewModel.Workspaces[0].Model.Guid = new Guid(JsonRepresentation.Properties().First(p => p.Name == "Uuid").Value.ToString());
}

Model.FileName = filePath;
Model.OnSaved();
}
Expand Down
44 changes: 44 additions & 0 deletions src/Libraries/CoreNodeModels/CoreNodeModelsImages.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,50 @@
f66KxdT5Mc9gSmp03qAW9gD5lfwobNUbvjVjAU0UNacLobgfWBUOJrhkXnc2pc08O3uXcsnTdV1Kw+dw
IPQxh9M1WA0uyLqE0AAGIW/Key8ihlALTQmXWtgG1VZGV7BDhxVyKQowQnFEcOlzsDI4jR14HIzwmO9p
2zaJFT8arCiKovwdxnwAzk7Zcq1S2RAAAAAASUVORK5CYII=
</value>
</data>
<data name="CoreNodeModels.Logic.Gate.Large" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</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
wgAADsIBFShKgAAAAXpJREFUWEftlTFLw0AYhiO66CKORV10qKCbm0ObxCJWXATFQZ39Aa4iKIibkMRS
EBER/AWCjuKkYLeC3qVaFwen+hd8Gr6AlVpTjB00Dzyk35e768sl5IyEhISvqNVqRTyyXD2ecyvd0m6b
cB0po8MkhRUCvOEzXtiuv2J6OpU5qPbIsG8J15EyOkyq4j1/XDIdnbFcf4rf23iFZTzGJdPVQzKlKeE6
UkbnQ4Cy5egJaRszp69dlqP66U/jDpZQYRHz2YJqeFyxB2gG91PsxAJj73Be2gEdCRDC2C0e1ZqUAZ0O
sIvLUgZ0OIDa4/1YlDLgTwSov+FpabfktwI8Wp4elXZLkgD/OwBfwjRjzwkxJ62AOAI8EWBE2g3Ynh7m
/jpe4y1u2EUd+1nwYntqUNoGJ+MArtK/xBvctDw1lt1vPIRC4grA9qo8nrHVmt4h10kZ2pI4AtSwfj3B
nOn4fTIkEj8JUEDOeH/Wch96pd024TpSJiQkfMIw3gFrUwF9tuj5yAAAAABJRU5ErkJggg==
</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]) };
}
}
}
Loading

0 comments on commit fc202fb

Please sign in to comment.