/// <summary>
 /// Initializes a new instance of the <see cref="CustomNodeSearchElement"/> class.
 /// </summary>
 /// <param name="customNodeManager">Custom node manager</param>
 /// <param name="info">Custom node info</param>
 public CustomNodeSearchElement(ICustomNodeSource customNodeManager, CustomNodeInfo info)
 {
     this.customNodeManager = customNodeManager;
     inputParameters = new List<Tuple<string, string>>();
     outputParameters = new List<string>();
     SyncWithCustomNodeInfo(info);
 }
        /// <summary>
        ///     Updates the properties of this search element.
        /// </summary>
        /// <param name="info">Actual data of custom node</param>        
        public void SyncWithCustomNodeInfo(CustomNodeInfo info)
        {
            ID = info.FunctionId;
            Name = info.Name;
            FullCategoryName = info.Category;
            Description = info.Description;
            Path = info.Path;
            iconName = ID.ToString();

            ElementType = ElementTypes.CustomNode;
            if (info.IsPackageMember)
                ElementType |= ElementTypes.Packaged; // Add one more flag.
        }
示例#3
0
        public void CanRefactorCustomNodeDescription()
        {
            const string nodeName = "TheNoodle";
            const string catName = "TheCat";
            const string descr = "TheCat";
            const string path = @"C:\turtle\graphics.dyn";
            var guid1 = Guid.NewGuid();
            var dummyInfo1 = new CustomNodeInfo(guid1, nodeName, catName, descr, path);
            var dummySearch1 = new CustomNodeSearchElement(null, dummyInfo1);

            search.Add(dummySearch1);

            Assert.AreEqual(1, search.NumElements);

            // search for name
            var results = search.Search(nodeName).ToList();

            // results are correct
            Assert.AreEqual(1, results.Count());
            var res1 = results[0];
            Assert.IsInstanceOf<CustomNodeSearchElement>(res1);
            Assert.AreEqual(guid1, ((CustomNodeSearchElement)res1).ID);

            // refactor description
            const string newDescription = "Tickle me elmo";
            var newInfo = new CustomNodeInfo(guid1, nodeName, catName, newDescription, path);
            dummySearch1.SyncWithCustomNodeInfo(newInfo);
            search.Update(dummySearch1);

            // num elements is unchanged
            Assert.AreEqual(1, search.NumElements);

            // search for name
            var results1 = search.Search(nodeName).ToList();

            // description is updated
            Assert.AreEqual(1, results1.Count());
            var res2 = results1[0];
            Assert.IsInstanceOf<CustomNodeSearchElement>(res2);
            Assert.AreEqual(guid1, ((CustomNodeSearchElement)res2).ID);
            Assert.AreEqual(newDescription, res2.Description);
        }
示例#4
0
        public void CanRefactorCustomNodeName()
        {
            const string nodeName = "TheNoodle";
            const string catName = "TheCat";
            const string descr = "TheCat";
            const string path = @"C:\turtle\graphics.dyn";
            var guid1 = Guid.NewGuid();
            var dummyInfo1 = new CustomNodeInfo(guid1, nodeName, catName, descr, path);
            var dummySearch1 = new CustomNodeSearchElement(null, dummyInfo1);

            search.Add(dummySearch1);

            Assert.AreEqual(1, search.NumElements);

            const string newNodeName = "TheTurtle";
            var newInfo = new CustomNodeInfo(guid1, newNodeName, catName, descr, path);
            dummySearch1.SyncWithCustomNodeInfo(newInfo);
            search.Update(dummySearch1);

            Assert.AreEqual(1, search.NumElements);

            // search for new name
            var results = search.Search(newNodeName).ToList();

            // results are correct
            Assert.AreEqual(1, results.Count());
            var res1 = results[0];
            Assert.IsInstanceOf<CustomNodeSearchElement>(res1);
            Assert.AreEqual(guid1, ((CustomNodeSearchElement)res1).ID);

            // search for old name
            var results1 = search.Search(nodeName);

            // results are correct
            Assert.AreEqual(0, results1.Count());
        }
