예제 #1
0
        public override InspectorPropertyInfo GetChildInfo(int childIndex)
        {
            if (childIndex < 0 || childIndex >= this.ChildCount)
            {
                throw new IndexOutOfRangeException();
            }

            InspectorPropertyInfo result;

            if (!this.childInfos.TryGetValue(childIndex, out result))
            {
                result = InspectorPropertyInfo.CreateValue(
                    name: CollectionResolverUtilities.DefaultIndexToChildName(childIndex),
                    order: childIndex,
                    serializationBackend: this.Property.BaseValueEntry.SerializationBackend,
                    getterSetter: new GetterSetter <TCollection, TElement>(
                        getter: (ref TCollection collection) => this.GetElement(collection, childIndex),
                        setter: (ref TCollection collection, TElement element) => this.SetElement(collection, element, childIndex)),
                    attributes: this.Property.Attributes.Where(attr => !attr.GetType().IsDefined(typeof(DontApplyToListElementsAttribute), true)).ToArray());

                this.childInfos[childIndex] = result;
            }

            return(result);
        }
        public override InspectorPropertyInfo GetChildInfo(int childIndex)
        {
            InspectorPropertyInfo info;

            if (this.childInfos.TryGetValue(childIndex, out info))
            {
                return(info);
            }

            var parameter = this.parameters[childIndex];

            var type = parameter.ParameterType;

            if (type.IsByRef)
            {
                type = type.GetElementType();
            }

            var getterSetterType = typeof(GetterSetter <>).MakeGenericType(type);
            var getterSetter     = Activator.CreateInstance(getterSetterType, new object[] { this.parameterValues, childIndex }) as IValueGetterSetter;

            info = InspectorPropertyInfo.CreateValue(parameter.Name, childIndex, SerializationBackend.None, getterSetter, parameter.GetAttributes());
            this.childInfos[childIndex] = info;

            return(info);
        }
예제 #3
0
        public override void ProcessMemberProperties(List <InspectorPropertyInfo> memberInfos)
        {
            var attr = this.GetClassDefinedTypeInfoBox(this.Property);
            var p    = InspectorPropertyInfo.CreateForMember(InjectedMemberInfo, false, SerializationBackend.None, new Attribute[] { new OnInspectorGUIAttribute(), new InfoBoxAttribute(attr.Message), new PropertyOrderAttribute(-100000) });

            memberInfos.Insert(0, p);
        }
        protected override InspectorPropertyInfo[] GetPropertyInfos()
        {
            this.targetType = this.ValueEntry.TypeOfValue;
            var members = targetType.GetAllMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
            var infos   = new List <InspectorPropertyInfo>();

            this.allowObsoleteMembers = this.Property.Context.GetGlobal("ALLOW_OBSOLETE_STATIC_MEMBERS", false);

            foreach (var member in members.Where(Filter).OrderBy(Order))
            {
                var attributes = new List <Attribute>();
                InspectorPropertyInfoUtility.ProcessAttributes(this.Property, member, attributes);

                if (member is MethodInfo && !attributes.HasAttribute <ButtonAttribute>() && !attributes.HasAttribute <OnInspectorGUIAttribute>())
                {
                    attributes.Add(new ButtonAttribute(ButtonSizes.Medium));
                }

                var info = InspectorPropertyInfo.CreateForMember(member, true, SerializationBackend.None, attributes);

                InspectorPropertyInfo previousPropertyWithName = null;
                int previousPropertyIndex = -1;

                for (int j = 0; j < infos.Count; j++)
                {
                    if (infos[j].PropertyName == info.PropertyName)
                    {
                        previousPropertyIndex    = j;
                        previousPropertyWithName = infos[j];
                        break;
                    }
                }

                if (previousPropertyWithName != null)
                {
                    bool createAlias = true;

                    if (member.SignaturesAreEqual(previousPropertyWithName.GetMemberInfo()))
                    {
                        createAlias = false;
                        infos.RemoveAt(previousPropertyIndex);
                    }

                    if (createAlias)
                    {
                        var alias = InspectorPropertyInfoUtility.GetPrivateMemberAlias(previousPropertyWithName.GetMemberInfo(), previousPropertyWithName.TypeOfOwner.GetNiceName(), " -> ");
                        infos[previousPropertyIndex] = InspectorPropertyInfo.CreateForMember(alias, true, SerializationBackend.None, attributes);
                    }
                }

                infos.Add(info);
            }

            return(InspectorPropertyInfoUtility.BuildPropertyGroupsAndFinalize(this.Property, targetType, infos, false));
        }
