Beispiel #1
0
        /// <summary>
        /// Fetches visible members in the inspected target object and assigns them to their corresponding categories
        /// </summary>
        private void Initialize()
        {
            OnBeforeInitialized();

            // fetch visible members
            _visibleMembers = VisibilityLogic.CachedGetVisibleMembers(targetType);

            var drawnByUnity = _visibleMembers
                               .Where(x => x.IsDefined <DrawByUnityAttribute>() || DrawnByUnityTypes.Any(x.GetDataType().IsA));

            _visibleMembers = _visibleMembers.Except(drawnByUnity).ToList();

            _membersDrawnByUnityLayout = drawnByUnity.Select(x => x.Name).ToArray();

            // allocate categories
            _categories = new List <MembersCategory>();

            var multiple    = targetType.GetCustomAttribute <DefineCategoriesAttribute>(true);
            var definitions = targetType.GetCustomAttributes <DefineCategoryAttribute>(true);

            if (multiple != null)
            {
                definitions = definitions.Concat(multiple.names.Select(n => new DefineCategoryAttribute(n, 1000)));
            }

            Func <string, string[]> ParseCategoryPath = fullPath =>
            {
                int      nPaths = fullPath.Split('/').Length;
                string[] result = new string[nPaths];
                for (int i = 0, index = -1; i < nPaths - 1; i++)
                {
                    index     = fullPath.IndexOf('/', index + 1);
                    result[i] = fullPath.Substring(0, index);
                }
                result[nPaths - 1] = fullPath;
                return(result);
            };

            // Order by exclusivity
            var defs = from d in definitions
                       let paths = ParseCategoryPath(d.FullPath)
                                   orderby !d.Exclusive
                                   select new { def = d, paths };

            // Parse paths and resolve definitions
            var resolver = new CategoryDefinitionResolver();
            var lookup   = new Dictionary <string, MembersCategory>();

            foreach (var x in defs)
            {
                var paths = x.paths;
                var d     = x.def;

                MembersCategory parent = null;

                for (int i = 0; i < paths.Length; i++)
                {
                    var path = paths[i];

                    var current = (parent == null ? _categories :
                                   parent.NestedCategories).FirstOrDefault(c => c.FullPath == path);

                    if (current == null)
                    {
                        current = new MembersCategory(path, d.Order, id, prefs);
                        if (i == 0)
                        {
                            _categories.Add(current);
                        }
                        if (parent != null)
                        {
                            parent.NestedCategories.Add(current);
                        }
                    }
                    lookup[path] = current;
                    parent       = current;
                }

                var last = lookup[paths.Last()];
                last.ForceExpand      = d.ForceExpand;
                last.AlwaysHideHeader = d.AlwaysHideHeader;
                resolver.Resolve(_visibleMembers, d).Foreach(last.Members.Add);

                lookup.Clear();
                parent.Members = parent.Members.OrderBy <MemberInfo, float>(VisibilityLogic.GetMemberDisplayOrder).ToList();
            }

            // filter out empty categories
            _categories = _categories.Where(x => x.NestedCategories.Count > 0 || x.Members.Count > 0)
                          .OrderBy(x => x.DisplayOrder)
                          .ToList();

            for (int i = 0; i < _categories.Count; i++)
            {
                var c = _categories[i];
                c.RemoveEmptyNestedCategories();
            }

            var getDisplayOptions = targetType.GetMethod("GetDisplayOptions");

            Assert.IsNotNull(getDisplayOptions);

            // otherwise whatever value is in our settings asset
            // TODO CHANGED: A common interface is now used for both cases.
            var defaultDisplay = typeof(IVFWObject).IsAssignableFrom(getDisplayOptions.DeclaringType) ?
                                 VFWSettings.DefaultDisplay : (CategoryDisplay)getDisplayOptions.Invoke(target);

            //var defaultDisplay = (getDisplayOptions.DeclaringType == typeof(BaseBehaviour) ||
            //                      getDisplayOptions.DeclaringType == typeof(BaseScriptableObject)) ?
            //                      VFWSettings.DefaultDisplay : (CategoryDisplay)getDisplayOptions.Invoke(target);

            int displayKey   = RuntimeHelper.CombineHashCodes(id, "display");
            int displayValue = prefs.ValueOrDefault(displayKey, (int)defaultDisplay);

            _display          = displayValue == -1 ? VFWSettings.DefaultDisplay : (CategoryDisplay)displayValue;
            prefs[displayKey] = (int)_display;

            var spacingKey = RuntimeHelper.CombineHashCodes(id, "spacing");

            _spacing          = prefs.ValueOrDefault(spacingKey, VFWSettings.DefaultSpacing);
            prefs[spacingKey] = _spacing;

            FieldInfo field;

            field = targetType.GetField("dbg", Flags.InstanceAnyVisibility);
            if (field == null)
            {
                ErrorHelper.MemberNotFound(targetType, "dbg");
            }

            _debug = EditorMember.WrapMember(field, target, target, id);

            OnAfterInitialized();
        }