示例#5
0
 /// <summary>
 ///     Attempts to retrieve information for the given custom node name. If there are multiple
 ///     custom nodes matching the given name, this method will return any one of them.
 /// </summary>
 /// <param name="name">Name of a custom node.</param>
 /// <param name="info"></param>
 /// <returns></returns>
 public bool TryGetNodeInfo(string name, out CustomNodeInfo info)
 {
     info = NodeInfos.Values.FirstOrDefault(x => x.Name == name);
     return(info != null);
 }
示例#6
0
        public void CanRemoveSingleCustomNodeByIdWhereThereAreDuplicatesWithDifferentIds()
        {
            const string nodeName = "TheNoodle";
            const string catName = "TheCat";
            const string descr = "TheCat";
            const string path = @"C:\turtle\graphics.dyn";
            var guid1 = Guid.NewGuid();
            var guid2 = Guid.NewGuid();
            var dummyInfo1 = new CustomNodeInfo(guid1, nodeName, catName, descr, path);
            var dummySearch1 = new CustomNodeSearchElement(null, dummyInfo1);
            var dummyInfo2 = new CustomNodeInfo(guid2, nodeName, catName, descr, path);
            var dummySearch2 = new CustomNodeSearchElement(null, dummyInfo2);

            search.Add(dummySearch1);
            search.Add(dummySearch2);
            Assert.AreEqual(2, search.NumElements);

            search.Remove(dummySearch2);
            Assert.AreEqual(1, search.NumElements);

            var results = search.Search(nodeName).ToList();
            Assert.AreEqual(1, results.Count());

            var res1 = results[0];
            Assert.IsInstanceOf<CustomNodeSearchElement>(res1);
            var node1 = (CustomNodeSearchElement)res1;
            Assert.AreEqual(node1.ID, guid1);
        }
示例#7
0
        public void CanAddDuplicateCustomNodeWithDifferentGuidsAndGetBothInResults()
        {
            const string nodeName = "TheNoodle";
            const string catName = "TheCat";
            const string descr = "TheCat";
            const string path = @"C:\turtle\graphics.dyn";
            var guid1 = Guid.NewGuid();
            var guid2 = Guid.NewGuid();
            var dummyInfo1 = new CustomNodeInfo(guid1, nodeName, catName, descr, path);
            var dummySearch1 = new CustomNodeSearchElement(null, dummyInfo1);
            var dummyInfo2 = new CustomNodeInfo(guid2, nodeName, catName, descr, path);
            var dummySearch2 = new CustomNodeSearchElement(null, dummyInfo2);

            search.Add(dummySearch1);
            search.Add(dummySearch2);
            Assert.AreEqual(2, search.NumElements);

            var results = search.Search(nodeName).ToList();
            Assert.AreEqual(2, results.Count());

            var resultIds = results.Cast<CustomNodeSearchElement>().Select(x => x.ID).ToList();
            Assert.IsTrue(resultIds.Contains(guid1));
            Assert.IsTrue(resultIds.Contains(guid2));

        }
示例#8
0
        public void CanRemoveNodeAndCategoryByFunctionId()
        {
            const string nodeName = "TheNoodle";
            const string catName = "TheCat";
            const string descr = "TheCat";
            const string path = @"C:\turtle\graphics.dyn";
            var guid1 = Guid.NewGuid();
            var dummyInfo1 = new CustomNodeInfo(guid1, nodeName, catName, descr, path);
            var dummySearch1 = new CustomNodeSearchElement(null, dummyInfo1);

            // add custom node
            search.Add(dummySearch1);
            // confirm it's in the dictionary
            Assert.AreEqual(1, search.NumElements);

            // remove custom node
            search.Remove(dummySearch1);
            // it's gone
            Assert.AreEqual(0, search.NumElements);

            var results = search.Search(nodeName);
            Assert.AreEqual(0, results.Count());
        }