예제 #5
0
        public static void AddProcessedMember(this IList <InspectorPropertyInfo> infos, InspectorProperty parentProperty, MemberInfo member, bool allowEditable = true, SerializationBackend backend = SerializationBackend.None, params Attribute[] attributes)
        {
            var list = new List <Attribute>();

            if (attributes != null)
            {
                list.AddRange(attributes);
            }
            InspectorPropertyInfoUtility.ProcessAttributes(parentProperty, member, list);
            infos.Add(InspectorPropertyInfo.CreateForMember(member, allowEditable, backend, list));
        }
예제 #6
0
        public static InspectorPropertyInfo CreateGroup(string name, Type typeOfOwner, int order, InspectorPropertyInfo[] groupInfos, IEnumerable <Attribute> attributes)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }

            if (typeOfOwner == null)
            {
                throw new ArgumentNullException("typeOfOwner");
            }

            if (groupInfos == null)
            {
                throw new ArgumentNullException("groupInfos");
            }

            if (name.Contains('.'))
            {
                throw new ArgumentException("Group names or paths may not contain '.'; was given the path/name '" + name + "'.");
            }

            if (name.Length == 0 || name[0] != '#')
            {
                throw new ArgumentException("The first character in a property group name must be '#'; was given the name '" + name + "'.");
            }

            var result = new InspectorPropertyInfo();

            result.memberInfos = groupInfos.SelectMany(n => n.GetMemberInfos()).ToArray();

            if (attributes == null)
            {
                result.attributes = new List <Attribute>();
            }
            else
            {
                result.attributes = attributes.ToList();
            }

            result.Order                = order;
            result.typeOfOwner          = typeOfOwner;
            result.PropertyName         = name;
            result.PropertyType         = PropertyType.Group;
            result.SerializationBackend = SerializationBackend.None;
            result.IsEditable           = false;
            result.groupInfos           = groupInfos;

            return(result);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ComplexTypePropertyChildren"/> class.
        /// </summary>
        /// <param name="property">The property to handle children for.</param>
        /// <exception cref="System.ArgumentException">
        /// Property to create complex type children for has no value entry.
        /// or
        /// Property must be either a reference type or a value type property.
        /// </exception>
        public ComplexTypePropertyChildren(InspectorProperty property) : base(property)
        {
            if (property.ValueEntry == null)
            {
                throw new ArgumentException("Property to create complex type children for has no value entry.");
            }

            if (property.Info.PropertyType != PropertyType.ReferenceType && property.Info.PropertyType != PropertyType.ValueType)
            {
                throw new ArgumentException("Property must be either a reference type or a value type property.");
            }

            this.ComplexType = property.ValueEntry.TypeOfValue;
            this.infos       = InspectorPropertyInfo.Get(this.ComplexType, property.Tree.IncludesSpeciallySerializedMembers && property.ValueEntry.SerializationBackend != SerializationBackend.Unity);
        }
예제 #8
0
        public static InspectorPropertyInfo CreateForUnityProperty(string unityPropertyName, Type typeOfOwner, Type typeOfValue, bool isEditable, IEnumerable <Attribute> attributes)
        {
            if (unityPropertyName == null)
            {
                throw new ArgumentNullException("unityPropertyName");
            }

            if (typeOfOwner == null)
            {
                throw new ArgumentNullException("typeOfOwner");
            }

            if (typeOfValue == null)
            {
                throw new ArgumentNullException("typeOfValue");
            }

            if (unityPropertyName.Contains('.'))
            {
                throw new ArgumentException("Property names may not contain '.'; was given the name '" + unityPropertyName + "'.");
            }

            var result = new InspectorPropertyInfo();

            result.memberInfos = new MemberInfo[0];

            result.typeOfOwner = typeOfOwner;
            result.typeOfValue = typeOfValue;

            result.PropertyName         = unityPropertyName;
            result.PropertyType         = PropertyType.Value;
            result.SerializationBackend = SerializationBackend.Unity;
            result.IsEditable           = isEditable;

            if (attributes == null)
            {
                result.attributes = new List <Attribute>();
            }
            else
            {
                result.attributes = attributes.Where(attr => attr != null).ToList();
            }

            result.isUnityPropertyOnly = true;

            return(result);
        }
