private static Type GetUnityTypeWithName(string name)
        {
            if (UnityTypes == null)
            {
                UnityTypes = new Dictionary <string, Type>();

                foreach (var type in AssemblyUtilities.GetTypes(AssemblyTypeFlags.UnityTypes | AssemblyTypeFlags.UnityEditorTypes)
                         .Where(n => typeof(UnityEngine.Object).IsAssignableFrom(n)))
                {
                    if (UnityTypes.ContainsKey(type.Name))
                    {
                        UnityTypes[type.Name] = null;
                    }
                    else
                    {
                        UnityTypes[type.Name] = type;
                    }
                }
            }

            Type result;

            UnityTypes.TryGetValue(name, out result);
            return(result);
        }
Example #2
0
    private static HashSet <Type> GetScriptableObjectTypes()
    {
        var customTypes = AssemblyUtilities.GetTypes(AssemblyTypeFlags.CustomTypes);
        var scrobTypes  = customTypes.Where(type => type.IsClass &&
                                            typeof(ScriptableObject).IsAssignableFrom(type) &&
                                            !typeof(EditorWindow).IsAssignableFrom(type) &&
                                            !typeof(Editor).IsAssignableFrom(type));

        return(new HashSet <Type>(scrobTypes));
    }
            protected override void BuildSelectionTree(OdinMenuTree tree)
            {
                var scriptableObjectTypes = AssemblyUtilities.GetTypes(AssemblyTypeFlags.CustomTypes)
                                            .Where(x => x.IsClass && !x.IsAbstract && x.InheritsFrom(typeof(T)));

                tree.Selection.SupportsMultiSelect = false;
                tree.Config.DrawSearchToolbar      = true;
                tree.AddRange(scriptableObjectTypes, x => x.GetNiceName())
                .AddThumbnailIcons();
            }
Example #4
0
        /// <summary>
        /// Builds the selection tree.
        /// </summary>
        protected override void BuildSelectionTree(OdinMenuTree tree)
        {
            tree.Config.UseCachedExpandedStates        = false;
            tree.DefaultMenuStyle.NotSelectedIconAlpha = 1f;
            if (types == null)
            {
                List <OdinMenuItem> items;
                if (cachedAllTypesMenuItems.TryGetValue(this.assemblyTypeFlags, out items))
                {
                    AddRecursive(tree, items, tree.MenuItems);
                }
                else
                {
                    var assemblyTypes = OrderTypes(AssemblyUtilities.GetTypes(this.assemblyTypeFlags).Where(x => char.IsLetter(x.Name.Trim()[0])));
                    foreach (var t in assemblyTypes)
                    {
                        var    niceName = t.GetNiceName();
                        string path     = this.GetTypeNamePath(t, niceName);
                        var    last     = tree.AddObjectAtPath(path, t).AddThumbnailIcons().Last();
                        last.SearchString = niceName == path ? path : niceName + "|" + path;
                    }

                    cachedAllTypesMenuItems[this.assemblyTypeFlags] = tree.MenuItems;
                }
            }
            else
            {
                foreach (var t in this.types)
                {
                    var    niceName = t.GetNiceName();
                    string path     = this.GetTypeNamePath(t, niceName);
                    var    last     = tree.AddObjectAtPath(path, t).Last();
                    last.SearchString = niceName == path ? path : niceName + "|" + path;

                    if (this.FlattenTree && t.Namespace != null)
                    {
                        last.OnDrawItem += x => GUI.Label(x.Rect.Padding(10, 0).AlignCenterY(16), t.Namespace, SirenixGUIStyles.RightAlignedGreyMiniLabel);
                    }
                }

                tree.EnumerateTree(x => x.Value != null, false).AddThumbnailIcons();
            }

            //tree.EnumerateTree().ForEach(i =>
            //{
            //    var t = i.Value as Type;
            //    if (t != null) { i.SearchString = t.GetNiceFullName(); }
            //});

            tree.Selection.SupportsMultiSelect = this.supportsMultiSelect;
            tree.Selection.SelectionChanged   += (t) =>
            {
                lastType = this.SelectionTree.Selection.Select(x => x.Value).OfType <Type>().LastOrDefault() ?? lastType;
            };
        }
