コード例 #1
0
        /// <summary>
        /// Gets a list of <see cref="OdinAttributeProcessor"/> to process attributes for the specified property.
        /// </summary>
        /// <param name="property">The property to find attribute porcessors for.</param>
        /// <returns>List of <see cref="OdinAttributeProcessor"/> to process attributes for the speicied member.</returns>
        public override List <OdinAttributeProcessor> GetSelfProcessors(InspectorProperty property)
        {
            List <OdinAttributeProcessor> processors = new List <OdinAttributeProcessor>();

            CachedMatchesList.Clear();
            CachedMatchesList.Add(SearchIndex.GetMatches(Type.EmptyTypes));

            if (property.ValueEntry != null)
            {
                CachedMatchesList.Add(SearchIndex.GetMatches(property.ValueEntry.TypeOfValue));
            }

            var results = TypeSearchIndex.GetCachedMergedQueryResults(CachedMatchesList);

            for (int i = 0; i < results.Length; i++)
            {
                var result   = results[i];
                var resolver = GetResolverInstance(result.MatchedType);

                if (resolver.CanProcessSelfAttributes(property))
                {
                    processors.Add(resolver);
                }
            }

            return(processors);
        }
コード例 #2
0
ファイル: DrawerUtilities.cs プロジェクト: treert/om.unity.xx
        public static void GetDefaultPropertyDrawers(InspectorProperty property, List <TypeSearchResult> resultList)
        {
            resultList.Clear();

            var queries = CachedQueryResultList;

            queries.Clear();

            // First we make and gather lots of small queries, which are essentially instant, as they are
            //  all cached by the search index.
            {
                // Empty query (for all drawers with no type constraints at all)
                queries.Add(SearchIndex.GetMatches(Type.EmptyTypes));

                // Value query
                if (property.ValueEntry != null)
                {
                    queries.Add(SearchIndex.GetMatches(property.ValueEntry.TypeOfValue));
                }

                // Attribute queries
                for (int i = 0; i < property.Attributes.Count; i++)
                {
                    var attr = property.Attributes[i].GetType();
                    queries.Add(SearchIndex.GetMatches(attr));

                    // Attribute and value query
                    if (property.ValueEntry != null)
                    {
                        queries.Add(SearchIndex.GetMatches(attr, property.ValueEntry.TypeOfValue));

                        if (InvalidAttributeTargetUtility.ShowInvalidAttributeErrorFor(property, attr))
                        {
                            queries.Add(GetInvalidAttributeTypeSearchResult(attr));
                        }
                    }
                }
            }

            var finalResults = TypeSearchIndex.GetCachedMergedQueryResults(queries);

            // Build up the final result list, filtering invalid drawer types away
            //  as we go.
            for (int i = 0; i < finalResults.Length; i++)
            {
                var result = finalResults[i];

                if (DrawerTypeCanDrawProperty(result.MatchedType, property))
                {
                    resultList.Add(finalResults[i]);
                }
            }
        }
コード例 #3
0
        protected virtual Validator[] CreateValidators(Type valueType)
        {
            List <Validator> validators = new List <Validator>();

            SearchResultList.Clear();

            SearchResultList.Add(ValueValidatorSearchIndex.GetMatches(Type.EmptyTypes));
            SearchResultList.Add(ValueValidatorSearchIndex.GetMatches(valueType));

            // @TODO Tor support this so it also works with attributes despite there being no member
            //var attributes = valueType.GetAttributes<Attribute>().ToList();

            //foreach (var attribute in attributes)
            //{
            //    SearchResultList.Add(AttributeValidatorSearchIndex.GetMatches(attribute.GetType()));
            //    SearchResultList.Add(AttributeValidatorSearchIndex.GetMatches(attribute.GetType(), valueType));
            //}

            ResultList.Clear();

            TypeSearchIndex.MergeQueryResultsIntoList(SearchResultList, ResultList);

            for (int i = 0; i < ResultList.Count; i++)
            {
                var result = ResultList[i];

                if (this.CustomValidatorFilter != null && !this.CustomValidatorFilter(result.MatchedType))
                {
                    continue;
                }

                try
                {
                    var validator = (Validator)Activator.CreateInstance(result.MatchedType);

                    if (validator.CanValidateValues() && validator.CanValidateValue(valueType))
                    {
                        validator.Initialize(valueType);
                        validators.Add(validator);
                    }
                }
                catch (Exception ex)
                {
                    validators.Add(new BrokenAttributeValidator(result.MatchedType, ValidationKind.Value, "Creating instance of validator '" + result.MatchedType.GetNiceName() + "' failed with exception: " + ex.ToString()));
                }
            }

            return(validators.ToArray());
        }