예제 #9
0
        public static InspectorPropertyInfo CreateForDelegate(string name, int order, Type typeOfOwner, Delegate @delegate, IEnumerable <Attribute> attributes)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }

            if (typeOfOwner == null)
            {
                throw new ArgumentNullException("typeOfOwner");
            }

            if (@delegate == null)
            {
                throw new ArgumentNullException("@delegate");
            }

            if (name.Contains('.'))
            {
                throw new ArgumentException("Property names may not contain '.'; was given the name '" + name + "'.");
            }

            var result = new InspectorPropertyInfo();

            result.memberInfos = new MemberInfo[0];

            result.typeOfOwner = typeOfOwner;

            result.PropertyName         = name;
            result.PropertyType         = PropertyType.Method;
            result.SerializationBackend = SerializationBackend.None;

            if (attributes == null)
            {
                result.attributes = new List <Attribute>();
            }
            else
            {
                result.attributes = attributes.Where(attr => attr != null).ToList();
            }

            result.@delegate = @delegate;

            return(result);
        }
예제 #10
0
        public static InspectorPropertyInfo CreateValue(string name, int order, SerializationBackend serializationBackend, IValueGetterSetter getterSetter, IEnumerable <Attribute> attributes)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }

            if (getterSetter == null)
            {
                throw new ArgumentNullException("getterSetter");
            }

            if (name.Contains('.'))
            {
                throw new ArgumentException("Property names may not contain '.'; was given the name '" + name + "'.");
            }

            var result = new InspectorPropertyInfo();

            result.memberInfos = new MemberInfo[0];

            result.typeOfOwner = getterSetter.OwnerType;
            result.typeOfValue = getterSetter.ValueType;

            if (attributes == null)
            {
                result.attributes = new List <Attribute>();
            }
            else
            {
                result.attributes = attributes.Where(attr => attr != null).ToList();
            }

            result.PropertyName         = name;
            result.PropertyType         = PropertyType.Value;
            result.SerializationBackend = serializationBackend;
            result.IsEditable           = !getterSetter.IsReadonly;

            result.getterSetter = getterSetter;

            return(result);
        }
예제 #11
0
        public override InspectorPropertyInfo GetChildInfo(int childIndex)
        {
            if (childIndex == 0)
            {
                var member = typeof(Rect).GetProperty("position");
                List <Attribute> attributes = new List <Attribute>();

                return(InspectorPropertyInfo.CreateForMember(this.Property, member, true, attributes));
            }
            else if (childIndex == 1)
            {
                var member = typeof(Rect).GetProperty("size");
                List <Attribute> attributes = new List <Attribute>();

                return(InspectorPropertyInfo.CreateForMember(this.Property, member, true, attributes));
            }
            else
            {
                throw new NotImplementedException();
            }
        }
        public override InspectorPropertyInfo GetChildInfo(int childIndex)
        {
            this.EnsureUpdated();

            InspectorPropertyInfo result;

            if (!this.childInfos.TryGetValue(childIndex, out result))
            {
                result = InspectorPropertyInfo.CreateValue(
                    name: CollectionResolverUtilities.DefaultIndexToChildName(childIndex),
                    order: childIndex,
                    serializationBackend: this.Property.BaseValueEntry.SerializationBackend,
                    getterSetter: new GetterSetter <TDictionary, EditableKeyValuePair <TKey, TValue> >(
                        getter: this.CreateGetter(childIndex),
                        setter: this.CreateSetter(childIndex)),
                    attributes: this.Property.Attributes);

                this.childInfos[childIndex] = result;
            }

            return(result);
        }