Example #5
0
        private void DrawTopBar()
        {
            Rect rect = SirenixEditorGUI.BeginHorizontalToolbar();

            {
                var iconRect = rect.AlignLeft(SerializationInfoMenuItem.IconSize).AlignMiddle(SerializationInfoMenuItem.IconSize);
                iconRect.x += SerializationInfoMenuItem.IconSpacing * 2;
                GUI.color   = (this.backendFlags & SerializationBackendFlags.Odin) != 0 ? Color.white : new Color(1f, 1f, 1f, 0.2f);
                GUI.DrawTexture(iconRect.Padding(2), EditorIcons.OdinInspectorLogo, ScaleMode.ScaleToFit);
                iconRect.x += SerializationInfoMenuItem.IconSize + SerializationInfoMenuItem.IconSpacing * 2;
                GUI.color   = (this.backendFlags & SerializationBackendFlags.Unity) != 0 ? Color.white : new Color(1f, 1f, 1f, 0.2f);
                GUI.DrawTexture(iconRect.Padding(2), EditorIcons.UnityLogo, ScaleMode.ScaleToFit);
                GUI.color = Color.white;

                var typeName = "   " + (this.targetType == null ? "Select Type" : this.targetType.GetNiceName().SplitPascalCase()) + "   ";
                GUILayout.Space(iconRect.xMax + 3);
                bool selectB = SirenixEditorGUI.ToolbarButton(new GUIContent(typeName));
                GUILayout.FlexibleSpace();
                bool selectA = SirenixEditorGUI.ToolbarButton(EditorIcons.TriangleDown);

                if (selectA || selectB)
                {
                    var btnRect = GUIHelper.GetCurrentLayoutRect().HorizontalPadding(20).AlignTop(20);
                    btnRect = btnRect.AlignRight(400);
                    var source = AssemblyUtilities.GetTypes(AssemblyTypeFlags.CustomTypes)
                                 .Where(x => !x.IsAbstract && x.IsClass && x.InheritsFrom <UnityEngine.Object>())
                                 .Where(x => !x.Assembly.FullName.StartsWith("Sirenix"))
                                 .OrderBy(x => x.Assembly.GetAssemblyTypeFlag())
                                 .OrderBy(x => x.Assembly.GetAssemblyTypeFlag())
                                 .ThenBy(x => x.Namespace)
                                 .ThenByDescending(x => x.Name);

                    var p = new TypeSelector(source, false);

                    p.SelectionChanged += (types) =>
                    {
                        var t = types.FirstOrDefault();
                        if (t != null)
                        {
                            this.targetType  = t;
                            this.odinContext = this.targetType.IsDefined <ShowOdinSerializedPropertiesInInspectorAttribute>(true);
                            this.CreateMenuTree(true);
                        }
                    };

                    p.SetSelection(this.targetType);
                    p.ShowInPopup(300);
                }
            }
            SirenixEditorGUI.EndHorizontalToolbar();
        }
Example #6
0
        private void Reset()
        {
            var types = AssemblyUtilities.GetTypes(AssemblyTypeFlags.UserTypes |
                                                   AssemblyTypeFlags.PluginTypes);
            var filteredTypes = types.Where(type =>
                                            type.IsSubclassOf(typeof(Packet)) &&
                                            !packetMappingPreset.ContainsValue(type) &&
                                            !packetMapping.ContainsValue(type)).ToList();
            var codeOffset = packetMapping.Count == 0 ? 100 : packetMapping.Keys.Max() + 1;

            for (var i = 0; i < filteredTypes.Count; ++i)
            {
                packetMapping.Add((ushort)(codeOffset + i), filteredTypes[i]);
            }
        }
