public void Defect_MAGN_3166() { // Create the node with given information. NodeModel node = new DSVarArgFunction(CurrentDynamoModel.LibraryServices.GetFunctionDescriptor("DSCore.List.Join@var[]..[]")); CurrentDynamoModel.ExecuteCommand(new DynCmd.CreateNodeCommand(node, 0, 0, true, false)); var nodeGuid = node.GUID; // The node sound be found, and it should be a DSVarArgFunction. var workspace = CurrentDynamoModel.CurrentWorkspace; Assert.IsNotNull(node); // Delete the node and ensure it is gone. CurrentDynamoModel.ExecuteCommand(new DynCmd.DeleteModelCommand(nodeGuid)); node = workspace.NodeFromWorkspace(nodeGuid); Assert.IsNull(node); // Perform undo operation. var undoOperation = DynCmd.UndoRedoCommand.Operation.Undo; CurrentDynamoModel.ExecuteCommand(new DynCmd.UndoRedoCommand(undoOperation)); // Now that deletion is undone, ensure the node exists. node = workspace.NodeFromWorkspace(nodeGuid); Assert.IsNotNull(node); Assert.IsNotNull(node as DSVarArgFunction); }
public void CanCopyAndPasteDSVarArgFunctionNode() { var model = ViewModel.Model; Assert.AreEqual(0, model.CurrentWorkspace.Nodes.Count); const string dsVarArgFunctionName = "DSCore.String.Split@string,string[]"; var node = new DSVarArgFunction(model.LibraryServices.GetFunctionDescriptor(dsVarArgFunctionName)); model.CurrentWorkspace.AddNode(node, false); // Here we check to see if we do get a DSVarArgFunction node (which // is what this test case is written for, other nodes will render the // test case meaningless). // Assert.AreEqual(1, model.CurrentWorkspace.Nodes.Count); model.AddToSelection(node); // Select the only DSVarArgFunction node. model.Copy(); // Copy the only DSVarArgFunction node. Assert.DoesNotThrow(() => { model.Paste(); // Nope, paste should not crash Dynamo. }); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { NodeModel node = null; var obj = JObject.Load(reader); var type = Type.GetType(obj["$type"].Value <string>()); // If we can't find this type - try to look in our load from assemblies, // but only during testing - this is required during testing because some dlls are loaded // using Assembly.LoadFrom using the assemblyHelper - which loads dlls into loadFrom context - // dlls loaded with LoadFrom context cannot be found using Type.GetType() - this should // not be an issue during normal dynamo use but if it is we can enable this code. if (type == null && this.isTestMode == true) { List <Assembly> resultList; var typeName = obj["$type"].Value <string>().Split(',').FirstOrDefault(); // This assemblyName does not usually contain version information... var assemblyName = obj["$type"].Value <string>().Split(',').Skip(1).FirstOrDefault().Trim(); if (assemblyName != null) { if (this.loadedAssemblies.TryGetValue(assemblyName, out resultList)) { var matchingTypes = resultList.Select(x => x.GetType(typeName)).ToList(); type = matchingTypes.FirstOrDefault(); } } } // Check for and attempt to resolve an unknown type before proceeding if (type == null) { // Attempt to resolve the type using `AlsoKnownAs` var unresolvedName = obj["$type"].Value <string>().Split(',').FirstOrDefault(); Type newType; nodeFactory.ResolveType(unresolvedName, out newType); // If resolved update the type if (newType != null) { type = newType; } } // If the id is not a guid, makes a guid based on the id of the node var guid = GuidUtility.tryParseOrCreateGuid(obj["Id"].Value <string>()); var replication = obj["Replication"].Value <string>(); var inPorts = obj["Inputs"].ToArray().Select(t => t.ToObject <PortModel>()).ToArray(); var outPorts = obj["Outputs"].ToArray().Select(t => t.ToObject <PortModel>()).ToArray(); var resolver = (IdReferenceResolver)serializer.ReferenceResolver; string assemblyLocation = objectType.Assembly.Location; bool remapPorts = true; // If type is still null at this point return a dummy node if (type == null) { node = CreateDummyNode(obj, assemblyLocation, inPorts, outPorts); } // Attempt to create a valid node using the type else if (type == typeof(Function)) { var functionId = Guid.Parse(obj["FunctionSignature"].Value <string>()); CustomNodeDefinition def = null; CustomNodeInfo info = null; bool isUnresolved = !manager.TryGetCustomNodeData(functionId, null, false, out def, out info); Function function = manager.CreateCustomNodeInstance(functionId, null, false, def, info); node = function; if (isUnresolved) { function.UpdatePortsForUnresolved(inPorts, outPorts); } } else if (type == typeof(CodeBlockNodeModel)) { var code = obj["Code"].Value <string>(); CodeBlockNodeModel codeBlockNode = new CodeBlockNodeModel(code, guid, 0.0, 0.0, libraryServices, ElementResolver); node = codeBlockNode; // If the code block node is in an error state read the extra port data // and initialize the input and output ports if (node.IsInErrorState) { List <string> inPortNames = new List <string>(); var inputs = obj["Inputs"]; foreach (var input in inputs) { inPortNames.Add(input["Name"].ToString()); } // NOTE: This could be done in a simpler way, but is being implemented // in this manner to allow for possible future port line number // information being available in the file List <int> outPortLineIndexes = new List <int>(); var outputs = obj["Outputs"]; int outputLineIndex = 0; foreach (var output in outputs) { outPortLineIndexes.Add(outputLineIndex++); } codeBlockNode.SetErrorStatePortData(inPortNames, outPortLineIndexes); } } else if (typeof(DSFunctionBase).IsAssignableFrom(type)) { var mangledName = obj["FunctionSignature"].Value <string>(); var priorNames = libraryServices.GetPriorNames(); var functionDescriptor = libraryServices.GetFunctionDescriptor(mangledName); string newName; // Update the function descriptor if a newer migrated version of the node exists if (priorNames.TryGetValue(mangledName, out newName)) { functionDescriptor = libraryServices.GetFunctionDescriptor(newName); } // Use the functionDescriptor to try and restore the proper node if possible if (functionDescriptor == null) { node = CreateDummyNode(obj, assemblyLocation, inPorts, outPorts); } else { if (type == typeof(DSVarArgFunction)) { node = new DSVarArgFunction(functionDescriptor); // The node syncs with the function definition. // Then we need to make the inport count correct var varg = (DSVarArgFunction)node; varg.VarInputController.SetNumInputs(inPorts.Count()); } else if (type == typeof(DSFunction)) { node = new DSFunction(functionDescriptor); } } } else if (type == typeof(DSVarArgFunction)) { var functionId = Guid.Parse(obj["FunctionSignature"].Value <string>()); node = manager.CreateCustomNodeInstance(functionId); } else if (type.ToString() == "CoreNodeModels.Formula") { node = (NodeModel)obj.ToObject(type); } else { node = (NodeModel)obj.ToObject(type); // if node is an customNode input symbol - assign the element resolver. if (node is Nodes.CustomNodes.Symbol) { (node as Nodes.CustomNodes.Symbol).ElementResolver = ElementResolver; } // We don't need to remap ports for any nodes with json constructors which pass ports remapPorts = false; } if (remapPorts) { RemapPorts(node, inPorts, outPorts, resolver, manager.AsLogger()); } // Cannot set Lacing directly as property is protected node.UpdateValue(new UpdateValueParams("ArgumentLacing", replication)); node.GUID = guid; // Add references to the node and the ports to the reference resolver, // so that they are available for entities which are deserialized later. serializer.ReferenceResolver.AddReference(serializer.Context, node.GUID.ToString(), node); foreach (var p in node.InPorts) { serializer.ReferenceResolver.AddReference(serializer.Context, p.GUID.ToString(), p); } foreach (var p in node.OutPorts) { serializer.ReferenceResolver.AddReference(serializer.Context, p.GUID.ToString(), p); } return(node); }
public NodeModel CreateNodeFromXml(XmlElement nodeElement, SaveContext context, ElementResolver resolver) { string assembly = ""; string function; var nickname = nodeElement.Attributes["nickname"].Value; FunctionDescriptor descriptor; Trace.Assert(nodeElement.Attributes != null, "nodeElement.Attributes != null"); if (nodeElement.Attributes["assembly"] == null) { assembly = DetermineAssemblyName(nodeElement); function = nickname.Replace(".get", "."); } else { string xmlSignature = nodeElement.Attributes["function"].Value; string hintedSigniture = libraryServices.FunctionSignatureFromFunctionSignatureHint(xmlSignature); if (hintedSigniture != null) { nodeElement.Attributes["nickname"].Value = libraryServices.NicknameFromFunctionSignatureHint(xmlSignature); function = hintedSigniture; // if the node needs additional parameters, add them here libraryServices.AddAdditionalAttributesToNode(xmlSignature, nodeElement); libraryServices.AddAdditionalElementsToNode(xmlSignature, nodeElement); } else { function = xmlSignature; } var xmlAttribute = nodeElement.Attributes["assembly"]; if (xmlAttribute != null) { assembly = Uri.UnescapeDataString(xmlAttribute.Value); } } if (context == SaveContext.File && !string.IsNullOrEmpty(assembly)) { var document = nodeElement.OwnerDocument; var docPath = Nodes.Utilities.GetDocumentXmlPath(document); assembly = Nodes.Utilities.MakeAbsolutePath(docPath, assembly); if (libraryServices.IsLibraryLoaded(assembly)) { descriptor = libraryServices.GetFunctionDescriptor(assembly, function); } else { // If the desired assembly is not loaded already. Check if it belongs to BuiltInFunctionGroup. if (libraryServices.IsFunctionBuiltIn(assembly, nickname)) { descriptor = libraryServices.GetFunctionDescriptor(function); } else { // If neither of these, Dynamo need to import the library. try { libraryServices.ImportLibrary(assembly); descriptor = libraryServices.GetFunctionDescriptor(assembly, function); } catch (LibraryLoadFailedException) { descriptor = libraryServices.GetFunctionDescriptor(function); } } } } else { descriptor = libraryServices.GetFunctionDescriptor(function); } if (null == descriptor) { var inputcount = DetermineFunctionInputCount(nodeElement); return(new DummyNode( inputcount, 1, nickname, nodeElement, assembly, DummyNode.Nature.Unresolved)); } DSFunctionBase result; if (descriptor.IsVarArg) { result = new DSVarArgFunction(descriptor); var akas = typeof(DSVarArgFunction).GetCustomAttribute <AlsoKnownAsAttribute>().Values; if (nodeElement.Name != typeof(DSVarArgFunction).FullName && akas.All(aka => aka != nodeElement.Name)) { VariableInputNodeController.SerializeInputCount( nodeElement, descriptor.Parameters.Count()); } } else { result = new DSFunction(descriptor); } result.Deserialize(nodeElement, context); // In case of input parameters mismatch, use default arguments for parameters that have one if (!descriptor.MangledName.EndsWith(function)) { string[] oldSignature = function.Split('@'); string[] inputTypes = oldSignature.Length > 1 ? oldSignature[1].Split(',') : new string[] {}; int i = 0, j = 0; foreach (var param in descriptor.InputParameters) { if (i >= inputTypes.Length || param.Item2 != inputTypes[i]) { result.InPorts[j].UsingDefaultValue = result.InPorts[j].DefaultValue != null; } else { i++; } j++; } } return(result); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { NodeModel node = null; var obj = JObject.Load(reader); var type = Type.GetType(obj["$type"].Value <string>()); //if we can't find this type - try to look in our load from assemblies, //but only during testing - this is required during testing because some dlls are loaded //using Assembly.LoadFrom using the assemblyHelper - which loads dlls into loadFrom context - //dlls loaded with LoadFrom context cannot be found using Type.GetType() - this should //not be an issue during normal dynamo use but if it is we can enable this code. if (type == null && this.isTestMode == true) { List <Assembly> resultList; var typeName = obj["$type"].Value <string>().Split(',').FirstOrDefault(); //this assemblyName does not usually contain version information... var assemblyName = obj["$type"].Value <string>().Split(',').Skip(1).FirstOrDefault().Trim(); if (assemblyName != null) { if (this.loadedAssemblies.TryGetValue(assemblyName, out resultList)) { var matchingTypes = resultList.Select(x => x.GetType(typeName)).ToList(); type = matchingTypes.FirstOrDefault(); } } } // If the id is not a guid, makes a guid based on the id of the node var guid = GuidUtility.tryParseOrCreateGuid(obj["Id"].Value <string>()); var replication = obj["Replication"].Value <string>(); var inPorts = obj["Inputs"].ToArray().Select(t => t.ToObject <PortModel>()).ToArray(); var outPorts = obj["Outputs"].ToArray().Select(t => t.ToObject <PortModel>()).ToArray(); var resolver = (IdReferenceResolver)serializer.ReferenceResolver; string assemblyLocation = objectType.Assembly.Location; bool remapPorts = true; if (type == null) { node = CreateDummyNode(obj, assemblyLocation, inPorts, outPorts); } else if (type == typeof(Function)) { var functionId = Guid.Parse(obj["FunctionSignature"].Value <string>()); CustomNodeDefinition def = null; CustomNodeInfo info = null; bool isUnresolved = !manager.TryGetCustomNodeData(functionId, null, false, out def, out info); Function function = manager.CreateCustomNodeInstance(functionId, null, false, def, info); node = function; if (isUnresolved) { function.UpdatePortsForUnresolved(inPorts, outPorts); } } else if (type == typeof(CodeBlockNodeModel)) { var code = obj["Code"].Value <string>(); node = new CodeBlockNodeModel(code, guid, 0.0, 0.0, libraryServices, ElementResolver); } else if (typeof(DSFunctionBase).IsAssignableFrom(type)) { var mangledName = obj["FunctionSignature"].Value <string>(); var functionDescriptor = libraryServices.GetFunctionDescriptor(mangledName); if (functionDescriptor == null) { node = CreateDummyNode(obj, assemblyLocation, inPorts, outPorts); } else { if (type == typeof(DSVarArgFunction)) { node = new DSVarArgFunction(functionDescriptor); // The node syncs with the function definition. // Then we need to make the inport count correct var varg = (DSVarArgFunction)node; varg.VarInputController.SetNumInputs(inPorts.Count()); } else if (type == typeof(DSFunction)) { node = new DSFunction(functionDescriptor); } } } else if (type == typeof(DSVarArgFunction)) { var functionId = Guid.Parse(obj["FunctionSignature"].Value <string>()); node = manager.CreateCustomNodeInstance(functionId); } else if (type.ToString() == "CoreNodeModels.Formula") { node = (NodeModel)obj.ToObject(type); } else { node = (NodeModel)obj.ToObject(type); // We don't need to remap ports for any nodes with json constructors which pass ports remapPorts = false; } if (remapPorts) { RemapPorts(node, inPorts, outPorts, resolver); } // Cannot set Lacing directly as property is protected node.UpdateValue(new UpdateValueParams("ArgumentLacing", replication)); node.GUID = guid; // Add references to the node and the ports to the reference resolver, // so that they are available for entities which are deserialized later. serializer.ReferenceResolver.AddReference(serializer.Context, node.GUID.ToString(), node); foreach (var p in node.InPorts) { serializer.ReferenceResolver.AddReference(serializer.Context, p.GUID.ToString(), p); } foreach (var p in node.OutPorts) { serializer.ReferenceResolver.AddReference(serializer.Context, p.GUID.ToString(), p); } return(node); }
public void CanCopyAndPasteDSVarArgFunctionNode() { Assert.AreEqual(0, CurrentDynamoModel.CurrentWorkspace.Nodes.Count()); const string dsVarArgFunctionName = "DSCore.String.Split@string,string[]"; var node = new DSVarArgFunction(CurrentDynamoModel.LibraryServices.GetFunctionDescriptor(dsVarArgFunctionName)); CurrentDynamoModel.CurrentWorkspace.AddAndRegisterNode(node, false); // Here we check to see if we do get a DSVarArgFunction node (which // is what this test case is written for, other nodes will render the // test case meaningless). // Assert.AreEqual(1, CurrentDynamoModel.CurrentWorkspace.Nodes.Count()); CurrentDynamoModel.AddToSelection(node); // Select the only DSVarArgFunction node. CurrentDynamoModel.Copy(); // Copy the only DSVarArgFunction node. Assert.DoesNotThrow(() => { CurrentDynamoModel.Paste(); // Nope, paste should not crash Dynamo. }); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { NodeModel node = null; var obj = JObject.Load(reader); var type = Type.GetType(obj["$type"].Value <string>()); var guid = Guid.Parse(obj["Uuid"].Value <string>()); var displayName = obj["DisplayName"].Value <string>(); //var x = obj["X"].Value<double>(); //var y = obj["Y"].Value<double>(); var inPorts = obj["InputPorts"].ToArray().Select(t => t.ToObject <PortModel>()).ToArray(); var outPorts = obj["OutputPorts"].ToArray().Select(t => t.ToObject <PortModel>()).ToArray(); var resolver = (IdReferenceResolver)serializer.ReferenceResolver; if (type == typeof(Function)) { var functionId = Guid.Parse(obj["FunctionUuid"].Value <string>()); node = manager.CreateCustomNodeInstance(functionId); RemapPorts(node, inPorts, outPorts, resolver); } else if (type == typeof(CodeBlockNodeModel)) { var code = obj["Code"].Value <string>(); node = new CodeBlockNodeModel(code, guid, 0.0, 0.0, libraryServices, ElementResolver); RemapPorts(node, inPorts, outPorts, resolver); } else if (typeof(DSFunctionBase).IsAssignableFrom(type)) { var mangledName = obj["FunctionName"].Value <string>(); var description = libraryServices.GetFunctionDescriptor(mangledName); if (type == typeof(DSVarArgFunction)) { node = new DSVarArgFunction(description); // The node syncs with the function definition. // Then we need to make the inport count correct var varg = (DSVarArgFunction)node; varg.VarInputController.SetNumInputs(inPorts.Count()); } else if (type == typeof(DSFunction)) { node = new DSFunction(description); } RemapPorts(node, inPorts, outPorts, resolver); } else if (type == typeof(DSVarArgFunction)) { var functionId = Guid.Parse(obj["FunctionUuid"].Value <string>()); node = manager.CreateCustomNodeInstance(functionId); RemapPorts(node, inPorts, outPorts, resolver); } else if (type == typeof(Formula)) { node = (Formula)obj.ToObject(type); RemapPorts(node, inPorts, outPorts, resolver); } else { node = (NodeModel)obj.ToObject(type); } node.GUID = guid; node.NickName = displayName; //node.X = x; //node.Y = y; // Add references to the node and the ports to the reference resolver, // so that they are available for entities which are deserialized later. serializer.ReferenceResolver.AddReference(serializer.Context, node.GUID.ToString(), node); foreach (var p in node.InPorts) { serializer.ReferenceResolver.AddReference(serializer.Context, p.GUID.ToString(), p); } foreach (var p in node.OutPorts) { serializer.ReferenceResolver.AddReference(serializer.Context, p.GUID.ToString(), p); } return(node); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { NodeModel node = null; var obj = JObject.Load(reader); var type = Type.GetType(obj["$type"].Value<string>()); var guid = Guid.Parse(obj["Uuid"].Value<string>()); var displayName = obj["DisplayName"].Value<string>(); //var x = obj["X"].Value<double>(); //var y = obj["Y"].Value<double>(); var inPorts = obj["InputPorts"].ToArray().Select(t => t.ToObject<PortModel>()).ToArray(); var outPorts = obj["OutputPorts"].ToArray().Select(t => t.ToObject<PortModel>()).ToArray(); var resolver = (IdReferenceResolver)serializer.ReferenceResolver; if (type == typeof(Function)) { var functionId = Guid.Parse(obj["FunctionUuid"].Value<string>()); node = manager.CreateCustomNodeInstance(functionId); RemapPorts(node, inPorts, outPorts, resolver); } else if(type == typeof(CodeBlockNodeModel)) { var code = obj["Code"].Value<string>(); node = new CodeBlockNodeModel(code, guid, 0.0, 0.0, libraryServices, ElementResolver); RemapPorts(node, inPorts, outPorts, resolver); } else if(typeof(DSFunctionBase).IsAssignableFrom(type)) { var mangledName = obj["FunctionName"].Value<string>(); var description = libraryServices.GetFunctionDescriptor(mangledName); if(type == typeof(DSVarArgFunction)) { node = new DSVarArgFunction(description); // The node syncs with the function definition. // Then we need to make the inport count correct var varg = (DSVarArgFunction)node; varg.VarInputController.SetNumInputs(inPorts.Count()); } else if(type == typeof(DSFunction)) { node = new DSFunction(description); } RemapPorts(node, inPorts, outPorts, resolver); } else if (type == typeof(DSVarArgFunction)) { var functionId = Guid.Parse(obj["FunctionUuid"].Value<string>()); node = manager.CreateCustomNodeInstance(functionId); RemapPorts(node, inPorts, outPorts, resolver); } else { node = (NodeModel)obj.ToObject(type); } node.GUID = guid; node.NickName = displayName; //node.X = x; //node.Y = y; // Add references to the node and the ports to the reference resolver, // so that they are available for entities which are deserialized later. serializer.ReferenceResolver.AddReference(serializer.Context, node.GUID.ToString(), node); foreach(var p in node.InPorts) { serializer.ReferenceResolver.AddReference(serializer.Context, p.GUID.ToString(), p); } foreach (var p in node.OutPorts) { serializer.ReferenceResolver.AddReference(serializer.Context, p.GUID.ToString(), p); } return node; }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { NodeModel node = null; var obj = JObject.Load(reader); var type = Type.GetType(obj["$type"].Value <string>()); // If the id is not a guid, makes a guid based on the id of the node var guid = GuidUtility.tryParseOrCreateGuid(obj["Id"].Value <string>()); var replication = obj["Replication"].Value <string>(); var inPorts = obj["Inputs"].ToArray().Select(t => t.ToObject <PortModel>()).ToArray(); var outPorts = obj["Outputs"].ToArray().Select(t => t.ToObject <PortModel>()).ToArray(); var resolver = (IdReferenceResolver)serializer.ReferenceResolver; string assemblyLocation = objectType.Assembly.Location; bool remapPorts = true; if (type == null) { node = CreateDummyNode(obj, assemblyLocation, inPorts, outPorts); } else if (type == typeof(Function)) { var functionId = Guid.Parse(obj["FunctionSignature"].Value <string>()); CustomNodeDefinition def = null; CustomNodeInfo info = null; bool isUnresolved = !manager.TryGetCustomNodeData(functionId, null, false, out def, out info); Function function = manager.CreateCustomNodeInstance(functionId, null, false, def, info); node = function; if (isUnresolved) { function.UpdatePortsForUnresolved(inPorts, outPorts); } } else if (type == typeof(CodeBlockNodeModel)) { var code = obj["Code"].Value <string>(); node = new CodeBlockNodeModel(code, guid, 0.0, 0.0, libraryServices, ElementResolver); } else if (typeof(DSFunctionBase).IsAssignableFrom(type)) { var mangledName = obj["FunctionSignature"].Value <string>(); var functionDescriptor = libraryServices.GetFunctionDescriptor(mangledName); if (functionDescriptor == null) { node = CreateDummyNode(obj, assemblyLocation, inPorts, outPorts); } else { if (type == typeof(DSVarArgFunction)) { node = new DSVarArgFunction(functionDescriptor); // The node syncs with the function definition. // Then we need to make the inport count correct var varg = (DSVarArgFunction)node; varg.VarInputController.SetNumInputs(inPorts.Count()); } else if (type == typeof(DSFunction)) { node = new DSFunction(functionDescriptor); } } } else if (type == typeof(DSVarArgFunction)) { var functionId = Guid.Parse(obj["FunctionSignature"].Value <string>()); node = manager.CreateCustomNodeInstance(functionId); } else if (type.ToString() == "CoreNodeModels.Formula") { node = (NodeModel)obj.ToObject(type); } else { node = (NodeModel)obj.ToObject(type); // We don't need to remap ports for any nodes with json constructors which pass ports remapPorts = false; } if (remapPorts) { RemapPorts(node, inPorts, outPorts, resolver); } // Cannot set Lacing directly as property is protected node.UpdateValue(new UpdateValueParams("ArgumentLacing", replication)); node.GUID = guid; // Add references to the node and the ports to the reference resolver, // so that they are available for entities which are deserialized later. serializer.ReferenceResolver.AddReference(serializer.Context, node.GUID.ToString(), node); foreach (var p in node.InPorts) { serializer.ReferenceResolver.AddReference(serializer.Context, p.GUID.ToString(), p); } foreach (var p in node.OutPorts) { serializer.ReferenceResolver.AddReference(serializer.Context, p.GUID.ToString(), p); } return(node); }
public NodeModel CreateNodeFromXml(XmlElement nodeElement, SaveContext context) { string assembly = ""; string function; var nickname = nodeElement.Attributes["nickname"].Value; FunctionDescriptor descriptor; Trace.Assert(nodeElement.Attributes != null, "nodeElement.Attributes != null"); if (nodeElement.Attributes["assembly"] == null) { assembly = DetermineAssemblyName(nodeElement); function = nickname.Replace(".get", "."); } else { string xmlSignature = nodeElement.Attributes["function"].Value; string hintedSigniture = libraryServices.FunctionSignatureFromFunctionSignatureHint(xmlSignature); if (hintedSigniture != null) { nodeElement.Attributes["nickname"].Value = libraryServices.NicknameFromFunctionSignatureHint(xmlSignature); function = hintedSigniture; // if the node needs additional parameters, add them here if (libraryServices.FunctionSignatureNeedsAdditionalAttributes(xmlSignature)) { libraryServices.AddAdditionalAttributesToNode(xmlSignature, nodeElement); } if (libraryServices.FunctionSignatureNeedsAdditionalElements(xmlSignature)) { libraryServices.AddAdditionalElementsToNode(xmlSignature, nodeElement); } } else { function = xmlSignature; } var xmlAttribute = nodeElement.Attributes["assembly"]; if (xmlAttribute != null) { assembly = Uri.UnescapeDataString(xmlAttribute.Value); } } if (context == SaveContext.File && !string.IsNullOrEmpty(assembly)) { var document = nodeElement.OwnerDocument; var docPath = Nodes.Utilities.GetDocumentXmlPath(document); assembly = Nodes.Utilities.MakeAbsolutePath(docPath, assembly); descriptor = libraryServices.IsLibraryLoaded(assembly) || libraryServices.ImportLibrary(assembly) ? libraryServices.GetFunctionDescriptor(assembly, function) : libraryServices.GetFunctionDescriptor(function); } else { descriptor = libraryServices.GetFunctionDescriptor(function); } if (null == descriptor) { var inputcount = DetermineFunctionInputCount(nodeElement); return(new DummyNode( inputcount, 1, nickname, nodeElement, assembly, DummyNode.Nature.Unresolved)); } DSFunctionBase result; if (descriptor.IsVarArg) { result = new DSVarArgFunction(descriptor); if (nodeElement.Name != typeof(DSVarArgFunction).FullName) { VariableInputNodeController.SerializeInputCount( nodeElement, descriptor.Parameters.Count()); } } else { result = new DSFunction(descriptor); } result.Deserialize(nodeElement, context); return(result); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { NodeModel node = null; var obj = JObject.Load(reader); var type = Type.GetType(obj["$type"].Value <string>()); //if the id is not a guid, makes a guid based on the id of the node var guid = GuidUtility.tryParseOrCreateGuid(obj["Id"].Value <string>()); var replication = obj["Replication"].Value <string>(); var inPorts = obj["Inputs"].ToArray().Select(t => t.ToObject <PortModel>()).ToArray(); var outPorts = obj["Outputs"].ToArray().Select(t => t.ToObject <PortModel>()).ToArray(); var resolver = (IdReferenceResolver)serializer.ReferenceResolver; if (type == typeof(Function)) { var functionId = Guid.Parse(obj["FunctionUuid"].Value <string>()); node = manager.CreateCustomNodeInstance(functionId); RemapPorts(node, inPorts, outPorts, resolver); } else if (type == typeof(CodeBlockNodeModel)) { var code = obj["Code"].Value <string>(); node = new CodeBlockNodeModel(code, guid, 0.0, 0.0, libraryServices, ElementResolver); RemapPorts(node, inPorts, outPorts, resolver); } else if (typeof(DSFunctionBase).IsAssignableFrom(type)) { var mangledName = obj["FunctionSignature"].Value <string>(); var description = libraryServices.GetFunctionDescriptor(mangledName); if (type == typeof(DSVarArgFunction)) { node = new DSVarArgFunction(description); // The node syncs with the function definition. // Then we need to make the inport count correct var varg = (DSVarArgFunction)node; varg.VarInputController.SetNumInputs(inPorts.Count()); } else if (type == typeof(DSFunction)) { node = new DSFunction(description); } RemapPorts(node, inPorts, outPorts, resolver); } else if (type == typeof(DSVarArgFunction)) { var functionId = Guid.Parse(obj["FunctionUuid"].Value <string>()); node = manager.CreateCustomNodeInstance(functionId); RemapPorts(node, inPorts, outPorts, resolver); } else if (type.ToString() == "CoreNodeModels.Formula") { node = (NodeModel)obj.ToObject(type); RemapPorts(node, inPorts, outPorts, resolver); } else { node = (NodeModel)obj.ToObject(type); } //cannot set Lacing directly as property is protected node.UpdateValue(new UpdateValueParams("ArgumentLacing", replication)); node.GUID = guid; // Add references to the node and the ports to the reference resolver, // so that they are available for entities which are deserialized later. serializer.ReferenceResolver.AddReference(serializer.Context, node.GUID.ToString(), node); foreach (var p in node.InPorts) { serializer.ReferenceResolver.AddReference(serializer.Context, p.GUID.ToString(), p); } foreach (var p in node.OutPorts) { serializer.ReferenceResolver.AddReference(serializer.Context, p.GUID.ToString(), p); } return(node); }