예제 #13
0
        public static void AddProcessedMember(this IList <InspectorPropertyInfo> infos, InspectorProperty parentProperty, string name, bool allowEditable = true, SerializationBackend backend = SerializationBackend.None, params Attribute[] attributes)
        {
            var type = ProcessingOwnerType;

            type = (parentProperty.ValueEntry != null) ? parentProperty.ValueEntry.TypeOfValue : ProcessingOwnerType;

            var members = type.GetMember(name, MemberTypes.Field | MemberTypes.Method | MemberTypes.Property, Flags.AllMembers);

            if (members.Length == 0 || members.Length > 1)
            {
                throw new ArgumentException("Could not find precisely 1 member on type '" + type.GetNiceName() + "' with name '" + name + "'; found " + members.Length + " members.");
            }

            var list = new List <Attribute>();

            if (attributes != null)
            {
                list.AddRange(attributes);
            }
            InspectorPropertyInfoUtility.ProcessAttributes(parentProperty, members[0], list);
            infos.Add(InspectorPropertyInfo.CreateForMember(members[0], allowEditable, backend, list));
        }
예제 #14
0
        private static OdinDrawer[] GetAllDrawers(Type valueType, Type attributeType, List <DrawerInfo> drawers, bool forceUniqueDrawerInstances = false)
        {
            List <DrawerInfo> results = new List <DrawerInfo>();

            if (valueType == typeof(NoType))
            {
                valueType = null;
            }

            if (valueType != null)
            {
                // First, look for drawers which draw this exact type and/or attribute
                results.AddRange(GetExactTypeDrawerInfos(valueType, attributeType, drawers));

                // Then look for generic drawers where this type can fulfill the generic constraints
                results.AddRange(GetGenericTypeDrawerInfos(valueType, attributeType, drawers));
            }

            // Look for exact omni attribute drawers
            results.AddRange(GetExactTypeDrawerInfos(null, attributeType, drawers));

            // Look for generic omni attribute drawers
            results.AddRange(GetGenericTypeDrawerInfos(null, attributeType, drawers));

            foreach (var locator in CustomDrawerLocators)
            {
                results.AddRange(locator.GetDrawers(valueType, attributeType));
            }

            return(results.Distinct()
                   .OrderByDescending(info => info.Priority)
                   .ThenBy(info => info.DrawerType.Name)
                   .Select(info =>
            {
                try
                {
                    return GetDrawer(info.DrawerType, forceUniqueDrawerInstances);
                }
                catch (Exception ex)
                {
                    Debug.Log("Encountered the following exception when trying to instantiate a drawer of type " + info.DrawerType.GetNiceName());
                    Debug.LogException(ex);
                    return null;
                }
            })
                   .Where(drawer => drawer != null && (valueType == null || drawer.CanDrawTypeFilter(valueType)))
                   .Append(() =>
            {
                // Add composite drawer last, if it can be added - it is the final fallback for types with sub properties
                if (valueType != null && attributeType == null && !typeof(UnityEngine.Object).IsAssignableFrom(valueType) && InspectorPropertyInfo.Get(valueType, true).Length > 0)
                {
                    return CompositeDrawer;
                }

                return null;
            })
                   .Where(drawer => drawer != null)
                   .ToArray());
        }