Example #7
0
 static OdinDatabaseInitializer()
 {
     foreach (var type in AssemblyUtilities.GetTypes(AssemblyTypeFlags.All))
     {
         if (!typeof(IOdinDatabase).IsAssignableFrom(type) || type.IsAbstract)
         {
             continue;
         }
         var info = typeof(GlobalConfig <>).MakeGenericType(type).GetProperty("Instance", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
         if (info?.GetValue(null, null) == null)
         {
             return;
         }
     }
 }
Example #8
0
        /// <summary>
        /// Builds the selection tree.
        /// </summary>
        protected override void BuildSelectionTree(OdinMenuTree tree)
        {
            tree.DefaultMenuStyle.NotSelectedIconAlpha = 1f;
            if (types == null)
            {
                List <OdinMenuItem> items;
                if (cachedAllTypesMenuItems.TryGetValue(this.assemblyTypeFlags, out items))
                {
                    AddRecursive(tree, items, tree.MenuItems);
                }
                else
                {
                    var assemblyTypes = OrderTypes(AssemblyUtilities.GetTypes(this.assemblyTypeFlags).Where(x => char.IsLetter(x.Name.Trim()[0])));
                    foreach (var t in assemblyTypes)
                    {
                        string path = string.IsNullOrEmpty(t.Namespace) ? t.GetNiceName() : t.Namespace + "/" + t.GetNiceName();
                        tree.AddObjectAtPath(path, t).AddThumbnailIcons();
                    }

                    cachedAllTypesMenuItems[this.assemblyTypeFlags] = tree.MenuItems;
                }
            }
            else
            {
                foreach (var t in this.types)
                {
                    string path = string.IsNullOrEmpty(t.Namespace) ? t.GetNiceName() : t.Namespace + "/" + t.GetNiceName();
                    tree.AddObjectAtPath(path, t);
                }

                tree.EnumerateTree(x => x.ObjectInstance != null, false).AddThumbnailIcons();
            }

            tree.EnumerateTree().ForEach(i =>
            {
                var t = i.ObjectInstance as Type;
                if (t != null)
                {
                    i.SearchString = t.GetNiceFullName();
                }
            });

            tree.Selection.SupportsMultiSelect = this.supportsMultiSelect;
            tree.Selection.SelectionChanged   += (t) =>
            {
                lastType = this.SelectionTree.Selection.Select(x => x.ObjectInstance).OfType <Type>().LastOrDefault() ?? lastType;
            };
        }
Example #9
0
        private IEnumerable GetAvailableHooks()
        {
            var notTheseHooks = new HashSet <Type>();

            if (this.Hooks != null)
            {
                notTheseHooks.AddRange(this.Hooks.Where(n => n.Hook != null).Select(n => n.Hook.GetType()));
            }

            var availableHookTypes = AssemblyUtilities.GetTypes(AssemblyTypeFlags.CustomTypes)
                                     .Where(type => !type.IsAbstract && !type.IsInterface && !notTheseHooks.Contains(type) && typeof(IValidationHook).IsAssignableFrom(type) && type.GetConstructor(Type.EmptyTypes) != null).ToList();

            return(availableHookTypes
                   .Select(type => new AutomatedValidationHook((IValidationHook)Activator.CreateInstance(type)))
                   .Select(x => new ValueDropdownItem(x.Hook.Name, x)));
        }
Example #10
0
        protected override OdinMenuTree BuildMenuTree()
        {
            var tree     = new OdinMenuTree();
            var branches = AssemblyUtilities.GetTypes(AssemblyTypeFlags.CustomTypes)
                           .Where(x => x.InheritsFrom <IBranch>() && !x.IsAbstract);

            foreach (var item in branches)
            {
                var obj    = Activator.CreateInstance(item);
                var branch = obj as IBranch;

                branch.Setup(tree);
                tree.Add(branch.Path, obj);
            }

            return(tree);
        }
Example #11
0
 static DatabaseInitializer()
 {
     if (UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode)
     {
         return;
     }
     foreach (var type in AssemblyUtilities.GetTypes(AssemblyTypeFlags.All))
     {
         if (!typeof(IDatabase).IsAssignableFrom(type) || type.IsAbstract)
         {
             continue;
         }
         //Debug.Log($"Database Initialization of type: {type.Name}");
         var info = typeof(GlobalConfig <>).MakeGenericType(type).GetProperty("Instance",
                                                                              System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
         if (info?.GetValue(null, null) == null)
         {
             return;
         }
     }
 }
Example #12
0
        static DrawerUtilities()
        {
            // This method is *very* expensive performance-wise and generates lots of garbage due to liberal use of LINQ for readability.
            // This is acceptable, as it only runs once per AppDomain reload, and only ever in the editor.

            //
            // First, get all relevant types
            //

            var typesToSearch = AssemblyUtilities.GetTypes(AssemblyTypeFlags.CustomTypes | AssemblyTypeFlags.UnityEditorTypes)
                                .Where(type => !type.IsAbstract && type.IsClass && !type.IsDefined(typeof(OdinDontRegisterAttribute), false) && (typeof(OdinDrawer).IsAssignableFrom(type) || (typeof(GUIDrawer).IsAssignableFrom(type) && (!(type.Namespace ?? "").StartsWith("Unity", StringComparison.InvariantCulture) || !ExcludeUnityDrawers.Contains(type.Name)))))
                                .ToArray();

            //
            // Find all regular Unity property and decorator drawers and create alias drawers for them
            //

            IEnumerable <Type> unityPropertyDrawers;
            IEnumerable <Type> unityPropertyAttributeDrawers;
            IEnumerable <Type> unityDecoratorDrawers;

            if (DrawerUtilities.CustomPropertyDrawerTypeField != null && DrawerUtilities.CustomPropertyDrawerUseForChildrenField != null)
            {
                unityPropertyDrawers =
                    typesToSearch.Where(type => type.IsGenericTypeDefinition == false && typeof(PropertyDrawer).IsAssignableFrom(type) && type.GetConstructor(Type.EmptyTypes) != null)
                    .SelectMany(type => type.GetCustomAttributes <CustomPropertyDrawer>(true).Select(attr => new { Type = type, Attribute = attr }))
                    .Where(n =>
                {
                    if (n.Attribute != null)
                    {
                        var drawnType = CustomPropertyDrawerTypeField.GetValue(n.Attribute) as Type;

                        if (drawnType != null && !typeof(PropertyAttribute).IsAssignableFrom(drawnType))
                        {
                            return(true);
                        }
                    }

                    return(false);
                })
                    .Select(n =>
                {
                    var drawnType = (Type)CustomPropertyDrawerTypeField.GetValue(n.Attribute);

                    if (drawnType.IsAbstract || (bool)DrawerUtilities.CustomPropertyDrawerUseForChildrenField.GetValue(n.Attribute))
                    {
                        var tArg = typeof(AbstractTypeUnityPropertyDrawer <, ,>).GetGenericArguments()[2];
                        return(typeof(AbstractTypeUnityPropertyDrawer <, ,>).MakeGenericType(n.Type, drawnType, tArg));
                    }
                    else
                    {
                        return(typeof(UnityPropertyDrawer <,>).MakeGenericType(n.Type, drawnType));
                    }
                });

                unityPropertyAttributeDrawers =
                    typesToSearch.Where(type => type.IsGenericTypeDefinition == false && typeof(PropertyDrawer).IsAssignableFrom(type) && type.GetConstructor(Type.EmptyTypes) != null)
                    .SelectMany(type => type.GetCustomAttributes <CustomPropertyDrawer>(true).Select(attr => new { Type = type, Attribute = attr }))
                    .Where(n =>
                {
                    if (n.Attribute != null)
                    {
                        var drawnType = CustomPropertyDrawerTypeField.GetValue(n.Attribute) as Type;

                        if (drawnType != null && typeof(PropertyAttribute).IsAssignableFrom(drawnType))
                        {
                            return(true);
                        }
                    }

                    return(false);
                })
                    .Select(n =>
                {
                    Type drawnType = (Type)CustomPropertyDrawerTypeField.GetValue(n.Attribute);

                    if ((bool)DrawerUtilities.CustomPropertyDrawerUseForChildrenField.GetValue(n.Attribute))
                    {
                        var tAttributeArgParam = typeof(UnityPropertyAttributeDrawer <, ,>).GetGenericArguments()[1];
                        return(typeof(UnityPropertyAttributeDrawer <, ,>).MakeGenericType(n.Type, tAttributeArgParam, drawnType));
                    }
                    else
                    {
                        return(typeof(UnityPropertyAttributeDrawer <, ,>).MakeGenericType(n.Type, drawnType, typeof(PropertyAttribute)));
                    }
                });

                unityDecoratorDrawers =
                    typesToSearch.Where(type => type.IsGenericTypeDefinition == false && typeof(DecoratorDrawer).IsAssignableFrom(type) && type.GetConstructor(Type.EmptyTypes) != null)
                    .Select(type => new { Type = type, Attribute = type.GetCustomAttribute <CustomPropertyDrawer>(true) })
                    .Where(n => n.Attribute != null)
                    .Select(n => new { Type = n.Type, Attribute = n.Attribute, DrawnType = CustomPropertyDrawerTypeField.GetValue(n.Attribute) as Type })
                    .Where(n => n.DrawnType != null && typeof(PropertyAttribute).IsAssignableFrom(n.DrawnType))
                    .Select(n =>
                {
                    if ((bool)DrawerUtilities.CustomPropertyDrawerUseForChildrenField.GetValue(n.Attribute))
                    {
                        var tAttributeArgParam = typeof(UnityDecoratorAttributeDrawer <, ,>).GetGenericArguments()[1];
                        return(typeof(UnityDecoratorAttributeDrawer <, ,>).MakeGenericType(n.Type, tAttributeArgParam, n.DrawnType));
                    }
                    else
                    {
                        return(typeof(UnityDecoratorAttributeDrawer <, ,>).MakeGenericType(n.Type, n.DrawnType, typeof(PropertyAttribute)));
                    }
                });
            }
            else
            {
                Debug.LogWarning("Could not find internal fields 'm_Type' and/or 'm_UseForChildren' in type CustomPropertyDrawer in this version of Unity; support for legacy Unity PropertyDrawers and DecoratorDrawers have been disabled in Odin's inspector. Please report this on Odin's issue tracker.");
                unityPropertyDrawers          = Enumerable.Empty <Type>();
                unityPropertyAttributeDrawers = Enumerable.Empty <Type>();
                unityDecoratorDrawers         = Enumerable.Empty <Type>();
            }

            DrawerUtilities.AllDrawerTypes = typesToSearch
                                             .Where(type => typeof(OdinDrawer).IsAssignableFrom(type))
                                             .AppendWith(unityPropertyDrawers)
                                             .AppendWith(unityPropertyAttributeDrawers)
                                             .AppendWith(unityDecoratorDrawers)
                                             .OrderByDescending(type => GetDrawerPriority(type))
                                             .ToList();

            //DrawerUtilities.SearchIndex.IndexingRules.Add(new TypeMatchIndexingRule(
            //    "DEBUG",
            //    (ref TypeSearchInfo info, ref string error) =>
            //    {
            //        Debug.Log("Indexed drawer: " + info.MatchType.GetNiceFullName());
            //        return true;
            //    }));

            // Unity drawers have a peculiar method of generic target selection,
            // where you pass in the generic type definition that you wish to draw.
            //
            // We need to support this, for Unity's own legacy drawers.
            DrawerUtilities.SearchIndex.MatchRules.Add(new TypeSearch.TypeMatchRule(
                                                           "Unity Drawer Generic Target Matcher",
                                                           (info, targets) =>
            {
                if (targets.Length != 1)
                {
                    return(null);
                }
                if (!info.Targets[0].IsGenericTypeDefinition)
                {
                    return(null);
                }

                var baseDef = info.MatchType.GetGenericTypeDefinition();

                bool abstractUnityValueDrawer = baseDef == typeof(AbstractTypeUnityPropertyDrawer <, ,>);
                bool plainUnityValueDrawer    = baseDef == typeof(UnityPropertyDrawer <,>);

                if (!(abstractUnityValueDrawer || plainUnityValueDrawer))
                {
                    return(null);
                }

                if (abstractUnityValueDrawer)
                {
                    if (targets[0].ImplementsOpenGenericType(info.Targets[0]))
                    {
                        var args = info.MatchType.GetGenericArguments();
                        return(info.MatchType.GetGenericTypeDefinition().MakeGenericType(args[0], targets[0], targets[0]));
                    }
                }
                else
                {
                    if (!targets[0].IsGenericType)
                    {
                        return(null);
                    }

                    if (targets[0].GetGenericTypeDefinition() == info.Targets[0])
                    {
                        var args = info.MatchType.GetGenericArguments();
                        return(info.MatchType.GetGenericTypeDefinition().MakeGenericType(args[0], targets[0]));
                    }
                }

                return(null);
            })
                                                       );

            DrawerUtilities.SearchIndex.AddIndexedTypes(
                DrawerUtilities.AllDrawerTypes
                .Select((type, i) =>
            {
                var info = new TypeSearchInfo()
                {
                    MatchType = type,
                    Priority  = DrawerUtilities.AllDrawerTypes.Count - i,
                    Targets   = null
                };

                if (type.ImplementsOpenGenericClass(typeof(OdinValueDrawer <>)))
                {
                    info.Targets = type.GetArgumentsOfInheritedOpenGenericClass(typeof(OdinValueDrawer <>));
                }
                else if (type.ImplementsOpenGenericClass(typeof(OdinAttributeDrawer <>)))
                {
                    if (type.ImplementsOpenGenericClass(typeof(OdinAttributeDrawer <,>)))
                    {
                        info.Targets = type.GetArgumentsOfInheritedOpenGenericClass(typeof(OdinAttributeDrawer <,>));
                        InvalidAttributeTargetUtility.RegisterValidAttributeTarget(info.Targets[0], info.Targets[1]);
                    }
                    else
                    {
                        info.Targets = type.GetArgumentsOfInheritedOpenGenericClass(typeof(OdinAttributeDrawer <>));
                    }
                }
                else if (type.ImplementsOpenGenericClass(typeof(OdinGroupDrawer <>)))
                {
                    info.Targets = type.GetArgumentsOfInheritedOpenGenericClass(typeof(OdinGroupDrawer <>));
                }
                else if (!type.IsFullyConstructedGenericType())
                {
                    info.Targets = type.GetGenericArguments();
                }

                info.Targets = info.Targets ?? Type.EmptyTypes;
                return(info);
            })
                );
        }
Example #13
0
        private TypeTreeNode GetTypeTree(Type type)
        {
            TypeTreeNode rootNode;

            if (typeTrees.TryGetValue(type, out rootNode) == false)
            {
                var typeFlag = AssemblyUtilities.GetAssemblyTypeFlag(type.Assembly);

                var additionalTypes = new List <Type>()
                {
                    typeof(NullType),
                    type,
                    typeof(string),
                    typeof(List <>).MakeGenericType(type),
                    type.MakeArrayType(),
                    type.MakeArrayType(2),
                    type.MakeArrayType(3)
                };

                var additions = additionalTypes
                                .Select(x => new
                {
                    type = x,
                    flag = (x == typeof(NullType) || x.IsArray) ? typeFlag : AssemblyUtilities.GetAssemblyTypeFlag(x.Assembly)
                })
                                .ToArray();

                rootNode = typeTrees[type] = new TypeTreeNode()
                {
                    ChildNodes = AssemblyUtilities
                                 .GetAllAssemblies()
                                 .Select(x => new { assembly = x, flag = AssemblyUtilities.GetAssemblyTypeFlag(x) })
                                 .GroupBy(a => a.flag)
                                 .Select(a => new TypeTreeNode()
                    {
                        AssemblyTypeFlag = a.Key,
                        IsVisible        = (a.Key & AssemblyTypeFlags.UserTypes) != 0,
                        ChildNodes       = AssemblyUtilities
                                           .GetTypes(a.Key)
                                           .Where(x => ((a.Key & AssemblyTypeFlags.UserTypes) != 0 || x.IsPublic) && x != type) // Only include public types or types from User assembly.
                                           .Prepend(additions.Where(x => x.flag == a.Key).Select(x => x.type))
                                           .Select(t => CanCreateInstance(type, ref t) ? t : null)
                                           .Where(t => t != null)
                                           .Distinct()
                                           .GroupBy(t => ((t == typeof(NullType) || t.IsArray) ? type : t).Namespace ?? "ALSO!GROUP!ME")
                                           .Select(g => new TypeTreeNode()
                        {
                            Namespace  = (g.Key == "ALSO!GROUP!ME") ? null : g.Key,
                            ChildNodes = g
                                         .Select(t => new TypeTreeNode()
                            {
                                Type = t
                            })
                                         .Where(x => x.Type == null || x.Type.GetNiceName().Contains('$') == false)
                                         .OrderBy(t => t.Type == typeof(NullType))
                                         .ThenBy(t => t.Type == null ? "" : t.Type.Name)
                                         .ToList()
                        })
                                           .Where(x => x.Type == null || x.Type.GetNiceName().Contains('$') == false)
                                           .OrderBy(x => x.Namespace)
                                           .ThenBy(x => x.Type)
                                           .ToList()
                    })
                                 .OrderBy(x => x.AssemblyTypeFlag)
                                 .ToList()
                };
                rootNode.IsVisible = true;
                rootNode.Initialize(this, null);
            }
            else
            {
                rootNode.Initialize(this, null);
            }

            this.hideFoldoutLabels = rootNode.EnumerateTree().Count(x => x.Type != null) < 20;

            if (this.hideFoldoutLabels)
            {
                foreach (var item in rootNode.EnumerateTree())
                {
                    item.IsVisible = true;
                }
            }
            else
            {
                var firstCollection = rootNode.EnumerateTree().FirstOrDefault(x => x.ChildNodes != null && x.ChildNodes.Count > 0);
                if (firstCollection != null)
                {
                    firstCollection.IsVisible = true;
                }
            }

            var firstTypeNode = rootNode.EnumerateTree().FirstOrDefault(x => x.Type != null);

            if (firstTypeNode != null)
            {
                firstTypeNode.ForceSetSelected = true;
            }

            if (this.autoSelectFirst && firstTypeNode != null)
            {
                this.chosenType = firstTypeNode.Type;
            }

            return(rootNode);
        }
Example #14
0
        static DrawerLocator()
        {
            // This method is *very* expensive performance-wise and generates lots of garbage due to liberal use of LINQ for readability.
            // This is acceptable, as it only runs once per AppDomain reload, and only ever in the editor.

            //
            // First, get all relevant types
            //

            var allTypes = AssemblyUtilities.GetTypes(AssemblyTypeFlags.CustomTypes | AssemblyTypeFlags.UnityEditorTypes)
                           .Where(type => type.IsAbstract == false && type.IsClass && (typeof(OdinDrawer).IsAssignableFrom(type) || (typeof(GUIDrawer).IsAssignableFrom(type) && (!(type.Namespace ?? "").StartsWith("Unity", StringComparison.InvariantCulture) || !ExcludeUnityDrawers.Contains(type.Name)))))
                           .ToArray();

            //
            // Find all regular Unity property and decorator drawers and create alias drawers for them
            //

            IEnumerable <Type> unityPropertyDrawers;
            IEnumerable <Type> unityPropertyAttributeDrawers;
            IEnumerable <Type> unityDecoratorDrawers;

            if (DrawerLocator.CustomPropertyDrawerTypeField != null && DrawerLocator.CustomPropertyDrawerUseForChildrenField != null)
            {
                unityPropertyDrawers =
                    allTypes.Where(type => type.IsGenericTypeDefinition == false && typeof(PropertyDrawer).IsAssignableFrom(type) && type.GetConstructor(Type.EmptyTypes) != null)
                    .SelectMany(type => type.GetCustomAttributes <CustomPropertyDrawer>(true).Select(attr => new { Type = type, Attribute = attr }))
                    .Where(n =>
                {
                    if (n.Attribute != null)
                    {
                        var drawnType = CustomPropertyDrawerTypeField.GetValue(n.Attribute) as Type;

                        if (drawnType != null && !typeof(PropertyAttribute).IsAssignableFrom(drawnType) && UnitySerializationUtility.GuessIfUnityWillSerialize(drawnType))
                        {
                            return(true);
                        }
                    }

                    return(false);
                })
                    .Select(n =>
                {
                    var drawnType = (Type)CustomPropertyDrawerTypeField.GetValue(n.Attribute);

                    if (drawnType.IsAbstract || (bool)DrawerLocator.CustomPropertyDrawerUseForChildrenField.GetValue(n.Attribute))
                    {
                        var tArg = typeof(AbstractTypeUnityPropertyDrawer <, ,>).GetGenericArguments()[2];
                        return(typeof(AbstractTypeUnityPropertyDrawer <, ,>).MakeGenericType(n.Type, drawnType, tArg));
                    }
                    else
                    {
                        return(typeof(UnityPropertyDrawer <,>).MakeGenericType(n.Type, drawnType));
                    }
                });

                unityPropertyAttributeDrawers =
                    allTypes.Where(type => type.IsGenericTypeDefinition == false && typeof(PropertyDrawer).IsAssignableFrom(type) && type.GetConstructor(Type.EmptyTypes) != null)
                    .SelectMany(type => type.GetCustomAttributes <CustomPropertyDrawer>(true).Select(attr => new { Type = type, Attribute = attr }))
                    .Where(n =>
                {
                    if (n.Attribute != null)
                    {
                        var drawnType = CustomPropertyDrawerTypeField.GetValue(n.Attribute) as Type;

                        if (drawnType != null && typeof(PropertyAttribute).IsAssignableFrom(drawnType))
                        {
                            return(true);
                        }
                    }

                    return(false);
                })
                    .Select(n =>
                {
                    Type drawnType = (Type)CustomPropertyDrawerTypeField.GetValue(n.Attribute);

                    if ((bool)DrawerLocator.CustomPropertyDrawerUseForChildrenField.GetValue(n.Attribute))
                    {
                        var tAttributeArgParam = typeof(UnityPropertyAttributeDrawer <, ,>).GetGenericArguments()[1];
                        return(typeof(UnityPropertyAttributeDrawer <, ,>).MakeGenericType(n.Type, tAttributeArgParam, drawnType));
                    }
                    else
                    {
                        return(typeof(UnityPropertyAttributeDrawer <, ,>).MakeGenericType(n.Type, drawnType, typeof(PropertyAttribute)));
                    }
                });

                unityDecoratorDrawers =
                    allTypes.Where(type => type.IsGenericTypeDefinition == false && typeof(DecoratorDrawer).IsAssignableFrom(type) && type.GetConstructor(Type.EmptyTypes) != null)
                    .Select(type => new { Type = type, Attribute = type.GetCustomAttribute <CustomPropertyDrawer>(true) })
                    .Where(n => n.Attribute != null)
                    .Select(n => new { Type = n.Type, Attribute = n.Attribute, DrawnType = CustomPropertyDrawerTypeField.GetValue(n.Attribute) as Type })
                    .Where(n => n.DrawnType != null && typeof(PropertyAttribute).IsAssignableFrom(n.DrawnType))
                    .Select(n =>
                {
                    if ((bool)DrawerLocator.CustomPropertyDrawerUseForChildrenField.GetValue(n.Attribute))
                    {
                        var tAttributeArgParam = typeof(UnityDecoratorAttributeDrawer <, ,>).GetGenericArguments()[1];
                        return(typeof(UnityDecoratorAttributeDrawer <, ,>).MakeGenericType(n.Type, tAttributeArgParam, n.DrawnType));
                    }
                    else
                    {
                        return(typeof(UnityDecoratorAttributeDrawer <, ,>).MakeGenericType(n.Type, n.DrawnType, typeof(PropertyAttribute)));
                    }
                });
            }
            else
            {
                Debug.LogWarning("Could not find internal fields 'm_Type' and/or 'm_UseForChildren' in type CustomPropertyDrawer; Unity PropertyDrawers and DecoratorDrawers have been disabled in the inspector.");
                unityPropertyDrawers          = Enumerable.Empty <Type>();
                unityPropertyAttributeDrawers = Enumerable.Empty <Type>();
                unityDecoratorDrawers         = Enumerable.Empty <Type>();
            }

            //
            // Find, group and sort all defined property drawer types
            //

            DrawerLocator.PropertyDrawerInfos =
                allTypes.Where(type => type.ImplementsOpenGenericClass(typeof(OdinValueDrawer <>)) && type.GetConstructor(Type.EmptyTypes) != null && type.IsDefined <OdinDrawerAttribute>(false))
                .Append(unityPropertyDrawers)
                .Select(drawerType =>
            {
                Type drawnType;

                if (!DrawerIsValid(drawerType, out drawnType) || drawnType == null)
                {
                    return(null);
                }

                return(new DrawerInfo(drawerType, drawnType, null, drawerType.GetAttribute <OdinDrawerAttribute>(false)));
            })
                .Where(info => info != null)
                .Distinct()
                .OrderByDescending(info => info.Priority)
                .ToList();

            DrawerLocator.AttributeDrawerInfos =
                allTypes.Where(type => type.ImplementsOpenGenericClass(typeof(OdinAttributeDrawer <>)) && type.GetConstructor(Type.EmptyTypes) != null && type.IsDefined <OdinDrawerAttribute>(false))
                .Append(unityDecoratorDrawers)
                .Append(unityPropertyAttributeDrawers)
                .Select(type =>
            {
                if (type.ImplementsOpenGenericClass(typeof(OdinAttributeDrawer <,>)))
                {
                    Type drawnType;

                    if (!DrawerIsValid(type, out drawnType))
                    {
                        return(null);
                    }

                    Type[] args = type.GetArgumentsOfInheritedOpenGenericClass(typeof(OdinAttributeDrawer <,>));
                    return(new DrawerInfo(type, drawnType, args[0], type.GetAttribute <OdinDrawerAttribute>(false)));
                }
                else
                {
                    return(new DrawerInfo(type, null, type.GetArgumentsOfInheritedOpenGenericClass(typeof(OdinAttributeDrawer <>))[0], type.GetAttribute <OdinDrawerAttribute>(false)));
                }
            })
                .Where(info => info != null)
                .Distinct()
                .OrderByDescending(info => info.Priority)
                .ToList();

            DrawerLocator.GroupDrawerInfos =
                allTypes.Where(type => type.IsGenericTypeDefinition == false && type.IsGenericType == false && type.ImplementsOpenGenericClass(typeof(OdinGroupDrawer <>)) && type.GetConstructor(Type.EmptyTypes) != null)
                .Select(type => new DrawerInfo(type, null, type.GetArgumentsOfInheritedOpenGenericClass(typeof(OdinGroupDrawer <>))[0], type.GetAttribute <OdinDrawerAttribute>(false)))
                .Where(info => info.OdinDrawerAttribute != null)
                .Distinct()
                .OrderByDescending(info => info.Priority)
                .ToList();

            //
            // Register found drawers in various dictionaries
            //

            for (int i = 0; i < DrawerLocator.PropertyDrawerInfos.Count; i++)
            {
                var info = DrawerLocator.PropertyDrawerInfos[i];
                DrawerLocator.DrawerTypePriorityLookup[info.DrawerType] = info.Priority;

                //Debug.Log("Found value drawer: " + info);
            }

            for (int i = 0; i < DrawerLocator.AttributeDrawerInfos.Count; i++)
            {
                var info = DrawerLocator.AttributeDrawerInfos[i];
                DrawerLocator.DrawerTypePriorityLookup[info.DrawerType] = info.Priority;

                //Debug.Log("Found attribute drawer: " + info);

                // Also register in attribute value drawer maps

                if (info.DrawnValueType != null)
                {
                    List <DrawerInfo> list;

                    if (!DrawerLocator.AttributeDrawerMap.TryGetValue(info.DrawnAttributeType, out list))
                    {
                        list = new List <DrawerInfo>();
                        DrawerLocator.AttributeDrawerMap.Add(info.DrawnAttributeType, list);
                    }

                    list.Add(info);
                }
            }
        }
        /// <summary>
        /// Not yet documented.
        /// </summary>
        public static Type GuessContainedType(this SerializedProperty property)
        {
            switch (property.propertyType)
            {
            case SerializedPropertyType.Generic:
                return(null);

            case SerializedPropertyType.Integer:
                return(typeof(int));

            case SerializedPropertyType.Boolean:
                return(typeof(bool));

            case SerializedPropertyType.Float:
                return(typeof(float));

            case SerializedPropertyType.String:
                return(typeof(string));

            case SerializedPropertyType.Color:
                return(typeof(Color));

            case SerializedPropertyType.ObjectReference:
            {
                if (!object.ReferenceEquals(property.objectReferenceValue, null))
                {
                    return(property.objectReferenceValue.GetType());
                }

                string typeName = property.GetProperTypeName();

                var possibles = AssemblyUtilities.GetTypes(AssemblyTypeFlags.UnityTypes | AssemblyTypeFlags.UnityEditorTypes)
                                .Where(n => n.Name == typeName && typeof(UnityEngine.Object).IsAssignableFrom(n))
                                .ToList();

                if (possibles.Count == 1)
                {
                    return(possibles[0]);
                }

                return(null);
            }

            case SerializedPropertyType.LayerMask:
                return(typeof(LayerMask));

            case SerializedPropertyType.Enum:
                return(null);

            case SerializedPropertyType.Vector2:
                return(typeof(Vector2));

            case SerializedPropertyType.Vector3:
                return(typeof(Vector3));

            case SerializedPropertyType.Vector4:
                return(typeof(Vector4));

            case SerializedPropertyType.Rect:
                return(typeof(Rect));

            case SerializedPropertyType.ArraySize:
                return(null);

            case SerializedPropertyType.Character:
                return(typeof(char));

            case SerializedPropertyType.AnimationCurve:
                return(typeof(AnimationCurve));

            case SerializedPropertyType.Bounds:
                return(typeof(Bounds));

            case SerializedPropertyType.Gradient:
                return(typeof(Gradient));

            case SerializedPropertyType.Quaternion:
                return(typeof(Quaternion));

            default:
                return(null);
            }
        }
Example #16
0
        static InspectorTypeDrawingConfigDrawer()
        {
            NeverDrawTypes = new HashSet <Type>();
            {
                var networkView = AssemblyUtilities.GetTypeByCachedFullName("UnityEngine.NetworkView");
                if (networkView != null)
                {
                    NeverDrawTypes.Add(networkView);
                }
                var gUIText = AssemblyUtilities.GetTypeByCachedFullName("UnityEngine.GUIText");
                if (gUIText != null)
                {
                    NeverDrawTypes.Add(gUIText);
                }
            }

            var unityObjectTypes = AssemblyUtilities.GetTypes(AssemblyTypeFlags.All) // @Tor: Consider switching to AssemblyTypeFlags.CustomTypes?
                                   .Where(type =>
                                          !type.Assembly.IsDynamic() &&
                                          typeof(UnityEngine.Object).IsAssignableFrom(type) &&
                                          //TypeExtensions.IsValidIdentifier(type.FullName) &&
                                          !type.IsDefined <CompilerGeneratedAttribute>() &&
                                          !type.IsDefined <ObsoleteAttribute>() &&
                                          !typeof(Joint).IsAssignableFrom(type) &&
                                          !NeverDrawTypes.Contains(type))
                                   .ToArray();

            Dictionary <Type, Type> haveDrawersAlready     = new Dictionary <Type, Type>();
            Dictionary <Type, Type> derivedClassDrawnTypes = new Dictionary <Type, Type>();

            unityObjectTypes.ForEach(type =>
            {
                if (typeof(Editor).IsAssignableFrom(type))
                {
                    try
                    {
                        bool editorForChildClasses;

                        var drawnType = InspectorTypeDrawingConfig.GetEditorDrawnType(type, out editorForChildClasses);

                        if (drawnType != null)
                        {
                            if (!haveDrawersAlready.ContainsKey(drawnType))
                            {
                                haveDrawersAlready.Add(drawnType, type);
                            }

                            if (editorForChildClasses && !derivedClassDrawnTypes.ContainsKey(drawnType))
                            {
                                derivedClassDrawnTypes.Add(drawnType, type);
                            }
                        }

                        if (/*type.IsVisible && */ InspectorTypeDrawingConfig.UnityInspectorEditorIsValidBase(type, null))
                        {
                            PossibleEditorTypes.Add(type);
                        }
                    }
                    catch (TypeLoadException)
                    {
                    }
                    catch (ReflectionTypeLoadException)
                    {
                    }
                }
            });

            HashSet <Type> stopBaseTypeLookUpTypes = new HashSet <Type>()
            {
                typeof(object),
                typeof(Component),
                typeof(Behaviour),
                typeof(MonoBehaviour),
                typeof(UnityEngine.Object),
                typeof(ScriptableObject),
                typeof(StateMachineBehaviour),
                //typeof(Networking.NetworkBehaviour)
            };

            if (UnityNetworkingUtility.NetworkBehaviourType != null)
            {
                // UnityEngine.Networking has been removed in Unity 2019+.
                stopBaseTypeLookUpTypes.Add(UnityNetworkingUtility.NetworkBehaviourType);
            }

            //Debug.Log("Searching the following " + unityObjectTypes.Length + " types for Odin-drawable types:\n\n" + string.Join("\n", unityObjectTypes.Select(n => n.GetNiceFullName()).ToArray()));

            unityObjectTypes.Where(type => /*type.IsVisible && */ !type.IsAbstract && !type.IsGenericTypeDefinition && !type.IsGenericType && !typeof(Editor).IsAssignableFrom(type) && !typeof(EditorWindow).IsAssignableFrom(type))
            .ForEach(type =>
            {
                Type preExistingEditorType;
                bool haveDrawerAlready = haveDrawersAlready.TryGetValue(type, out preExistingEditorType);

                if (!haveDrawerAlready)
                {
                    Type baseType = type.BaseType;

                    while (baseType != null && !stopBaseTypeLookUpTypes.Contains(baseType))
                    {
                        Type editor;

                        if (derivedClassDrawnTypes.TryGetValue(baseType, out editor))
                        {
                            haveDrawerAlready     = true;
                            preExistingEditorType = editor;
                            break;
                        }

                        baseType = baseType.BaseType;
                    }
                }

                if (!haveDrawerAlready)
                {
                    PossibleDrawnTypes.Add(type);
                }

                AddTypeToGroups(type, preExistingEditorType);
            });

            //Debug.Log("Found the following " + PossibleDrawnTypes.Count + " types that Odin can draw:\n\n" + string.Join("\n", PossibleDrawnTypes.Select(n => n.GetNiceFullName()).ToArray()));

            // Remove editor entries for any types that are not eligible to be drawn
            {
                bool fixedAny = false;

                foreach (var type in InspectorConfig.Instance.DrawingConfig.GetAllDrawnTypesWithEntries())
                {
                    if (!PossibleDrawnTypes.Contains(type))
                    {
                        InspectorConfig.Instance.DrawingConfig.ClearEditorEntryForDrawnType(type);
                        fixedAny = true;
                    }
                }

                if (fixedAny)
                {
                    AssetDatabase.SaveAssets();
                }
            }

            UpdateRootGroupHasEligibletypes();
            UpdateRootGroupConflicts();
            SortRootGroups();
            UpdateRootGroupsSearch("", DisplayType.AllUnityObjects);
        }
Example #17
0
 private IEnumerable <Type> GetAssetTypes() =>
 AssemblyUtilities.GetTypes(AssemblyTypeFlags.UserTypes)
 .Where(x => x.InheritsFrom <ScriptableObject>() && !x.IsAbstract);