Ejemplo n.º 1
0
        /// <summary>
        /// Creates the node.
        /// </summary>
        /// <param name="id">The node id.</param>
        /// <param name="context">The context.</param>
        /// <param name="groupArchetype">The group archetype.</param>
        /// <param name="nodeArchetype">The node archetype.</param>
        /// <returns>Created node or null if failed.</returns>
        public static SurfaceNode CreateNode(uint id, VisjectSurfaceContext context, GroupArchetype groupArchetype, NodeArchetype nodeArchetype)
        {
            Assert.IsTrue(groupArchetype.Archetypes.Contains(nodeArchetype));

            SurfaceNode node;

            if (nodeArchetype.Create != null)
            {
                node = nodeArchetype.Create(id, context, nodeArchetype, groupArchetype);
            }
            else
            {
                node = new SurfaceNode(id, context, nodeArchetype, groupArchetype);
            }
            return(node);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Spawns the node.
        /// </summary>
        /// <param name="groupArchetype">The group archetype.</param>
        /// <param name="nodeArchetype">The node archetype.</param>
        /// <param name="location">The location.</param>
        /// <param name="customValues">The custom values array. Must match node archetype <see cref="NodeArchetype.DefaultValues"/> size. Pass null to use default values.</param>
        /// <returns>Created node.</returns>
        public SurfaceNode SpawnNode(GroupArchetype groupArchetype, NodeArchetype nodeArchetype, Vector2 location, object[] customValues = null)
        {
            if (groupArchetype == null || nodeArchetype == null)
            {
                throw new ArgumentNullException();
            }

            if (!_surface.CanSpawnNodeType(nodeArchetype))
            {
                Editor.LogWarning("Cannot spawn given node type.");
                return(null);
            }

            var id = GetFreeNodeID();

            // Create node
            var node = NodeFactory.CreateNode(id, this, groupArchetype, nodeArchetype);

            if (node == null)
            {
                Editor.LogWarning("Failed to create node.");
                return(null);
            }
            Nodes.Add(node);

            // Initialize
            if (customValues != null)
            {
                if (node.Values != null && node.Values.Length == customValues.Length)
                {
                    Array.Copy(customValues, node.Values, customValues.Length);
                }
                else
                {
                    throw new InvalidOperationException("Invalid node custom values.");
                }
            }
            OnControlLoaded(node);
            node.OnSurfaceLoaded();
            node.Location = location;
            OnControlSpawned(node);

            MarkAsModified();

            return(node);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SurfaceNode"/> class.
        /// </summary>
        /// <param name="id">The node id.</param>
        /// <param name="context">The surface context.</param>
        /// <param name="nodeArch">The node archetype.</param>
        /// <param name="groupArch">The group archetype.</param>
        public SurfaceNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch)
            : base(context, nodeArch.Size.X + Constants.NodeMarginX * 2, nodeArch.Size.Y + Constants.NodeMarginY * 2 + Constants.NodeHeaderSize + Constants.NodeFooterSize)
        {
            Title          = nodeArch.Title;
            ID             = id;
            Archetype      = nodeArch;
            GroupArchetype = groupArch;
            AutoFocus      = false;
            TooltipText    = nodeArch.Description;
            CullChildren   = false;

            if (Archetype.DefaultValues != null)
            {
                Values = new object[Archetype.DefaultValues.Length];
                Array.Copy(Archetype.DefaultValues, Values, Values.Length);
            }
        }
Ejemplo n.º 4
0
            private static void OnActiveContextMenuShowAsync()
            {
                Profiler.BeginEvent("Setup Anim Graph Context Menu (async)");

                foreach (var scriptType in Editor.Instance.CodeEditing.All.Get())
                {
                    if (!SurfaceUtils.IsValidVisualScriptType(scriptType))
                    {
                        continue;
                    }

                    // Skip Newtonsoft.Json stuff
                    var scriptTypeTypeName = scriptType.TypeName;
                    if (scriptTypeTypeName.StartsWith("Newtonsoft.Json."))
                    {
                        continue;
                    }
                    var scriptTypeName = scriptType.Name;

                    // Enum
                    if (scriptType.IsEnum)
                    {
                        // Create node archetype
                        var node = (NodeArchetype)Archetypes.Constants.Nodes[10].Clone();
                        node.DefaultValues[0] = Activator.CreateInstance(scriptType.Type);
                        node.Flags           &= ~NodeFlags.NoSpawnViaGUI;
                        node.Title            = scriptTypeName;
                        node.Description      = Editor.Instance.CodeDocs.GetTooltip(scriptType);

                        // Create group archetype
                        var groupKey = new KeyValuePair <string, ushort>(scriptTypeName, 2);
                        if (!_cache.TryGetValue(groupKey, out var group))
                        {
                            group = new GroupArchetype
                            {
                                GroupID    = groupKey.Value,
                                Name       = groupKey.Key,
                                Color      = new Color(243, 156, 18),
                                Tag        = _version,
                                Archetypes = new List <NodeArchetype>(),
                            };
                            _cache.Add(groupKey, group);
                        }

                        // Add node to the group
                        ((IList <NodeArchetype>)group.Archetypes).Add(node);
                        continue;
                    }

                    // Structure
                    if (scriptType.IsValueType)
                    {
                        if (scriptType.IsVoid)
                        {
                            continue;
                        }

                        // Create group archetype
                        var groupKey = new KeyValuePair <string, ushort>(scriptTypeName, 4);
                        if (!_cache.TryGetValue(groupKey, out var group))
                        {
                            group = new GroupArchetype
                            {
                                GroupID    = groupKey.Value,
                                Name       = groupKey.Key,
                                Color      = new Color(155, 89, 182),
                                Tag        = _version,
                                Archetypes = new List <NodeArchetype>(),
                            };
                            _cache.Add(groupKey, group);
                        }

                        var tooltip = Editor.Instance.CodeDocs.GetTooltip(scriptType);

                        // Create Pack node archetype
                        var node = (NodeArchetype)Archetypes.Packing.Nodes[6].Clone();
                        node.DefaultValues[0] = scriptTypeTypeName;
                        node.Flags           &= ~NodeFlags.NoSpawnViaGUI;
                        node.Title            = "Pack " + scriptTypeName;
                        node.Description      = tooltip;
                        ((IList <NodeArchetype>)group.Archetypes).Add(node);

                        // Create Unpack node archetype
                        node = (NodeArchetype)Archetypes.Packing.Nodes[13].Clone();
                        node.DefaultValues[0] = scriptTypeTypeName;
                        node.Flags           &= ~NodeFlags.NoSpawnViaGUI;
                        node.Title            = "Unpack " + scriptTypeName;
                        node.Description      = tooltip;
                        ((IList <NodeArchetype>)group.Archetypes).Add(node);
                    }
                }

                // Add group to context menu (on a main thread)
                FlaxEngine.Scripting.InvokeOnUpdate(() =>
                {
                    lock (_locker)
                    {
                        _taskContextMenu.AddGroups(_cache.Values);
                        _taskContextMenu = null;
                    }
                });

                Profiler.EndEvent();

                lock (_locker)
                {
                    _task = null;
                }
            }
Ejemplo n.º 5
0
        /// <summary>
        /// Gets the archetypes for the node.
        /// </summary>
        /// <param name="groups">The group archetypes.</param>
        /// <param name="groupID">The group identifier.</param>
        /// <param name="typeID">The type identifier.</param>
        /// <param name="gArch">The output group archetype.</param>
        /// <param name="arch">The output node archetype.</param>
        /// <returns>True if found it, otherwise false.</returns>
        public static bool GetArchetype(List <GroupArchetype> groups, ushort groupID, ushort typeID, out GroupArchetype gArch, out NodeArchetype arch)
        {
            gArch = null;
            arch  = null;

            // Find archetype for that node
            foreach (var groupArchetype in groups)
            {
                if (groupArchetype.GroupID == groupID && groupArchetype.Archetypes != null)
                {
                    foreach (var nodeArchetype in groupArchetype.Archetypes)
                    {
                        if (nodeArchetype.TypeID == typeID)
                        {
                            // Found
                            gArch = groupArchetype;
                            arch  = nodeArchetype;
                            return(true);
                        }
                    }
                }
            }

            // Error
            Editor.LogError($"Failed to create Visject Surface node with id: {groupID}:{typeID}");
            return(false);
        }
Ejemplo n.º 6
0
            private static void OnActiveContextMenuShowAsync()
            {
                Profiler.BeginEvent("Setup Visual Script Context Menu (async)");
#if DEBUG_INVOKE_METHODS_SEARCHING || DEBUG_FIELDS_SEARCHING
                var searchStartTime = DateTime.Now;
                var searchHitsCount = 0;
#endif

                foreach (var scriptType in Editor.Instance.CodeEditing.All.Get())
                {
                    if (!SurfaceUtils.IsValidVisualScriptType(scriptType))
                    {
                        continue;
                    }

                    // Skip Newtonsoft.Json stuff
                    var scriptTypeTypeName = scriptType.TypeName;
                    if (scriptTypeTypeName.StartsWith("Newtonsoft.Json."))
                    {
                        continue;
                    }
                    var scriptTypeName = scriptType.Name;

                    // Enum
                    if (scriptType.IsEnum)
                    {
                        // Create node archetype
                        var node = (NodeArchetype)Archetypes.Constants.Nodes[10].Clone();
                        node.DefaultValues[0] = Activator.CreateInstance(scriptType.Type);
                        node.Flags           &= ~NodeFlags.NoSpawnViaGUI;
                        node.Title            = scriptTypeName;
                        node.Description      = scriptTypeTypeName;
                        var attributes       = scriptType.GetAttributes(false);
                        var tooltipAttribute = (TooltipAttribute)attributes.FirstOrDefault(x => x is TooltipAttribute);
                        if (tooltipAttribute != null)
                        {
                            node.Description += "\n" + tooltipAttribute.Text;
                        }

                        // Create group archetype
                        var groupKey = new KeyValuePair <string, ushort>(scriptTypeName, 2);
                        if (!_cache.TryGetValue(groupKey, out var group))
                        {
                            group = new GroupArchetype
                            {
                                GroupID    = groupKey.Value,
                                Name       = groupKey.Key,
                                Color      = new Color(243, 156, 18),
                                Tag        = _version,
                                Archetypes = new List <NodeArchetype>(),
                            };
                            _cache.Add(groupKey, group);
                        }

                        // Add node to the group
                        ((IList <NodeArchetype>)group.Archetypes).Add(node);
                        continue;
                    }

                    // Structure
                    if (scriptType.IsValueType)
                    {
                        if (scriptType.IsVoid)
                        {
                            continue;
                        }

                        // Create group archetype
                        var groupKey = new KeyValuePair <string, ushort>(scriptTypeName, 4);
                        if (!_cache.TryGetValue(groupKey, out var group))
                        {
                            group = new GroupArchetype
                            {
                                GroupID    = groupKey.Value,
                                Name       = groupKey.Key,
                                Color      = new Color(155, 89, 182),
                                Tag        = _version,
                                Archetypes = new List <NodeArchetype>(),
                            };
                            _cache.Add(groupKey, group);
                        }

                        var attributes       = scriptType.GetAttributes(false);
                        var tooltipAttribute = (TooltipAttribute)attributes.FirstOrDefault(x => x is TooltipAttribute);

                        // Create Pack node archetype
                        var node = (NodeArchetype)Archetypes.Packing.Nodes[6].Clone();
                        node.DefaultValues[0] = scriptTypeTypeName;
                        node.Flags           &= ~NodeFlags.NoSpawnViaGUI;
                        node.Title            = "Pack " + scriptTypeName;
                        node.Description      = scriptTypeTypeName;
                        if (tooltipAttribute != null)
                        {
                            node.Description += "\n" + tooltipAttribute.Text;
                        }
                        ((IList <NodeArchetype>)group.Archetypes).Add(node);

                        // Create Unpack node archetype
                        node = (NodeArchetype)Archetypes.Packing.Nodes[13].Clone();
                        node.DefaultValues[0] = scriptTypeTypeName;
                        node.Flags           &= ~NodeFlags.NoSpawnViaGUI;
                        node.Title            = "Unpack " + scriptTypeName;
                        node.Description      = scriptTypeTypeName;
                        if (tooltipAttribute != null)
                        {
                            node.Description += "\n" + tooltipAttribute.Text;
                        }
                        ((IList <NodeArchetype>)group.Archetypes).Add(node);
                    }

                    foreach (var member in scriptType.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly))
                    {
                        if (member.IsGeneric)
                        {
                            continue;
                        }

                        if (member.IsMethod)
                        {
                            // Skip methods not declared in this type
                            if (member.Type is MethodInfo m && m.GetBaseDefinition().DeclaringType != m.DeclaringType)
                            {
                                continue;
                            }
                            var name = member.Name;
                            if (name == "ToString")
                            {
                                continue;
                            }

                            // Skip if searching by name doesn't return a match
                            var members = scriptType.GetMembers(name, MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
                            if (!members.Contains(member))
                            {
                                continue;
                            }

                            // Check if method is valid for Visual Script usage
                            if (SurfaceUtils.IsValidVisualScriptInvokeMethod(member, out var parameters))
                            {
                                // Create node archetype
                                var node = (NodeArchetype)Archetypes.Function.Nodes[3].Clone();
                                node.DefaultValues[0] = scriptTypeTypeName;
                                node.DefaultValues[1] = name;
                                node.DefaultValues[2] = parameters.Length;
                                node.Flags           &= ~NodeFlags.NoSpawnViaGUI;
                                node.Title            = SurfaceUtils.GetMethodDisplayName((string)node.DefaultValues[1]);
                                node.Description      = SurfaceUtils.GetVisualScriptMemberInfoDescription(member);
                                node.SubTitle         = string.Format(" (in {0})", scriptTypeName);
                                node.Tag = member;

                                // Create group archetype
                                var groupKey = new KeyValuePair <string, ushort>(scriptTypeName, 16);
                                if (!_cache.TryGetValue(groupKey, out var group))
                                {
                                    group = new GroupArchetype
                                    {
                                        GroupID    = groupKey.Value,
                                        Name       = groupKey.Key,
                                        Color      = new Color(109, 160, 24),
                                        Tag        = _version,
                                        Archetypes = new List <NodeArchetype>(),
                                    };
                                    _cache.Add(groupKey, group);
                                }

                                // Add node to the group
                                ((IList <NodeArchetype>)group.Archetypes).Add(node);
#if DEBUG_INVOKE_METHODS_SEARCHING
                                Editor.LogWarning(scriptTypeTypeName + " -> " + member.GetSignature());
                                searchHitsCount++;
#endif
                            }
                        }
                        else if (member.IsField)
                        {
                            var name = member.Name;

                            // Skip if searching by name doesn't return a match
                            var members = scriptType.GetMembers(name, MemberTypes.Field, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
                            if (!members.Contains(member))
                            {
                                continue;
                            }

                            // Check if field is valid for Visual Script usage
                            if (SurfaceUtils.IsValidVisualScriptField(member))
                            {
                                if (member.HasGet)
                                {
                                    // Create node archetype
                                    var node = (NodeArchetype)Archetypes.Function.Nodes[6].Clone();
                                    node.DefaultValues[0] = scriptTypeTypeName;
                                    node.DefaultValues[1] = name;
                                    node.DefaultValues[2] = member.ValueType.TypeName;
                                    node.DefaultValues[3] = member.IsStatic;
                                    node.Flags           &= ~NodeFlags.NoSpawnViaGUI;
                                    node.Title            = "Get " + name;
                                    node.Description      = SurfaceUtils.GetVisualScriptMemberInfoDescription(member);
                                    node.SubTitle         = string.Format(" (in {0})", scriptTypeName);

                                    // Create group archetype
                                    var groupKey = new KeyValuePair <string, ushort>(scriptTypeName, 16);
                                    if (!_cache.TryGetValue(groupKey, out var group))
                                    {
                                        group = new GroupArchetype
                                        {
                                            GroupID    = groupKey.Value,
                                            Name       = groupKey.Key,
                                            Color      = new Color(109, 160, 24),
                                            Tag        = _version,
                                            Archetypes = new List <NodeArchetype>(),
                                        };
                                        _cache.Add(groupKey, group);
                                    }

                                    // Add node to the group
                                    ((IList <NodeArchetype>)group.Archetypes).Add(node);
#if DEBUG_FIELDS_SEARCHING
                                    Editor.LogWarning(scriptTypeTypeName + " -> Get " + member.GetSignature());
                                    searchHitsCount++;
#endif
                                }
                                if (member.HasSet)
                                {
                                    // Create node archetype
                                    var node = (NodeArchetype)Archetypes.Function.Nodes[7].Clone();
                                    node.DefaultValues[0] = scriptTypeTypeName;
                                    node.DefaultValues[1] = name;
                                    node.DefaultValues[2] = member.ValueType.TypeName;
                                    node.DefaultValues[3] = member.IsStatic;
                                    node.Flags           &= ~NodeFlags.NoSpawnViaGUI;
                                    node.Title            = "Set " + name;
                                    node.Description      = SurfaceUtils.GetVisualScriptMemberInfoDescription(member);
                                    node.SubTitle         = string.Format(" (in {0})", scriptTypeName);

                                    // Create group archetype
                                    var groupKey = new KeyValuePair <string, ushort>(scriptTypeName, 16);
                                    if (!_cache.TryGetValue(groupKey, out var group))
                                    {
                                        group = new GroupArchetype
                                        {
                                            GroupID    = groupKey.Value,
                                            Name       = groupKey.Key,
                                            Color      = new Color(109, 160, 24),
                                            Tag        = _version,
                                            Archetypes = new List <NodeArchetype>(),
                                        };
                                        _cache.Add(groupKey, group);
                                    }

                                    // Add node to the group
                                    ((IList <NodeArchetype>)group.Archetypes).Add(node);
#if DEBUG_FIELDS_SEARCHING
                                    Editor.LogWarning(scriptTypeTypeName + " -> Set " + member.GetSignature());
                                    searchHitsCount++;
#endif
                                }
                            }
                        }
                    }
                }

                // Add group to context menu (on a main thread)
                FlaxEngine.Scripting.InvokeOnUpdate(() =>
                {
#if DEBUG_INVOKE_METHODS_SEARCHING || DEBUG_FIELDS_SEARCHING
                    var addStartTime = DateTime.Now;
#endif
                    lock (_locker)
                    {
                        _taskContextMenu.AddGroups(_cache.Values);
                        _taskContextMenu = null;
                    }
#if DEBUG_INVOKE_METHODS_SEARCHING || DEBUG_FIELDS_SEARCHING
                    Editor.LogError($"Added items to VisjectCM in: {(DateTime.Now - addStartTime).TotalMilliseconds} ms");
#endif
                });

#if DEBUG_INVOKE_METHODS_SEARCHING || DEBUG_FIELDS_SEARCHING
                Editor.LogError($"Collected {searchHitsCount} items in: {(DateTime.Now - searchStartTime).TotalMilliseconds} ms");
#endif
                Profiler.EndEvent();

                lock (_locker)
                {
                    _task = null;
                }
            }