예제 #15
0
        public static InspectorPropertyInfo CreateForMember(MemberInfo member, bool allowEditable, SerializationBackend serializationBackend, List <Attribute> attributes)
        {
            if (member == null)
            {
                throw new ArgumentNullException("member");
            }

            if (!(member is FieldInfo || member is PropertyInfo || member is MethodInfo))
            {
                throw new ArgumentException("Can only create inspector properties for field, property and method members.");
            }

            if (member is MethodInfo && serializationBackend != SerializationBackend.None)
            {
                throw new ArgumentException("Serialization backend can only be None for method members.");
            }

            if (member is MethodInfo && allowEditable)
            {
                //throw new ArgumentException("allowEditable can only be false for method members.");
                allowEditable = false;
            }

            if (allowEditable && member is FieldInfo && (member as FieldInfo).IsLiteral)
            {
                allowEditable = false;
            }

            string name = null;

            if (member is MethodInfo)
            {
                var mi         = member as MethodInfo;
                var parameters = mi.GetParameters();
                if (parameters.Length > 0)
                {
                    name = mi.GetNiceName();
                }
            }

            if (name == null)
            {
                name = member.Name;
            }

            if (name.Contains("."))
            {
                var index = name.LastIndexOf(".") + 1;

                if (index < name.Length)
                {
                    name = name.Substring(index);
                }
                else
                {
                    throw new ArgumentException("A member name somehow had a '.' as the last character. This shouldn't be possible, but the '" + member.Name + "' has messed things up for everyone now. Good job!");
                }
            }

            var result = new InspectorPropertyInfo();

            if (member.IsDefined(typeof(OmitFromPrefabModificationPathsAttribute), true))
            {
                name = "#" + name;
            }

            result.memberInfos          = new MemberInfo[] { member };
            result.PropertyName         = name;
            result.PropertyType         = member is MethodInfo ? PropertyType.Method : PropertyType.Value;
            result.SerializationBackend = serializationBackend;

            if (attributes == null)
            {
                result.attributes = new List <Attribute>();
            }
            else
            {
                result.attributes = attributes;

                for (int i = attributes.Count - 1; i >= 0; i--)
                {
                    var attr = attributes[i];

                    if (attr == null)
                    {
                        attributes.RemoveAt(i);
                        continue;
                    }

                    var orderAttr = attr as PropertyOrderAttribute;
                    if (orderAttr != null)
                    {
                        result.Order = orderAttr.Order;
                    }
                }
            }

            result.typeOfOwner = member.DeclaringType;

            if (member is FieldInfo || member is PropertyInfo)
            {
                var valueType = member.GetReturnType();

                result.typeOfValue = valueType;

                result.getterSetter = GetEmittedGetterSetterCreator(member.DeclaringType, valueType)(member, !allowEditable);

                //if (member is FieldInfo)
                //{
                //    //TwoArgsObjectArray[0] = member;
                //    //TwoArgsObjectArray[1] = !allowEditable;

                //    //var con = getterSetterType.GetConstructor(GetterSetterFieldConstructorSignature);
                //    //result.getterSetter = (IValueGetterSetter)con.Invoke(TwoArgsObjectArray);

                //    //result.getterSetter = (IValueGetterSetter)Activator.CreateInstance(typeof(GetterSetter<,>).MakeGenericType(member.DeclaringType, valueType), member, !allowEditable);

                //    result.getterSetter = GetEmittedFieldGetterSetterCreator(member.DeclaringType, valueType)(member as FieldInfo, !allowEditable);
                //}
                //else
                //{
                //    //OneArgObjectArray[0] = member;

                //    //var con = getterSetterType.GetConstructor(GetterSetterPropertyConstructorSignature);
                //    //result.getterSetter = (IValueGetterSetter)con.Invoke(OneArgObjectArray);

                //    //result.getterSetter = (IValueGetterSetter)Activator.CreateInstance(typeof(GetterSetter<,>).MakeGenericType(member.DeclaringType, valueType), member);

                //}

                result.IsEditable = allowEditable && !attributes.HasAttribute <ReadOnlyAttribute>() && !result.getterSetter.IsReadonly;
            }

            return(result);
        }