コード例 #4
0
        /// <summary>
        /// Gets an <see cref="OdinPropertyResolver"/> instance for the specified property.
        /// </summary>
        /// <param name="property">The property to get an <see cref="OdinPropertyResolver"/> instance for.</param>
        /// <returns>An instance of <see cref="OdinPropertyResolver"/> to resolver the specified property.</returns>
        public override OdinPropertyResolver GetResolver(InspectorProperty property)
        {
            if (property.Tree.IsStatic && property == property.Tree.SecretRootProperty)
            {
                return(OdinPropertyResolver.Create(typeof(StaticRootPropertyResolver <>).MakeGenericType(property.ValueEntry.TypeOfValue), property));
            }

            var queries = QueryResultsList;

            queries.Clear();

            queries.Add(SearchIndex.GetMatches(Type.EmptyTypes));

            Type typeOfValue = property.ValueEntry != null ? property.ValueEntry.TypeOfValue : null;

            if (typeOfValue != null)
            {
                queries.Add(SearchIndex.GetMatches(typeOfValue));

                for (int i = 0; i < property.Attributes.Count; i++)
                {
                    queries.Add(SearchIndex.GetMatches(typeOfValue, property.Attributes[i].GetType()));
                }
            }

            TypeSearchIndex.MergeQueryResultsIntoList(queries, MergedSearchResultsList);

            for (int i = 0; i < MergedSearchResultsList.Count; i++)
            {
                var info = MergedSearchResultsList[i];

                if (GetEmptyResolverInstance(info.MatchedType).CanResolveForPropertyFilter(property))
                {
                    return(OdinPropertyResolver.Create(info.MatchedType, property));
                }
            }

            return(OdinPropertyResolver.Create <EmptyPropertyResolver>(property));
        }
コード例 #5
0
        public static List <OdinPropertyProcessor> GetMemberProcessors(InspectorProperty property)
        {
            var queries = CachedQueryList;

            queries.Clear();

            //var results = CachedResultList;
            //results.Clear();

            queries.Add(SearchIndex.GetMatches(Type.EmptyTypes));

            if (property.ValueEntry != null)
            {
                var valueType = property.ValueEntry.TypeOfValue;

                queries.Add(SearchIndex.GetMatches(valueType));

                for (int i = 0; i < property.Attributes.Count; i++)
                {
                    queries.Add(SearchIndex.GetMatches(valueType, property.Attributes[i].GetType()));
                }
            }

            var results = TypeSearchIndex.GetCachedMergedQueryResults(queries);

            List <OdinPropertyProcessor> processors = new List <OdinPropertyProcessor>();

            for (int i = 0; i < results.Length; i++)
            {
                var result = results[i];
                if (GetEmptyInstance(result.MatchedType).CanProcessForProperty(property))
                {
                    processors.Add(OdinPropertyProcessor.Create(result.MatchedType, property));
                }
            }

            return(processors);
        }
