예제 #1
0
        /// <inheritdoc />
        public override void OnDestroy()
        {
            if (IsDisposing)
            {
                return;
            }
            if (_cmStateMachineMenu != null)
            {
                _cmStateMachineMenu.Dispose();
                _cmStateMachineMenu = null;
            }
            if (_cmStateMachineTransitionMenu != null)
            {
                _cmStateMachineTransitionMenu.Dispose();
                _cmStateMachineTransitionMenu = null;
            }
            if (_isRegisteredForScriptsReload)
            {
                _isRegisteredForScriptsReload      = false;
                ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
            }
            NodesCache.Wait();

            base.OnDestroy();
        }
예제 #2
0
        /// <inheritdoc />
        protected override void OnContextChanged()
        {
            base.OnContextChanged();

            VisjectCM menu = null;

            // Override surface primary context menu for state machine editing
            if (Context?.Context is Animation.StateMachine)
            {
                if (_cmStateMachineMenu == null)
                {
                    _cmStateMachineMenu = new VisjectCM(StateMachineGroupArchetypes, (arch) => true);
                    _cmStateMachineMenu.ShowExpanded = true;
                }
                menu = _cmStateMachineMenu;
            }

            // Override surface primary context menu for state machine transition editing
            if (Context?.Context is Animation.StateMachineTransition)
            {
                if (_cmStateMachineTransitionMenu == null)
                {
                    _cmStateMachineTransitionMenu = new VisjectCM(NodeFactory.DefaultGroups, CanSpawnNodeType, null, GetCustomNodes());
                    _cmStateMachineTransitionMenu.AddGroup(StateMachineTransitionGroupArchetype);
                }
                menu = _cmStateMachineTransitionMenu;
            }

            SetPrimaryMenu(menu);
        }
예제 #3
0
        /// <inheritdoc />
        protected override void OnShowPrimaryMenu(VisjectCM activeCM, Vector2 location, Box startBox)
        {
            Profiler.BeginEvent("Setup Anim Graph Context Menu");
            NodesCache.Get(activeCM);
            Profiler.EndEvent();

            base.OnShowPrimaryMenu(activeCM, location, startBox);

            activeCM.VisibleChanged += OnActiveContextMenuVisibleChanged;
        }
예제 #4
0
            public static void Get(VisjectCM contextMenu)
            {
                Wait();

                lock (_locker)
                {
                    if (_cache == null)
                    {
                        _cache = new Dictionary <KeyValuePair <string, ushort>, GroupArchetype>();
                    }
                    contextMenu.LockChildrenRecursive();

                    // Check if has cached groups
                    if (_cache.Count != 0)
                    {
                        // Check if context menu doesn't have the recent cached groups
                        if (!contextMenu.Groups.Any(g => g.Archetype.Tag is int asInt && asInt == _version))
                        {
                            var groups = contextMenu.Groups.Where(g => g.Archetype.Tag is int).ToArray();
                            foreach (var g in groups)
                            {
                                contextMenu.RemoveGroup(g);
                            }
                            foreach (var g in _cache.Values)
                            {
                                contextMenu.AddGroup(g);
                            }
                        }
                    }
                    else
                    {
                        // Remove any old groups from context menu
                        var groups = contextMenu.Groups.Where(g => g.Archetype.Tag is int).ToArray();
                        foreach (var g in groups)
                        {
                            contextMenu.RemoveGroup(g);
                        }

                        // Register for scripting types reload
                        Editor.Instance.CodeEditing.TypesCleared += OnCodeEditingTypesCleared;

                        // Run caching on an async
                        _task            = Task.Run(OnActiveContextMenuShowAsync);
                        _taskContextMenu = contextMenu;
                    }

                    contextMenu.UnlockChildrenRecursive();
                }
            }
예제 #5
0
        /// <inheritdoc />
        public override void Dispose()
        {
            if (_cmStateMachineMenu != null)
            {
                _cmStateMachineMenu.Dispose();
                _cmStateMachineMenu = null;
            }
            if (_cmStateMachineTransitionMenu != null)
            {
                _cmStateMachineTransitionMenu.Dispose();
                _cmStateMachineTransitionMenu = null;
            }

            base.Dispose();
        }