예제 #16
0
        internal static InspectorProperty Create(PropertyTree tree, InspectorProperty parent, InspectorPropertyInfo info, int index)
        {
            // Validate parameters first
            if (tree == null)
            {
                throw new ArgumentNullException("tree");
            }

            if (info == null)
            {
                if (parent == null)
                {
                    throw new ArgumentException("A parent is expected when the given InspectorPropertyInfo is null.");
                }

                if (parent.Children.IsCollection == false)
                {
                    throw new ArgumentException("The children of the given parent must be from a collection when the given InspectorPropertyInfo is null.");
                }
            }

            if (parent != null)
            {
                if (tree != parent.Tree)
                {
                    throw new ArgumentException("The given tree and the given parent's tree are not the same tree.");
                }

                if (parent.Children is DisabledPropertyChildren)
                {
                    throw new ArgumentException("A given parent must be able to have children to create a child property for it.");
                }

                if (index < 0 || index >= parent.Children.Count)
                {
                    throw new IndexOutOfRangeException("The given index for the property to create is out of bounds.");
                }
            }
            else
            {
                index = -1;
            }

            // Now start building a property
            InspectorProperty property = new InspectorProperty();

            property.Tree = tree;

            if (parent != null)
            {
                property.Path = parent.Children.GetPath(index);
            }
            else
            {
                property.Path = info.PropertyName;
            }

            property.Parent = parent;

            property.Index   = index;
            property.Context = new PropertyContextContainer(property);

            if (property.Path == null)
            {
                Debug.Log("Property path is null for property " + property.NiceName + "!");
            }

            {
                InspectorProperty current = property;

                do
                {
                    current = current.Parent;
                }while (current != null && current.BaseValueEntry == null);

                property.ParentValueProperty = current;
            }

            if (property.ParentValueProperty != null)
            {
                property.ParentType   = property.ParentValueProperty.ValueEntry.TypeOfValue;
                property.ParentValues = new ImmutableList(property.ParentValueProperty.ValueEntry.WeakValues);
            }
            else
            {
                property.ParentType   = tree.TargetType;
                property.ParentValues = new ImmutableList(tree.WeakTargets);
            }

            if (info != null)
            {
                property.Info     = info;
                property.Name     = info.PropertyName;
                property.NiceName = ObjectNames.NicifyVariableName(property.Name.TrimStart('#'));
                property.Label    = new GUIContent(property.NiceName);
            }
            else
            {
                // Collection elements inherit the info of the collection itself
                // and have their name set a little further down
                property.Info = parent.Info;
            }

            if (property.Info.PropertyType == PropertyType.ValueType || property.Info.PropertyType == PropertyType.ReferenceType)
            {
                property.BaseValueEntry = PropertyValueEntry.Create(property, InspectorProperty.GetBaseContainedValueType(property));
                property.ValueEntry     = property.BaseValueEntry;
            }

            if (info == null)
            {
                property.ForceUpdatePropertyNameAndPath(index);
            }

            // Do NOT update the property here. Property updating may cause this property to be requested before
            // it has been registered, resulting in an infinite loop. It is the calling code's responsibility to
            // update the property before usage.

            return(property);
        }
예제 #17
0
 public static void AddDelegate(this IList <InspectorPropertyInfo> infos, string name, Delegate @delegate, int order = 0, params Attribute[] attributes)
 {
     infos.Add(InspectorPropertyInfo.CreateForDelegate(name, order, typeof(object), (Delegate)@delegate, attributes));
 }
예제 #18
0
 public override bool ChildPropertyRequiresRefresh(int index, InspectorPropertyInfo info)
 {
     return(this.GetChildInfo(index) != info);
 }
예제 #19
0
 public override bool ChildPropertyRequiresRefresh(int index, InspectorPropertyInfo info)
 {
     return(false);
 }
