Exemple #1
0
        protected override void ConstructFieldTemplates(NodeProvider nodeProvider, Dictionary <Type, NodeFieldTemplate> templates)
        {
            NodeLibrary library = nodeProvider.GetNodeLibrary();

            foreach (var nodeTemplate in library.nodeTemplates)
            {
                Type type = nodeTemplate.RuntimeNodeType;

                var template = new NodeFieldTemplate();
                var fields   = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

                foreach (var field in fields)
                {
                    bool isPrivate = field.IsPrivate;

                    if (IsOutput(field))
                    {
                        template.OutputPorts.Add(new Ports.PortDescription(field.Name, field.FieldType, PortDirection.Output, false, false));
                    }
                    else if (IsInput(field))
                    {
                        template.OutputPorts.Add(new Ports.PortDescription(field.Name, field.FieldType, PortDirection.Input, false, false));
                    }
                    else
                    {
                        template.Properties.Add(new PropertyDescription {
                            FieldType = field
                        });
                    }
                }

                templates.Add(type, template);
            }
        }
Exemple #2
0
        protected override void ConstructFieldTemplates(NodeProvider nodeProvider, Dictionary <Type, NodeFieldTemplate> templates)
        {
            NodeLibrary library = nodeProvider.GetNodeLibrary();

            foreach (var nodeTemplate in library.nodeTemplates)
            {
                Type type     = nodeTemplate.RuntimeNodeType;
                var  fields   = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                var  template = new NodeFieldTemplate();

                var supressInput = type.GetCustomAttribute <SupressInputAttribute>();

                // All tasks (nodes in this case) need to have an input, that isnt in the code of the behaviours
                // so we just add it in the first thing we do.
                if (supressInput == null)
                {
                    template.InputPorts.Add(new PortDescription("Input", typeof(Task), PortDirection.Input, false, false));
                }

                foreach (var field in fields)
                {
                    OutputAttribute output   = field.GetCustomAttribute <OutputAttribute>();
                    InputAttribute  input    = field.GetCustomAttribute <InputAttribute>();
                    SerializeField  property = field.GetCustomAttribute <SerializeField>();

                    bool autoAdd  = false;
                    bool isInput  = input == null ? false : true;
                    bool isOutput = output == null ? false : true;

                    if (output != null)
                    {
                        autoAdd = output.AutoAddPortOnConnect;
                    }
                    if (input != null)
                    {
                        autoAdd = input.AutoAddPortOnConnect;
                    }

                    bool isList = IsListType(field);

                    if (output != null || input != null)
                    {
                        if (IsListType(field))
                        {
                            AddGenericPort(template, field, isInput, isOutput, autoAdd);
                        }
                        else
                        {
                            AddNonGenericPort(template, field.FieldType, field.Name, field.Name, isInput, isOutput, autoAdd);
                        }
                    }
                    else if (property != null)
                    {
                        AddNonGenericProperty(template, field, field.Name, field.Name);
                    }
                }
                templates.Add(type, template);
            }
        }
        public List <SearchTreeEntry> CreateSearchTree(SearchWindowContext context)
        {
            // First build up temporary data structure containing group & title as an array of strings (the last one is the actual title) and associated node type.
            if (m_nodeProvider == null)
            {
                Debug.LogError("NodeProvider in Node Search Window is null cant construct search tree!");
                return(new List <SearchTreeEntry>());
            }

            NodeLibrary nodeLibrary = m_nodeProvider.GetNodeLibrary();

            // Sort the entries lexicographically by group then title with the requirement that items always comes before sub-groups in the same group.
            // Example result:
            // - Art/BlendMode
            // - Art/Adjustments/ColorBalance
            // - Art/Adjustments/Contrast
            nodeLibrary.nodeTemplates.Sort((entry1, entry2) =>
            {
                for (var i = 0; i < entry1.Title.Length; i++)
                {
                    if (i >= entry2.Title.Length)
                    {
                        return(1);
                    }
                    var value = entry1.Title[i].CompareTo(entry2.Title[i]);
                    if (value != 0)
                    {
                        // Make sure that leaves go before nodes
                        if (entry1.Title.Length != entry2.Title.Length && (i == entry1.Title.Length - 1 || i == entry2.Title.Length - 1))
                        {
                            return(entry1.Title.Length < entry2.Title.Length ? -1 : 1);
                        }
                        return(value);
                    }
                }
                return(0);
            });

            //* Build up the data structure needed by SearchWindow.

            // `groups` contains the current group path we're in.
            var groups = new List <string>();

            // First item in the tree is the title of the window.
            var tree = new List <SearchTreeEntry>
            {
                new SearchTreeGroupEntry(new GUIContent("Add Node"), 0),
            };

            foreach (var nodeEntry in nodeLibrary.nodeTemplates)
            {
                // `createIndex` represents from where we should add new group entries from the current entry's group path.
                var createIndex = int.MaxValue;

                // Compare the group path of the current entry to the current group path.
                for (var i = 0; i < nodeEntry.Title.Length - 1; i++)
                {
                    var group = nodeEntry.Title[i];
                    if (i >= groups.Count)
                    {
                        // The current group path matches a prefix of the current entry's group path, so we add the
                        // rest of the group path from the currrent entry.
                        createIndex = i;
                        break;
                    }
                    if (groups[i] != group)
                    {
                        // A prefix of the current group path matches a prefix of the current entry's group path,
                        // so we remove everyfrom from the point where it doesn't match anymore, and then add the rest
                        // of the group path from the current entry.
                        groups.RemoveRange(i, groups.Count - i);
                        createIndex = i;
                        break;
                    }
                }

                // Create new group entries as needed.
                // If we don't need to modify the group path, `createIndex` will be `int.MaxValue` and thus the loop won't run.
                for (var i = createIndex; i < nodeEntry.Title.Length - 1; i++)
                {
                    var group = nodeEntry.Title[i];
                    groups.Add(group);
                    tree.Add(new SearchTreeGroupEntry(new GUIContent(group))
                    {
                        level = i + 1
                    });
                }

                // Finally, add the actual entry.
                tree.Add(new SearchTreeEntry(new GUIContent(nodeEntry.Title.Last(), m_icon))
                {
                    level = nodeEntry.Title.Length, userData = nodeEntry
                });
            }

            return(tree);
        }