Пример #1
0
        /// <summary>
        /// Checks if inspected contains any targets that equal null, and if so,
        /// attempts to recover references to them. Any targets that remain null
        /// after these attempts get removed from the inspected array.
        /// </summary>
        /// <returns> True if there were no null targets, or any null targets could be recovered. Returns false if there were unrecoverable null targets. </returns>
        public bool TryRecoverAnyNullUnityObjects()
        {
            bool noUnfixableNullsFound = true;

            for (int n = inspected.Length - 1; n >= 0; n--)
            {
                var target = inspected[n];
                if (target == null)
                {
                    if (UnityObjectExtensions.TryToFixNull(ref target))
                    {
                                                #if DEV_MODE
                        Debug.LogWarning("InspectorState.inspected[" + n + "] (\"" + target.name + "\") was null, but was able to recover it using InstanceID.");
                                                #endif
                        continue;
                    }

                                        #if DEV_MODE
                    Debug.LogWarning("InspectorState.inspected[" + n + "] (\"" + (ReferenceEquals(target, null) ? "null" : target.name) + "\") was null and unrecoverable. Removing from array");
                                        #endif

                    // if could not recover target, remove null entry from array
                    inspected             = inspected.RemoveAt(n);
                    noUnfixableNullsFound = false;
                }
            }
            return(noUnfixableNullsFound);
        }
Пример #2
0
        /// <summary>
        /// Invokes the Method, messages the user about it and updates results member if method has a return value.
        /// </summary>
        /// <param name="pingIfUnityObject"> True if should "ping" the return value, if the method has one, and it's of type UnityEngine.Object  or UnityEngine.Object[], and not null or empty. </param>
        /// <param name="displayDialogIfNotUnityObject"> True if should display a popup dialog to the user about the results, if method has a return type, and it's not of type UnityEngine.Object or UnityEngine.Object[]. </param>
        /// <param name="copyToClipboardIfNotPingedOrDialogShown"> True if should copy the method return value to clipboard, if it has one, and if value was not pinged and popup was not displayed. </param>
        ///  <param name="pingIfUnityObject"> True if should select the return value(s), if the method has one, and it's of type UnityEngine.Object  or UnityEngine.Object[], and not null or empty. </param>
        private void Invoke(bool pingIfUnityObject, bool displayDialogIfNotUnityObject, bool copyToClipboardIfNotPingedOrDialogShown, bool selectIfUnityObject)
        {
            Inspector.RefreshView();             // make sure repaint gets called immediately

            string error;
            bool   suppressMessages = pingIfUnityObject || displayDialogIfNotUnityObject || copyToClipboardIfNotPingedOrDialogShown || selectIfUnityObject;

            Invoke(out error, suppressMessages);

            if (!hasReturnValue)
            {
                                #if DEV_MODE && PI_ASSERTATIONS
                Debug.Assert(!suppressMessages);
                                #endif
                return;
            }

            if (pingIfUnityObject)
            {
                var list = new List <Object>(0);
                if (UnityObjectExtensions.TryExtractObjectReferences(results, ref list))
                {
                    DrawGUI.Ping(list.ToArray());
                }
            }

            if (selectIfUnityObject)
            {
                var list = new List <Object>(0);
                if (UnityObjectExtensions.TryExtractObjectReferences(results, ref list))
                {
                    Inspector.Select(list.ToArray());
                }
            }

            if (displayDialogIfNotUnityObject && !isCoroutine)
            {
                TryDisplayDialogForResult();
            }
            else if (copyToClipboardIfNotPingedOrDialogShown)
            {
                Clipboard.Copy(result);
            }

            if (Event.current != null)
            {
                ExitGUIUtility.ExitGUI();                 // avoid ArgumentException: Getting control 1's position in a group with only 1 controls when doing repaint
            }
        }
Пример #3
0
        /// <inheritdoc/>
        public void OnProjectOrHierarchyChanged(OnChangedEventSubject changed, ref bool hasNullReferences)
        {
            if (changed != OnChangedEventSubject.Project && changed != OnChangedEventSubject.Undefined)
            {
                return;
            }

            for (int n = targets.Length - 1; n >= 0; n--)
            {
                var target = targets[n];
                if (target == null)
                {
                    if (UnityObjectExtensions.TryToFixNull(ref target))
                    {
                                                #if DEV_MODE
                        Debug.LogWarning(ToString() + ".OnHierarchyChanged fixed targets[" + n + "] (\"" + target.name + "\") being null.");
                                                #endif
                        continue;
                    }

                                        #if DEV_MODE
                    Debug.Log(ToString() + ".OnHierarchyChanged targets[" + n + "] was null and could not be fixed.");
                                        #endif

                    hasNullReferences = true;
                }
            }

                        #if UNITY_EDITOR
            if (editor != null && Editors.DisposeIfInvalid(ref editor))
            {
                hasNullReferences = true;                 // set to true so that drawers get rebuilt, in case e.g. asset paths have changed.
            }

            if (assetEditor != null && Editors.DisposeIfInvalid(ref assetEditor))
            {
                hasNullReferences = true;                 // set to true so that drawers get rebuilt, in case e.g. asset paths have changed.
            }
                        #endif

            FetchAssetEditor();
            UpdateEditor();
        }
Пример #4
0
        private bool TryPingResult()
        {
            if (!hasReturnValue)
            {
                return(false);
            }

            if (!hasResult)
            {
                Invoke();
            }

            var list = new List <Object>(0);

            if (UnityObjectExtensions.TryExtractObjectReferences(results, ref list))
            {
                DrawGUI.Ping(list.ToArray());
            }
            return(true);
        }