예제 #6
0
        /// <inheritdoc />
        protected override void OnShowPrimaryMenu(VisjectCM activeCM, Vector2 location, Box startBox)
        {
            // Check if show additional nodes in the current surface context
            if (activeCM != _cmStateMachineMenu)
            {
                Profiler.BeginEvent("Setup Anim Graph Context Menu");
                NodesCache.Get(activeCM);
                Profiler.EndEvent();

                base.OnShowPrimaryMenu(activeCM, location, startBox);

                activeCM.VisibleChanged += OnActiveContextMenuVisibleChanged;
            }
            else
            {
                base.OnShowPrimaryMenu(activeCM, location, startBox);
            }
        }
예제 #7
0
        /// <inheritdoc />
        public override void Dispose()
        {
            if (_cmStateMachineMenu != null)
            {
                _cmStateMachineMenu.Dispose();
                _cmStateMachineMenu = null;
            }
            if (_cmStateMachineTransitionMenu != null)
            {
                _cmStateMachineTransitionMenu.Dispose();
                _cmStateMachineTransitionMenu = null;
            }
            if (_isRegisteredForScriptsReload)
            {
                _isRegisteredForScriptsReload      = false;
                ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
            }

            base.Dispose();
        }
예제 #8
0
        /// <inheritdoc />
        protected override void OnContextChanged()
        {
            base.OnContextChanged();

            VisjectCM menu = null;

            // Override surface primary context menu for state machine editing
            if (Context?.Context is Animation.StateMachine)
            {
                if (_cmStateMachineMenu == null)
                {
                    _cmStateMachineMenu = new VisjectCM(new VisjectCM.InitInfo
                    {
                        Groups       = StateMachineGroupArchetypes,
                        CanSpawnNode = arch => true,
                    });
                    _cmStateMachineMenu.ShowExpanded = true;
                }
                menu = _cmStateMachineMenu;
            }

            // Override surface primary context menu for state machine transition editing
            if (Context?.Context is Animation.StateMachineTransition)
            {
                if (_cmStateMachineTransitionMenu == null)
                {
                    _cmStateMachineTransitionMenu = new VisjectCM(new VisjectCM.InitInfo
                    {
                        Groups           = NodeFactory.DefaultGroups,
                        CanSpawnNode     = CanUseNodeType,
                        ParametersGetter = null,
                        CustomNodesGroup = GetCustomNodes(),
                    });
                    _cmStateMachineTransitionMenu.AddGroup(StateMachineTransitionGroupArchetype);
                }
                menu = _cmStateMachineTransitionMenu;
            }

            SetPrimaryMenu(menu);
        }
        /// <summary>
        /// Sets the primary menu for the Visject nodes spawning. Can be overriden per surface or surface context. Set to null to restore the default menu.
        /// </summary>
        /// <param name="menu">The menu to override with (use null if restore the default value).</param>
        protected virtual void SetPrimaryMenu(VisjectCM menu)
        {
            menu = menu ?? _cmPrimaryMenu;

            if (menu == _activeVisjectCM)
            {
                return;
            }

            if (_activeVisjectCM != null)
            {
                _activeVisjectCM.ItemClicked    -= OnPrimaryMenuButtonClick;
                _activeVisjectCM.VisibleChanged -= OnPrimaryMenuVisibleChanged;
            }

            _activeVisjectCM = menu;

            if (_activeVisjectCM != null)
            {
                _activeVisjectCM.ItemClicked    += OnPrimaryMenuButtonClick;
                _activeVisjectCM.VisibleChanged += OnPrimaryMenuVisibleChanged;
            }
        }
예제 #10
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;
                }
            }
 /// <summary>
 /// Called when showing primary context menu.
 /// </summary>
 /// <param name="activeCM">The active context menu to show.</param>
 /// <param name="location">The display location on the surface control.</param>
 /// <param name="startBox">The start box.</param>
 protected virtual void OnShowPrimaryMenu(VisjectCM activeCM, Vector2 location, Box startBox)
 {
     activeCM.Show(this, location, startBox);
 }
예제 #12
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;
                }
            }