示例#9
0
        /// <summary>
        /// Helper method for custom node adding and removing
        /// </summary>
        public static void AssertAddAndRemoveCustomNode(
            NodeSearchModel searchModel, string nodeName, string catName, string descr = "Bla",
            string path = "Bla")
        {
            var dummyInfo = new CustomNodeInfo(Guid.NewGuid(), nodeName, catName, descr, path);
            var dummySearch = new CustomNodeSearchElement(null, dummyInfo);
            searchModel.Add(dummySearch);

            var res = searchModel.Search(nodeName).ToList();
            Assert.AreNotEqual(0, res.Count());
            Assert.AreEqual(res[0].Name, nodeName);

            searchModel.Remove(dummySearch);
            res = searchModel.Search(nodeName).ToList();
            Assert.AreEqual(0, res.Count());
        }
示例#10
0
        public void CanRefactorCustomNodeWhilePreservingDuplicates()
        {
            const string nodeName = "TheNoodle";
            const string catName = "TheCat";
            const string descr = "TheCat";
            const string path = @"C:\turtle\graphics.dyn";
            var guid1 = Guid.NewGuid();
            var dummyInfo1 = new CustomNodeInfo(guid1, nodeName, catName, descr, path);
            var dummySearch1 = new CustomNodeSearchElement(null, dummyInfo1);
            var dummySearch2 = new CustomNodeSearchElement(null, dummyInfo1);

            search.Add(dummySearch1);
            search.Add(dummySearch2);

            Assert.AreEqual(2, search.NumElements);

            // refactor one of the nodes with newNodeName
            const string newNodeName = "TheTurtle";
            var newInfo = new CustomNodeInfo(guid1, newNodeName, catName, descr, path);
            dummySearch1.SyncWithCustomNodeInfo(newInfo);
            search.Update(dummySearch1);

            // num elements is unchanged
            Assert.AreEqual(2, search.NumElements);

            // search for new name
            var results = search.Search(newNodeName).ToList();

            // results are correct - only one result
            Assert.AreEqual(1, results.Count());
            var res1 = results[0];
            Assert.IsInstanceOf<CustomNodeSearchElement>(res1);
            Assert.AreSame(dummySearch1, res1);

            // search for old name
            results = search.Search(nodeName).ToList();

            // results are correct - the first nodes are returned
            Assert.AreEqual(1, results.Count());
            var res2 = results[0];
            Assert.IsInstanceOf<CustomNodeSearchElement>(res2);
            Assert.AreSame(dummySearch2, res2);
        }
示例#11
0
 internal bool Refactor(CustomNodeInfo nodeInfo)
 {
     this.RemoveNodeAndEmptyParentCategory(nodeInfo.Guid);
     return(this.Add(nodeInfo));
 }
示例#12
0
 public void Add(CustomNodeInfo nodeInfo)
 {
     this.Add(nodeInfo.Name, nodeInfo.Category, nodeInfo.Description, nodeInfo.Guid);
 }
示例#13
0
 /// <summary>
 ///     Attempts to retrieve information for the given custom node identifier.
 /// </summary>
 /// <param name="id">Custom node identifier.</param>
 /// <param name="info"></param>
 /// <returns>Success or failure.</returns>
 public bool TryGetNodeInfo(Guid id, out CustomNodeInfo info)
 {
     return(NodeInfos.TryGetValue(id, out info));
 }
示例#14
0
        public bool SyncWithWorkspace(DynamoModel dynamoModel, bool addToSearch, bool compileFunction)
        {

            // Get the internal nodes for the function
            var functionWorkspace = WorkspaceModel;

            try
            {
                // Add function defininition
                dynamoModel.CustomNodeManager.AddFunctionDefinition(FunctionId, this);

                // search
                if (addToSearch)
                {
                    AddToSearch(dynamoModel.SearchModel);
                }

                var info = new CustomNodeInfo(FunctionId, functionWorkspace.Name, functionWorkspace.Category,
                                              functionWorkspace.Description, WorkspaceModel.FileName);

                dynamoModel.CustomNodeManager.SetNodeInfo(info);
                Compile(dynamoModel, dynamoModel.EngineController);
            }
            catch (Exception e)
            {
                dynamoModel.Logger.Log("Error saving:" + e.GetType());
                dynamoModel.Logger.Log(e);
                return false;
            }

            return true;
        }