예제 #20
0
        //internal void ForceUpdatePropertyNameAndPath(int? newIndex)
        //{
        //    if (newIndex != null)
        //    {
        //        this.Index = newIndex.Value;
        //    }

        //    this.unityPropertyPath = null;
        //    this.prefabModificationPath = null;

        //    if (this.Parent != null)
        //    {
        //        this.Path = this.Parent.Children.GetPath(this.Index);
        //    }
        //    else
        //    {
        //        this.Path = this.Info.PropertyName;
        //    }

        //    // Children may be null, as this may be called before the property has ever updated itself
        //    if (this.Children != null)
        //    {
        //        this.Children.ClearCaches();

        //        for (int i = 0; i < this.Children.Count; i++)
        //        {
        //            this.Children[i].ForceUpdatePropertyNameAndPath(null);
        //        }
        //    }
        //}

        internal static InspectorProperty Create(PropertyTree tree, InspectorProperty parent, InspectorPropertyInfo info, int index, bool isSecretRoot)
        {
            // Validate parameters first
            if (tree == null)
            {
                throw new ArgumentNullException("tree");
            }

            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            if (parent != null)
            {
                if (tree != parent.Tree)
                {
                    throw new ArgumentException("The given tree and the given parent's tree are not the same tree.");
                }

                if (index < 0 || index >= parent.Children.Count)
                {
                    throw new IndexOutOfRangeException("The given index for the property to create is out of bounds.");
                }
            }

            // Now start building a property
            InspectorProperty property = new InspectorProperty();

            // Set some basic values
            property.Tree    = tree;
            property.Info    = info;
            property.Parent  = parent;
            property.Index   = index;
            property.Context = new PropertyContextContainer(property);

            // Find property path
            {
                if (parent != null)
                {
                    property.Path = parent.Children.GetPath(index);
                }
                else
                {
                    property.Path = info.PropertyName;
                }

                if (property.Path == null)
                {
                    Debug.Log("Property path is null for property " + ObjectNames.NicifyVariableName(info.PropertyName.TrimStart('#', '$')) + "!");
                }
            }

            // Find parent value property
            if (parent != null)
            {
                InspectorProperty current = property;

                do
                {
                    current = current.Parent;
                }while (current != null && current.BaseValueEntry == null);

                property.ParentValueProperty = current;
            }

            // Set parent type and values
            if (property.ParentValueProperty != null)
            {
                property.ParentType   = property.ParentValueProperty.ValueEntry.TypeOfValue;
                property.ParentValues = new ImmutableList(property.ParentValueProperty.ValueEntry.WeakValues);
            }
            else
            {
                property.ParentType   = tree.TargetType;
                property.ParentValues = new ImmutableList(tree.WeakTargets);
            }

            // Find serializing/owning property
            {
                InspectorProperty current = property.ParentValueProperty;

                while (current != null && !current.ValueEntry.TypeOfValue.InheritsFrom(typeof(UnityEngine.Object)))
                {
                    current = current.ParentValueProperty;
                }

                if (current != null)
                {
                    property.SerializationRoot = current;
                }
                else
                {
                    property.SerializationRoot = isSecretRoot ? property : tree.SecretRootProperty;
                }
            }

            // Set name and label
            {
                property.Name = info.PropertyName;

                var mi = property.Info.GetMemberInfo() as MethodInfo;
                if (mi != null)
                {
                    var name        = property.Name;
                    var parensIndex = name.IndexOf('(');

                    if (parensIndex >= 0)
                    {
                        name = name.Substring(0, parensIndex);
                    }

                    property.NiceName = name.TrimStart('#', '$').SplitPascalCase();
                }
                else
                {
                    property.NiceName = ObjectNames.NicifyVariableName(property.Name.TrimStart('#', '$'));
                }

                property.Label = new GUIContent(property.NiceName);
            }

            // Create a value entry if necessary
            if (property.Info.PropertyType == PropertyType.Value)
            {
                property.BaseValueEntry = PropertyValueEntry.Create(property, info.TypeOfValue, isSecretRoot);
                property.ValueEntry     = property.BaseValueEntry;
            }

            // Do NOT update the property here. Property updating may cause this property to be requested before
            // it has been registered, resulting in an infinite loop. It is the calling code's responsibility to
            // update the property before usage.

            if (!isSecretRoot)
            {
                property.RefreshProcessedAttributes();
                property.ChildResolver = tree.PropertyResolverLocator.GetResolver(property);
                property.Children      = new PropertyChildren(property);
            }

            return(property);
        }
예제 #21
0
 public abstract bool ChildPropertyRequiresRefresh(int index, InspectorPropertyInfo info);
예제 #22
0
 public static void AddValue <TValue>(this IList <InspectorPropertyInfo> infos, string name, Func <TValue> getter, Action <TValue> setter, int order = 0, SerializationBackend backend = SerializationBackend.None, params Attribute[] attributes)
 {
     infos.Add(InspectorPropertyInfo.CreateValue(name, order, backend, new GetterSetter <object, TValue>(getter, setter), attributes));
 }
예제 #23
0
 public static void AddMember(this IList <InspectorPropertyInfo> infos, MemberInfo member, bool allowEditable = true, SerializationBackend backend = SerializationBackend.None, params Attribute[] attributes)
 {
     infos.Add(InspectorPropertyInfo.CreateForMember(member, allowEditable, backend, attributes ?? new Attribute[0]));
 }