Beispiel #2
0
        /// <summary>
        /// Fetches visible members in the inspected target object and assigns them to their corresponding categories
        /// </summary>
        private void Initialize()
        {
            OnBeforeInitialized();

            // fetch visible members
            _visibleMembers = VFWVisibilityLogic.CachedGetVisibleMembers(targetType).ToList();

            // allocate categories
            _categories = new List <MembersCategory>();

            var multiple    = targetType.GetCustomAttribute <DefineCategoriesAttribute>(true);
            var definitions = targetType.GetCustomAttributes <DefineCategoryAttribute>(true);

            if (multiple != null)
            {
                definitions = definitions.Concat(multiple.names.Select(n => new DefineCategoryAttribute(n, 1000)));
            }

            Func <string, string[]> ParseCategoryPath = fullPath =>
            {
                int      nPaths = fullPath.Split('/').Length;
                string[] result = new string[nPaths];
                for (int i = 0, index = -1; i < nPaths - 1; i++)
                {
                    index     = fullPath.IndexOf('/', index + 1);
                    result[i] = fullPath.Substring(0, index);
                }
                result[nPaths - 1] = fullPath;
                return(result);
            };

            // Order by exclusivity
            var defs = from d in definitions
                       let paths = ParseCategoryPath(d.FullPath)
                                   orderby !d.Exclusive
                                   select new { def = d, paths };

            // Parse paths and resolve definitions
            var resolver = new CategoryDefinitionResolver();
            var lookup   = new Dictionary <string, MembersCategory>();

            foreach (var x in defs)
            {
                var paths = x.paths;
                var d     = x.def;

                MembersCategory parent = null;

                for (int i = 0; i < paths.Length; i++)
                {
                    var path = paths[i];

                    var current = (parent == null ?  _categories :
                                   parent.NestedCategories).FirstOrDefault(c => c.FullPath == path);

                    if (current == null)
                    {
                        current = new MembersCategory(path, d.DisplayOrder, id);
                        if (i == 0)
                        {
                            _categories.Add(current);
                        }
                        if (parent != null)
                        {
                            parent.NestedCategories.Add(current);
                        }
                    }
                    lookup[path] = current;
                    parent       = current;
                }

                var last = lookup[paths.Last()];
                last.ForceExpand      = d.ForceExpand;
                last.AlwaysHideHeader = d.AlwaysHideHeader;
                resolver.Resolve(_visibleMembers, d).Foreach(last.Members.Add);

                lookup.Clear();
                parent.Members = parent.Members.OrderBy <MemberInfo, float>(VFWVisibilityLogic.GetMemberDisplayOrder).ToList();
            }

            // filter out empty categories
            _categories = _categories.Where(x => x.NestedCategories.Count > 0 || x.Members.Count > 0)
                          .OrderBy(x => x.DisplayOrder)
                          .ToList();

            for (int i = 0; i < _categories.Count; i++)
            {
                var c = _categories[i];
                c.RemoveEmptyNestedCategories();
            }

            var displayKey   = RuntimeHelper.CombineHashCodes(id, "display");
            var displayValue = prefs.Ints.ValueOrDefault(displayKey, -1);
            var vfwSettings  = VFWSettings.GetInstance();

            _display = displayValue == -1 ? vfwSettings.DefaultDisplay : (CategoryDisplay)displayValue;
            prefs.Ints[displayKey] = (int)_display;

            var spacingKey = RuntimeHelper.CombineHashCodes(id, "spacing");

            _spacing = prefs.Ints.ValueOrDefault(spacingKey, vfwSettings.DefaultSpacing);
            prefs.Ints[spacingKey] = _spacing;

            var field = targetType.GetAllMembers(typeof(MonoBehaviour), Flags.InstancePrivate)
                        .FirstOrDefault(m => m.Name == "_serializationData");

            if (field == null)
            {
                throw new vMemberNotFound(targetType, "_serializationData");
            }

            _serializationData = EditorMember.WrapMember(field, target, target, id);

            field = targetType.GetField("dbg", Flags.InstanceAnyVisibility);
            if (field == null)
            {
                throw new vMemberNotFound(targetType, "dbg");
            }

            _debug = EditorMember.WrapMember(field, target, target, id);

            OnAfterInitialized();
        }