示例#15
0
 /// <summary>
 /// Stores the path and function definition without initializing a node.  Overwrites
 /// the existing NodeInfo if necessary
 /// </summary>
 private void SetNodeInfo(CustomNodeInfo newInfo)
 {
     NodeInfos[newInfo.FunctionId] = newInfo;
     OnInfoUpdated(newInfo);
 }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            NodeModel node = null;

            String typeName     = String.Empty;
            String functionName = String.Empty;
            String assemblyName = String.Empty;

            var  obj  = JObject.Load(reader);
            Type type = null;

            try
            {
                type     = Type.GetType(obj["$type"].Value <string>());
                typeName = obj["$type"].Value <string>().Split(',').FirstOrDefault();

                if (typeName.Equals("Dynamo.Graph.Nodes.ZeroTouch.DSFunction"))
                {
                    // If it is a zero touch node, then get the whole function name including the namespace.
                    functionName = obj["FunctionSignature"].Value <string>().Split('@').FirstOrDefault().Trim();
                }
                // we get the assembly name from the type string for the node model nodes.
                else
                {
                    assemblyName = obj["$type"].Value <string>().Split(',').Skip(1).FirstOrDefault().Trim();
                }
            }
            catch (Exception e)
            {
                nodeFactory?.AsLogger().Log(e);
            }
            // 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;

                // This assemblyName does not usually contain version information...
                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, typeName, assemblyName, functionName, 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;
                // Skip deserializing the Description Json property as the original one in dyf may
                // already be updated without syncing with the dyn
                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 lookupSignature    = libraryServices.GetFunctionSignatureFromFunctionSignatureHint(mangledName) ?? mangledName;
                var functionDescriptor = libraryServices.GetFunctionDescriptor(lookupSignature);

                // Use the functionDescriptor to try and restore the proper node if possible
                if (functionDescriptor == null)
                {
                    node = CreateDummyNode(obj, assemblyName, functionName, 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);
        }
示例#17
0
 public Package GetOwnerPackage(CustomNodeInfo def)
 {
     return(GetOwnerPackage(def.Path));
 }
示例#18
0
 public bool IsUnderPackageControl(CustomNodeInfo def)
 {
     return(IsUnderPackageControl(def.Path));
 }
示例#19
0
 internal void Refactor(CustomNodeInfo nodeInfo)
 {
     this.Remove(nodeInfo.Name);
     this.Add(nodeInfo);
 }
示例#20
0
        public bool SyncWithWorkspace(bool addToSearch, bool compileFunction)
        {
            // Get the internal nodes for the function
            var functionWorkspace = this.WorkspaceModel;

            try
            {
                // Add function defininition
                dynSettings.Controller.CustomNodeManager.AddFunctionDefinition(this.FunctionId, this);

                // search
                if (addToSearch)
                {
                    AddToSearch();
                }

                var info = new CustomNodeInfo(this.FunctionId, functionWorkspace.Name, functionWorkspace.Category,
                                              functionWorkspace.Description, this.WorkspaceModel.FileName);

                dynSettings.Controller.CustomNodeManager.SetNodeInfo(info);

                this.CompileAndAddToEnvironment(dynSettings.Controller.FSchemeEnvironment);
            }
            catch (Exception e)
            {
                DynamoLogger.Instance.Log("Error saving:" + e.GetType());
                DynamoLogger.Instance.Log(e);
                return false;
            }

            return true;
        }
示例#21
0
        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);
        }