Пример #5
0
        public void RemoveUnloadedAndInvalidTargets()
        {
                        #if DEV_MODE && DEBUG_REMOVE_INVALID
            Debug.Log("SelectionHistory.RemoveReferencesToUnloadedOrInvalidScenes()");
                        #endif

            int count = history.Count;
            for (int n = count - 1; n >= 0; n--)
            {
                var objs = history[n];

                for (int o = objs.Length - 1; o >= 0; o--)
                {
                    var obj = objs[o];
                    if (obj == null)
                    {
                        if (!UnityObjectExtensions.TryToFixNull(ref obj))
                        {
                                                        #if DEV_MODE && DEBUG_REMOVE_INVALID
                            Debug.Log("Removing history[" + n + "][" + o + "]: because target no longer exists");
                                                        #endif

                            objs = objs.RemoveAt(o);
                        }
                    }
                }

                if (objs.Length == 0)
                {
                    history.RemoveAt(n);
                    if (currentIndex > n)
                    {
                        currentIndex--;
                    }

                                        #if DEV_MODE && DEBUG_REMOVE_INVALID
                    Debug.Log("Removed history[" + n + "] because none of the targets existed any longer. Index now " + index + " nad history.Count=" + history.Count);
                                        #endif
                }
            }
        }
Пример #6
0
        /// <inheritdoc/>
        public override bool DrawPrefix(Rect position)
        {
            if (Event.current.type == EventType.Repaint)
            {
                //hide prefix resizer line behind the field
                DrawGUI.Active.ColorRect(lastDrawPosition, DrawGUI.Active.InspectorBackgroundColor);

                if (backgroundRect.width > 0f)
                {
                    GUI.Label(backgroundRect, "", InspectorPreferences.Styles.MethodBackground);
                }
            }

            bool drawBackgroundBehindFoldoutsWas = DrawGUI.drawBackgroundBehindFoldouts;

            DrawGUI.drawBackgroundBehindFoldouts = false;

            var prefixDrawRect      = PrefixLabelPosition;
            var clipLabelInsideRect = prefixDrawRect;

            clipLabelInsideRect.width += clipLabelInsideRect.x;
            clipLabelInsideRect.x      = 0f;
            prefixDrawRect.y           = 0f;

            //use BeginArea to prevent foldout text clipping past the Button
            GUILayout.BeginArea(clipLabelInsideRect);
            bool dirty = base.DrawPrefix(prefixDrawRect);

            GUILayout.EndArea();

            DrawGUI.drawBackgroundBehindFoldouts = drawBackgroundBehindFoldoutsWas;

            bool selected    = Selected;
            var  guiColorWas = GUI.color;

            bool isInvoking;

            if (isCoroutine && Application.isPlaying)
            {
                if (monoBehaviour != null)
                {
                    isInvoking = monoBehaviour.IsInvoking(memberInfo.MethodInfo.Name);
                }
                else
                {
                    isInvoking = StaticCoroutine.IsInvoking(memberInfo.MethodInfo.Name);
                }
            }
            else
            {
                isInvoking = false;
            }

            if (isInvoking)
            {
                GUI.color = Color.green;
            }
            else if (selected)
            {
                var col = preferences.theme.ButtonSelected;
                GUI.color = col;
            }

            if (GUI.Button(buttonRect, buttonLabel, Style))
            {
                DrawGUI.UseEvent();
                if (Event.current.button == 0)
                {
                    dirty = true;
                    Invoke();
                    Select(ReasonSelectionChanged.ControlClicked);
                }
                else if (Event.current.button == 1)
                {
                    var menu = Menu.Create();

                    menu.Add(Menu.Item("Invoke", () => Invoke(false, false, false, false)));

                    if (hasReturnValue)
                    {
                                                #if !POWER_INSPECTOR_LITE
                        menu.AddSeparator();
                        menu.Add(Menu.Item("Copy Return Value", () => Invoke(false, false, true, false)));
                                                #endif
                        if (UnityObjectExtensions.IsUnityObjectOrUnityObjectCollectionType(Type))
                        {
                            menu.Add(Menu.Item("Ping Return Value", () => Invoke(true, false, false, false)));
                            menu.Add(Menu.Item("Select Return Value", () => Invoke(false, false, false, true)));
                        }
                    }

                    if (isCoroutine)
                    {
                        menu.AddSeparator();

                        var    monoBehaviour = UnityObject as MonoBehaviour;
                        string methodName    = MethodInfo.Name;

                        if (monoBehaviour != null && Application.isPlaying)
                        {
                            menu.Add("Invoke Repeating/Every Second", () => monoBehaviour.InvokeRepeating(MethodInfo.Name, 1f, 1f));
                            menu.Add("Invoke Repeating/Every 5 Seconds", () => monoBehaviour.InvokeRepeating(MethodInfo.Name, 5f, 5f));
                            menu.Add("Invoke Repeating/Every 10 Seconds", () => monoBehaviour.InvokeRepeating(MethodInfo.Name, 10f, 10f));

                            if (monoBehaviour.IsInvoking(methodName))
                            {
                                menu.Add("Stop Coroutine", () => monoBehaviour.StopCoroutine(MethodInfo.Name));
                                menu.Add("Cancel Invoke", () => monoBehaviour.CancelInvoke(MethodInfo.Name));
                            }
                        }
                    }

                    ContextMenuUtility.Open(menu, this);
                }
                else if (Event.current.button == 2)
                {
                    Invoke(true, false, true, false);
                }
            }

            GUI.color = guiColorWas;

            return(dirty);
        }