示例#1
0
        public static void OnSceneTreeReflect(SceneExplorerState state, ReferenceChain refChain, System.Object obj, bool rawReflection = false)
        {
            if (!SceneExplorerCommon.SceneTreeCheckDepth(refChain))
            {
                return;
            }

            if (obj == null)
            {
                SceneExplorerCommon.OnSceneTreeMessage(refChain, "null");
                return;
            }

            Type type = obj.GetType();

            if (!rawReflection)
            {
                if (state.preventCircularReferences.ContainsKey(obj.GetHashCode()))
                {
                    SceneExplorerCommon.OnSceneTreeMessage(refChain, "Circular reference detected");
                    return;
                }

                state.preventCircularReferences.Add(obj.GetHashCode(), true);

                if (type == typeof(UnityEngine.Transform))
                {
                    GUITransform.OnSceneTreeReflectUnityEngineTransform(refChain, (UnityEngine.Transform)obj);
                    return;
                }

                if (TypeUtil.IsList(obj))
                {
                    GUIList.OnSceneTreeReflectIList(state, refChain, obj);
                    return;
                }

                if (TypeUtil.IsCollection(obj))
                {
                    GUICollection.OnSceneTreeReflectICollection(state, refChain, obj);
                    return;
                }

                if (TypeUtil.IsEnumerable(obj))
                {
                    GUIEnumerable.OnSceneTreeReflectIEnumerable(state, refChain, obj);
                    return;
                }

                if (type == typeof(Material))
                {
                    GUIMaterial.OnSceneReflectUnityEngineMaterial(state, refChain, (UnityEngine.Material)obj);
                    return;
                }
                if (type == typeof(Mesh))
                {
                    if (!((Mesh)obj).isReadable)
                    {
                        SceneExplorerCommon.OnSceneTreeMessage(refChain, "Mesh is not readable");
                        return;
                    }
                }
            }

            var members = TypeUtil.GetAllMembers(type, ModTools.Instance.config.sceneExplorerShowInheritedMembers);

            if (ModTools.Instance.config.sceneExplorerSortAlphabetically)
            {
                Array.Sort(members, (info, info1) => string.Compare(info.Name, info1.Name, StringComparison.Ordinal));
            }

            foreach (MemberInfo member in members)
            {
                if (member.MemberType == MemberTypes.Field && ModTools.Instance.config.sceneExplorerShowFields)
                {
                    var field = (FieldInfo)member;

                    try
                    {
                        GUIField.OnSceneTreeReflectField(state, refChain.Add(field), obj, field);
                    }
                    catch (Exception ex)
                    {
                        SceneExplorerCommon.OnSceneTreeMessage(refChain, $"Exception when fetching field \"{field.Name}\" - {ex.Message}\n{ex.StackTrace}");
                    }
                }
                else if (member.MemberType == MemberTypes.Property && ModTools.Instance.config.sceneExplorerShowProperties)
                {
                    var property = (PropertyInfo)member;

                    try
                    {
                        GUIProperty.OnSceneTreeReflectProperty(state, refChain.Add(property), obj, property);
                    }
                    catch (Exception ex)
                    {
                        SceneExplorerCommon.OnSceneTreeMessage(refChain, $"Exception when fetching property \"{property.Name}\" - {ex.Message}\n{ex.StackTrace}");
                    }
                }
                else if (member.MemberType == MemberTypes.Method && ModTools.Instance.config.sceneExplorerShowMethods)
                {
                    var method = (MethodInfo)member;

                    try
                    {
                        GUIMethod.OnSceneTreeReflectMethod(refChain.Add(method), obj, method);
                    }
                    catch (Exception ex)
                    {
                        SceneExplorerCommon.OnSceneTreeMessage(refChain, $"Exception when fetching method \"{method.Name}\" - {ex.Message}");
                    }
                }
            }
        }
        public static void OnSceneTreeReflect(SceneExplorerState state, ReferenceChain refChain, object obj, bool rawReflection, TypeUtil.SmartType smartType = TypeUtil.SmartType.Undefined, string filter = "")
        {
            if (!SceneExplorerCommon.SceneTreeCheckDepth(refChain))
            {
                return;
            }

            if (obj == null)
            {
                SceneExplorerCommon.OnSceneTreeMessage(refChain, "null");
                return;
            }

            var type = obj.GetType();

            if (!rawReflection)
            {
                if (!type.IsValueType && state.PreventCircularReferences.Contains(obj))
                {
                    try
                    {
                        GUI.contentColor = Color.yellow;
                        SceneExplorerCommon.OnSceneTreeMessage(refChain, "Circular reference detected");
                    }
                    finally
                    {
                        GUI.contentColor = Color.white;
                    }

                    return;
                }

                state.PreventCircularReferences.Add(obj);

                if (type == typeof(Transform))
                {
                    GUITransform.OnSceneTreeReflectUnityEngineTransform(refChain, (Transform)obj);
                    return;
                }

                if (TypeUtil.IsList(obj))
                {
                    GUIList.OnSceneTreeReflectIList(state, refChain, obj, smartType);
                    return;
                }

                if (TypeUtil.IsCollection(obj))
                {
                    GUICollection.OnSceneTreeReflectICollection(state, refChain, obj, smartType);
                    return;
                }

                if (TypeUtil.IsEnumerable(obj))
                {
                    GUIEnumerable.OnSceneTreeReflectIEnumerable(state, refChain, obj, smartType);
                    return;
                }

                if (type == typeof(Material))
                {
                    GUIMaterial.OnSceneReflectUnityEngineMaterial(state, refChain, (Material)obj);
                    return;
                }

                if (type == typeof(Mesh) && !((Mesh)obj).isReadable)
                {
                    SceneExplorerCommon.OnSceneTreeMessage(refChain, "Mesh is not readable");
                    return;
                }
            }

            var members = TypeUtil.GetAllMembers(type, MainWindow.Instance.Config.ShowInheritedMembers);

            if (MainWindow.Instance.Config.SortItemsAlphabetically)
            {
                Array.Sort(members, (x, y) => string.CompareOrdinal(x.ReflectionInfo.Name, y.ReflectionInfo.Name));
            }

            var matchingMembers = 0;

            foreach (var member in members)
            {
                var filterMatchFrom = -1;
                if (!filter.IsNullOrEmpty() && (filterMatchFrom = member.ReflectionInfo.Name.IndexOf(filter, StringComparison.OrdinalIgnoreCase)) < 0)
                {
                    continue;
                }

                matchingMembers++;
                switch (member.ReflectionInfo.MemberType)
                {
                case MemberTypes.Field when MainWindow.Instance.Config.ShowFields:
                {
                    var field = (FieldInfo)member.ReflectionInfo;

                    if (field.IsLiteral && !field.IsInitOnly && !MainWindow.Instance.Config.ShowConsts)
                    {
                        continue;
                    }

                    try
                    {
                        GUIField.OnSceneTreeReflectField(state, refChain.Add(field), obj, field, TypeUtil.OverrideSmartType(member.DetectedType, field.Name, obj), filterMatchFrom, filter.Length);
                    }
                    catch (Exception ex)
                    {
                        SceneExplorerCommon.OnSceneTreeMessage(refChain, $"Exception when fetching field \"{field.Name}\" - {ex.Message}\n{ex.StackTrace}");
                    }

                    break;
                }

                case MemberTypes.Property when MainWindow.Instance.Config.ShowProperties:
                {
                    var property = (PropertyInfo)member.ReflectionInfo;
                    if (property.GetIndexParameters().Length > 0)
                    {
                        continue;     // TODO: add support for indexers
                    }

                    try
                    {
                        GUIProperty.OnSceneTreeReflectProperty(state, refChain.Add(property), obj, property, TypeUtil.OverrideSmartType(member.DetectedType, property.Name, obj), filterMatchFrom, filter.Length);
                    }
                    catch (Exception ex)
                    {
                        SceneExplorerCommon.OnSceneTreeMessage(refChain, $"Exception when fetching property \"{property.Name}\" - {ex.Message}\n{ex.StackTrace}");
                    }

                    break;
                }

                case MemberTypes.Method when MainWindow.Instance.Config.ShowMethods:
                {
                    var method = (MethodInfo)member.ReflectionInfo;

                    try
                    {
                        GUIMethod.OnSceneTreeReflectMethod(refChain.Add(method), obj, method, filterMatchFrom, filter.Length);
                    }
                    catch (Exception ex)
                    {
                        SceneExplorerCommon.OnSceneTreeMessage(refChain, $"Exception when fetching method \"{method.Name}\" - {ex.Message}");
                    }

                    break;
                }
                }
            }

            if (filter.IsNullOrEmpty() || members.Length <= 0 || matchingMembers != 0)
            {
                return;
            }

            GUI.contentColor = Color.yellow;
            SceneExplorerCommon.OnSceneTreeMessage(refChain, "No members matching the search term found!");
            GUI.contentColor = Color.white;
        }