コード例 #6
0
ファイル: DrawerUtilities.cs プロジェクト: treert/om.unity.xx
        public static IEnumerable <TypeSearchResult> GetDefaultPropertyDrawers(InspectorProperty property)
        {
            var queries = CachedQueryResultList;

            queries.Clear();

            // First we make and gather lots of small queries, which are essentially instant, as they are
            //  all cached by the search index.
            {
                // Empty query (for all drawers with no type constraints at all)
                queries.Add(SearchIndex.GetMatches(Type.EmptyTypes));

                // Value query
                if (property.ValueEntry != null)
                {
                    queries.Add(SearchIndex.GetMatches(property.ValueEntry.TypeOfValue));
                }

                // Attribute queries
                for (int i = 0; i < property.Attributes.Count; i++)
                {
                    var attr = property.Attributes[i].GetType();
                    queries.Add(SearchIndex.GetMatches(attr));

                    // Attribute and value query
                    if (property.ValueEntry != null)
                    {
                        queries.Add(SearchIndex.GetMatches(attr, property.ValueEntry.TypeOfValue));

                        if (InvalidAttributeTargetUtility.ShowInvalidAttributeErrorFor(property, attr))
                        {
                            queries.Add(new TypeSearchResult[]
                            {
                                new TypeSearchResult()
                                {
                                    MatchedInfo = new TypeSearchInfo()
                                    {
                                        MatchType = typeof(InvalidAttributeNotificationDrawer <>),
                                        Priority  = double.MaxValue,
                                        Targets   = Type.EmptyTypes
                                    },
                                    MatchedRule    = InvalidAttributeRule,
                                    MatchedTargets = Type.EmptyTypes,
                                    MatchedType    = typeof(InvalidAttributeNotificationDrawer <>).MakeGenericType(attr)
                                }
                            });
                        }
                    }
                }
            }

            var finalResults = TypeSearchIndex.GetCachedMergedQueryResults(queries);

            // Yield the final result array, filtering invalid drawer types away
            //  as we go.
            for (int i = 0; i < finalResults.Length; i++)
            {
                var result = finalResults[i];

                if (DrawerTypeCanDrawProperty(result.MatchedType, property))
                {
                    yield return(finalResults[i]);
                }
            }
        }
コード例 #7
0
        static DefaultValidatorLocator()
        {
            ValueValidatorSearchIndex     = new TypeSearchIndex();
            AttributeValidatorSearchIndex = new TypeSearchIndex();

            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                foreach (var attr in assembly.GetAttributes <RegisterValidatorAttribute>())
                {
                    var type = attr.ValidatorType;

                    if (!type.InheritsFrom <Validator>())
                    {
                        Debug.LogError("The registered validator type " + attr.ValidatorType.GetNiceFullName() + " is not derived from " + typeof(Validator).GetNiceFullName());
                        continue;
                    }

                    if (type.ImplementsOpenGenericClass(typeof(AttributeValidator <,>)))
                    {
                        AttributeValidatorSearchIndex.AddIndexedType(new TypeSearchInfo()
                        {
                            MatchType = type,
                            Targets   = type.GetArgumentsOfInheritedOpenGenericClass(typeof(AttributeValidator <,>)),
                            Priority  = attr.Priority
                        });
                    }
                    else if (type.ImplementsOpenGenericClass(typeof(AttributeValidator <>)))
                    {
                        AttributeValidatorSearchIndex.AddIndexedType(new TypeSearchInfo()
                        {
                            MatchType = type,
                            Targets   = type.GetArgumentsOfInheritedOpenGenericClass(typeof(AttributeValidator <>)),
                            Priority  = attr.Priority
                        });
                    }
                    else if (type.ImplementsOpenGenericClass(typeof(ValueValidator <>)))
                    {
                        ValueValidatorSearchIndex.AddIndexedType(new TypeSearchInfo()
                        {
                            MatchType = type,
                            Targets   = type.GetArgumentsOfInheritedOpenGenericClass(typeof(ValueValidator <>)),
                            Priority  = attr.Priority
                        });
                    }
                    else
                    {
                        ValueValidatorSearchIndex.AddIndexedType(new TypeSearchInfo()
                        {
                            MatchType = type,
                            Targets   = Type.EmptyTypes,
                            Priority  = attr.Priority,
                        });

                        AttributeValidatorSearchIndex.AddIndexedType(new TypeSearchInfo()
                        {
                            MatchType = type,
                            Targets   = Type.EmptyTypes,
                            Priority  = attr.Priority,
                        });
                    }
                }
            }
        }
コード例 #8
0
        protected virtual Validator[] CreateValidators(MemberInfo member, Type memberValueType, bool isCollectionElement)
        {
            List <Validator> validators = new List <Validator>();

            SearchResultList.Clear();

            SearchResultList.Add(AttributeValidatorSearchIndex.GetMatches(Type.EmptyTypes));
            SearchResultList.Add(ValueValidatorSearchIndex.GetMatches(memberValueType));

            var attributes = member.GetAttributes <Attribute>().ToList();

            attributes.AddRange(memberValueType.GetAttributes <Attribute>());

            foreach (var attribute in attributes)
            {
                if (isCollectionElement && attribute.GetType().IsDefined <DontApplyToListElementsAttribute>(true))
                {
                    continue;
                }

                SearchResultList.Add(AttributeValidatorSearchIndex.GetMatches(attribute.GetType()));
                SearchResultList.Add(AttributeValidatorSearchIndex.GetMatches(attribute.GetType(), memberValueType));
            }

            ResultList.Clear();
            AttributeNumberMap.Clear();

            TypeSearchIndex.MergeQueryResultsIntoList(SearchResultList, ResultList);

            for (int i = 0; i < ResultList.Count; i++)
            {
                var result = ResultList[i];

                if (this.CustomValidatorFilter != null && !this.CustomValidatorFilter(result.MatchedType))
                {
                    continue;
                }

                try
                {
                    Validator validator = (Validator)Activator.CreateInstance(result.MatchedType);

                    if (validator is IAttributeValidator)
                    {
                        Attribute validatorAttribute = null;
                        Type      attrType           = result.MatchedTargets[0];

                        if (!attrType.InheritsFrom <Attribute>())
                        {
                            throw new NotSupportedException("Please don't manually implement the IAttributeValidator interface on any types; it's a special snowflake.");
                        }

                        int number, seen = 0;
                        AttributeNumberMap.TryGetValue(attrType, out number);

                        for (int j = 0; j < attributes.Count; j++)
                        {
                            var attr = attributes[j];

                            if (attr.GetType() == attrType)
                            {
                                if (seen == number)
                                {
                                    validatorAttribute = attr;
                                    break;
                                }
                                else
                                {
                                    seen++;
                                }
                            }
                        }

                        if (validatorAttribute == null)
                        {
                            throw new Exception("Could not find the correctly numbered attribute of type '" + attrType.GetNiceFullName() + "' on member " + member.DeclaringType.GetNiceName() + "." + member.Name + "; found " + seen + " attributes of that type, but needed number " + number + ".");
                        }

                        (validator as IAttributeValidator).SetAttributeInstance(validatorAttribute);

                        number++;
                        AttributeNumberMap[attrType] = number;
                    }

                    if (validator.CanValidateValues() && validator.CanValidateValue(memberValueType))
                    {
                        validator.Initialize(memberValueType);
                        validators.Add(validator);
                    }
                    else if (validator.CanValidateMembers() && validator.CanValidateMember(member, memberValueType))
                    {
                        validator.Initialize(member, memberValueType);
                        validators.Add(validator);
                    }
                }
                catch (Exception ex)
                {
                    validators.Add(new BrokenAttributeValidator(result.MatchedType, ValidationKind.Member, "Creating instance of validator '" + result.MatchedType.GetNiceName() + "' failed with exception: " + ex.ToString()));
                }
            }

            return(validators.ToArray());
        }