diff --git a/Editor.Extras/Drawers/ButtonDrawer.cs b/Editor.Extras/Drawers/ButtonDrawer.cs index 6bd48cd..20b0c2a 100644 --- a/Editor.Extras/Drawers/ButtonDrawer.cs +++ b/Editor.Extras/Drawers/ButtonDrawer.cs @@ -16,7 +16,9 @@ namespace TriInspector.Drawers public override TriExtensionInitializationResult Initialize(TriPropertyDefinition propertyDefinition) { - var isValidMethod = propertyDefinition.MemberInfo is MethodInfo mi && mi.GetParameters().Length == 0; + var isValidMethod = propertyDefinition.TryGetMemberInfo(out var memberInfo) && + memberInfo is MethodInfo mi && + mi.GetParameters().Length == 0; if (!isValidMethod) { return "[Button] valid only on methods without parameters"; @@ -64,20 +66,21 @@ namespace TriInspector.Drawers private static void InvokeButton(TriProperty property, object[] parameters) { - var methodInfo = (MethodInfo) property.MemberInfo; - - property.ModifyAndRecordForUndo(targetIndex => + if (property.TryGetMemberInfo(out var memberInfo) && memberInfo is MethodInfo methodInfo) { - try + property.ModifyAndRecordForUndo(targetIndex => { - var parentValue = property.Parent.GetValue(targetIndex); - methodInfo.Invoke(parentValue, parameters); - } - catch (Exception e) - { - Debug.LogException(e); - } - }); + try + { + var parentValue = property.Parent.GetValue(targetIndex); + methodInfo.Invoke(parentValue, parameters); + } + catch (Exception e) + { + Debug.LogException(e); + } + }); + } } } } \ No newline at end of file diff --git a/Editor.Integrations/Odin/TriPropertyTreeForOdin.cs b/Editor.Integrations/Odin/TriPropertyTreeForOdin.cs index cda8036..6c30287 100644 --- a/Editor.Integrations/Odin/TriPropertyTreeForOdin.cs +++ b/Editor.Integrations/Odin/TriPropertyTreeForOdin.cs @@ -1,4 +1,6 @@ -using Sirenix.OdinInspector.Editor; +using System; +using System.Collections.Generic; +using Sirenix.OdinInspector.Editor; using Sirenix.Utilities.Editor; using UnityEditor; using Object = UnityEngine.Object; @@ -27,6 +29,7 @@ namespace TriInspector.Editor.Integrations.Odin RootPropertyDefinition = new TriPropertyDefinition( memberInfo: odinValueEntry.Property.Info.GetMemberInfo(), + ownerType: odinValueEntry.Property.Info.TypeOfOwner, order: -1, fieldName: odinValueEntry.Property.Name, fieldType: odinValueEntry.TypeOfValue, @@ -36,6 +39,7 @@ namespace TriInspector.Editor.Integrations.Odin _odinValueEntry.Values[targetIndex] = (T) value; return null; }, + attributes: new List(), isArrayElement: false ); RootProperty = new TriProperty(this, null, RootPropertyDefinition, -1, _serializedProperty); diff --git a/Editor/Resolvers/InstanceActionResolver.cs b/Editor/Resolvers/InstanceActionResolver.cs index 09bec14..a3eb69d 100644 --- a/Editor/Resolvers/InstanceActionResolver.cs +++ b/Editor/Resolvers/InstanceActionResolver.cs @@ -11,7 +11,7 @@ namespace TriInspector.Resolvers public static bool TryResolve(TriPropertyDefinition propertyDefinition, string method, out ActionResolver resolver) { - var parentType = propertyDefinition.MemberInfo.DeclaringType; + var parentType = propertyDefinition.OwnerType; if (parentType == null) { resolver = null; diff --git a/Editor/Resolvers/InstanceFieldValueResolver.cs b/Editor/Resolvers/InstanceFieldValueResolver.cs index e346baa..c4bdce9 100644 --- a/Editor/Resolvers/InstanceFieldValueResolver.cs +++ b/Editor/Resolvers/InstanceFieldValueResolver.cs @@ -11,7 +11,7 @@ namespace TriInspector.Resolvers public static bool TryResolve(TriPropertyDefinition propertyDefinition, string expression, out ValueResolver resolver) { - var parentType = propertyDefinition.MemberInfo.DeclaringType; + var parentType = propertyDefinition.OwnerType; if (parentType == null) { resolver = null; diff --git a/Editor/Resolvers/InstanceMethodValueResolver.cs b/Editor/Resolvers/InstanceMethodValueResolver.cs index b1fa51b..1653339 100644 --- a/Editor/Resolvers/InstanceMethodValueResolver.cs +++ b/Editor/Resolvers/InstanceMethodValueResolver.cs @@ -11,7 +11,7 @@ namespace TriInspector.Resolvers public static bool TryResolve(TriPropertyDefinition propertyDefinition, string expression, out ValueResolver resolver) { - var parentType = propertyDefinition.MemberInfo.DeclaringType; + var parentType = propertyDefinition.OwnerType; if (parentType == null) { resolver = null; diff --git a/Editor/Resolvers/InstancePropertyValueResolver.cs b/Editor/Resolvers/InstancePropertyValueResolver.cs index dd2a8e7..e48ad94 100644 --- a/Editor/Resolvers/InstancePropertyValueResolver.cs +++ b/Editor/Resolvers/InstancePropertyValueResolver.cs @@ -11,7 +11,7 @@ namespace TriInspector.Resolvers public static bool TryResolve(TriPropertyDefinition propertyDefinition, string expression, out ValueResolver resolver) { - var parentType = propertyDefinition.MemberInfo.DeclaringType; + var parentType = propertyDefinition.OwnerType; if (parentType == null) { resolver = null; diff --git a/Editor/TriProperty.cs b/Editor/TriProperty.cs index b7e6a99..facc129 100644 --- a/Editor/TriProperty.cs +++ b/Editor/TriProperty.cs @@ -169,9 +169,6 @@ namespace TriInspector } } - [PublicAPI] - public MemberInfo MemberInfo => _definition.MemberInfo; - [PublicAPI] public Type FieldType => _definition.FieldType; @@ -209,7 +206,7 @@ namespace TriInspector if (_isExpandedPrefsKey == null) { - _isExpandedPrefsKey = $"TriInspector.expanded.{PropertyTree.TargetObjectType}.{MemberInfo}"; + _isExpandedPrefsKey = $"TriInspector.expanded.{PropertyTree.TargetObjectType}.{RawName}"; } return EditorPrefs.GetBool(_isExpandedPrefsKey, false); @@ -305,6 +302,12 @@ namespace TriInspector } } + [PublicAPI] + public bool TryGetMemberInfo(out MemberInfo memberInfo) + { + return _definition.TryGetMemberInfo(out memberInfo); + } + public object GetValue(int targetIndex) { return _definition.GetValue(this, targetIndex); diff --git a/Editor/TriPropertyDefinition.cs b/Editor/TriPropertyDefinition.cs index dc08b23..98c4f13 100644 --- a/Editor/TriPropertyDefinition.cs +++ b/Editor/TriPropertyDefinition.cs @@ -16,6 +16,8 @@ namespace TriInspector [CanBeNull] private readonly ValueSetterDelegate _valueSetter; private readonly List _extensionErrors = new List(); + private readonly MemberInfo _memberInfo; + private readonly List _attributes; private TriPropertyDefinition _arrayElementDefinitionBackingField; @@ -24,40 +26,54 @@ namespace TriInspector private IReadOnlyList _hideProcessorsBackingField; private IReadOnlyList _disableProcessorsBackingField; - internal TriPropertyDefinition(int order, FieldInfo fi) - : this(fi, order, fi.Name, fi.FieldType, MakeGetter(fi), MakeSetter(fi), false) + public static TriPropertyDefinition CreateForFieldInfo(int order, FieldInfo fi) { + return CreateForMemberInfo(fi, order, fi.Name, fi.FieldType, MakeGetter(fi), MakeSetter(fi)); } - internal TriPropertyDefinition(int order, PropertyInfo pi) - : this(pi, order, pi.Name, pi.PropertyType, MakeGetter(pi), MakeSetter(pi), false) + public static TriPropertyDefinition CreateForPropertyInfo(int order, PropertyInfo pi) { + return CreateForMemberInfo(pi, order, pi.Name, pi.PropertyType, MakeGetter(pi), MakeSetter(pi)); } - internal TriPropertyDefinition(int order, MethodInfo mi) - : this(mi, order, mi.Name, typeof(MethodInfo), MakeGetter(mi), MakeSetter(mi), false) + public static TriPropertyDefinition CreateForMethodInfo(int order, MethodInfo mi) { + return CreateForMemberInfo(mi, order, mi.Name, typeof(MethodInfo), MakeGetter(mi), MakeSetter(mi)); + } + + private static TriPropertyDefinition CreateForMemberInfo( + MemberInfo memberInfo, int order, string propertyName, Type propertyType, + ValueGetterDelegate valueGetter, ValueSetterDelegate valueSetter) + { + var attributes = memberInfo?.GetCustomAttributes().ToList(); + var ownerType = memberInfo?.DeclaringType ?? typeof(object); + + return new TriPropertyDefinition( + memberInfo, ownerType, order, propertyName, propertyType, valueGetter, valueSetter, attributes, false); } internal TriPropertyDefinition( MemberInfo memberInfo, + Type ownerType, int order, string fieldName, Type fieldType, ValueGetterDelegate valueGetter, ValueSetterDelegate valueSetter, + List attributes, bool isArrayElement) { - MemberInfo = memberInfo; + OwnerType = ownerType; Name = fieldName; FieldType = fieldType; IsArrayElement = isArrayElement; + _attributes = attributes ?? new List(); + _memberInfo = memberInfo; _valueGetter = valueGetter; _valueSetter = valueSetter; - Attributes = memberInfo?.GetCustomAttributes().ToList() ?? new List(); - Order = Attributes.TryGet(out PropertyOrderAttribute orderAttribute) ? orderAttribute.Order : order; + Order = order; IsReadOnly = _valueSetter == null || Attributes.TryGet(out ReadOnlyAttribute _); if (TriReflectionUtilities.IsArrayOrList(FieldType, out var elementType)) @@ -77,15 +93,15 @@ namespace TriInspector } } - public MemberInfo MemberInfo { get; } + public Type OwnerType { get; } public Type FieldType { get; } public string Name { get; } - public int Order { get; } + public int Order { get; internal set; } - public IReadOnlyList Attributes { get; } + public IReadOnlyList Attributes => _attributes; public bool IsReadOnly { get; } @@ -114,6 +130,17 @@ namespace TriInspector } } + public List GetEditableAttributes() + { + return _attributes; + } + + public bool TryGetMemberInfo(out MemberInfo memberInfo) + { + memberInfo = _memberInfo; + return memberInfo != null; + } + public object GetValue(TriProperty property, int targetIndex) { return _valueGetter(property, targetIndex); @@ -144,7 +171,6 @@ namespace TriInspector $"Cannot get array element definition for non array property: {FieldType}"); } - var elementMember = MemberInfo; var elementGetter = new ValueGetterDelegate((self, targetIndex) => { var parentValue = (IList) self.Parent.GetValue(targetIndex); @@ -157,8 +183,8 @@ namespace TriInspector return parentValue; }); - _arrayElementDefinitionBackingField = new TriPropertyDefinition(elementMember, 0, "Element", - ArrayElementType, elementGetter, elementSetter, true); + _arrayElementDefinitionBackingField = new TriPropertyDefinition(_memberInfo, OwnerType, 0, + "Element", ArrayElementType, elementGetter, elementSetter, _attributes, true); } return _arrayElementDefinitionBackingField; diff --git a/Editor/TriPropertyTree.cs b/Editor/TriPropertyTree.cs index 07a2788..a508756 100644 --- a/Editor/TriPropertyTree.cs +++ b/Editor/TriPropertyTree.cs @@ -56,7 +56,7 @@ namespace TriInspector { _rootPropertyElement = new TriPropertyElement(RootProperty, new TriPropertyElement.Props { - forceInline = RootProperty.MemberInfo == null, + forceInline = !RootProperty.TryGetMemberInfo(out _), }); _rootPropertyElement.AttachInternal(); } diff --git a/Editor/TriPropertyTreeForSerializedObject.cs b/Editor/TriPropertyTreeForSerializedObject.cs index a9b2d40..57f4eda 100644 --- a/Editor/TriPropertyTreeForSerializedObject.cs +++ b/Editor/TriPropertyTreeForSerializedObject.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using JetBrains.Annotations; using UnityEditor; @@ -19,11 +20,13 @@ namespace TriInspector RootPropertyDefinition = new TriPropertyDefinition( memberInfo: null, + ownerType: null, order: -1, fieldName: "ROOT", fieldType: TargetObjectType, valueGetter: (self, targetIndex) => _serializedObject.targetObjects[targetIndex], valueSetter: (self, targetIndex, value) => _serializedObject.targetObjects[targetIndex], + attributes: new List(), isArrayElement: false); RootProperty = new TriProperty(this, null, RootPropertyDefinition, serializedObject); diff --git a/Editor/TriTypeProcessor.cs b/Editor/TriTypeProcessor.cs index 9f2e5ab..d7ed7b4 100644 --- a/Editor/TriTypeProcessor.cs +++ b/Editor/TriTypeProcessor.cs @@ -5,10 +5,6 @@ namespace TriInspector { public abstract class TriTypeProcessor { - internal int Order { get; set; } - - public virtual void ProcessType(Type type, List properties) - { - } + public abstract void ProcessType(Type type, List properties); } } \ No newline at end of file diff --git a/Editor/TriTypeProcessor.cs.meta b/Editor/TriTypeProcessor.cs.meta index 0479f51..167fe3b 100644 --- a/Editor/TriTypeProcessor.cs.meta +++ b/Editor/TriTypeProcessor.cs.meta @@ -1,3 +1,11 @@ -fileFormatVersion: 2 +fileFormatVersion: 2 guid: 0a7c26cf735e465d8373066f830cf5c4 -timeCreated: 1660754122 \ No newline at end of file +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/TypeProcessors.meta b/Editor/TypeProcessors.meta index 420706d..55234f8 100644 --- a/Editor/TypeProcessors.meta +++ b/Editor/TypeProcessors.meta @@ -1,3 +1,8 @@ -fileFormatVersion: 2 +fileFormatVersion: 2 guid: 52aec2fc04054420970349733f05237b -timeCreated: 1660755366 \ No newline at end of file +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/TypeProcessors/TriRegisterButtonsTypeProcessor.cs b/Editor/TypeProcessors/TriRegisterButtonsTypeProcessor.cs index 92409bb..9361e6d 100644 --- a/Editor/TypeProcessors/TriRegisterButtonsTypeProcessor.cs +++ b/Editor/TypeProcessors/TriRegisterButtonsTypeProcessor.cs @@ -19,7 +19,7 @@ namespace TriInspector.TypeProcessors properties.AddRange(TriReflectionUtilities .GetAllInstanceMethodsInDeclarationOrder(type) .Where(IsSerialized) - .Select((it, ind) => new TriPropertyDefinition(ind + methodsOffset, it))); + .Select((it, ind) => TriPropertyDefinition.CreateForMethodInfo(ind + methodsOffset, it))); } private static bool IsSerialized(MethodInfo methodInfo) diff --git a/Editor/TypeProcessors/TriRegisterShownByTriPropertiesTypeProcessor.cs b/Editor/TypeProcessors/TriRegisterShownByTriPropertiesTypeProcessor.cs index 823e3ba..6339124 100644 --- a/Editor/TypeProcessors/TriRegisterShownByTriPropertiesTypeProcessor.cs +++ b/Editor/TypeProcessors/TriRegisterShownByTriPropertiesTypeProcessor.cs @@ -19,7 +19,7 @@ namespace TriInspector.TypeProcessors properties.AddRange(TriReflectionUtilities .GetAllInstancePropertiesInDeclarationOrder(type) .Where(IsSerialized) - .Select((it, ind) => new TriPropertyDefinition(ind + propertiesOffset, it))); + .Select((it, ind) => TriPropertyDefinition.CreateForPropertyInfo(ind + propertiesOffset, it))); } private static bool IsSerialized(PropertyInfo propertyInfo) diff --git a/Editor/TypeProcessors/TriRegisterUnitySerializedFieldsTypeProcessor.cs b/Editor/TypeProcessors/TriRegisterUnitySerializedFieldsTypeProcessor.cs index cd391a2..3f70592 100644 --- a/Editor/TypeProcessors/TriRegisterUnitySerializedFieldsTypeProcessor.cs +++ b/Editor/TypeProcessors/TriRegisterUnitySerializedFieldsTypeProcessor.cs @@ -19,7 +19,7 @@ namespace TriInspector.TypeProcessors properties.AddRange(TriReflectionUtilities .GetAllInstanceFieldsInDeclarationOrder(type) .Where(IsSerialized) - .Select((it, ind) => new TriPropertyDefinition(ind + fieldsOffset, it))); + .Select((it, ind) => TriPropertyDefinition.CreateForFieldInfo(ind + fieldsOffset, it))); } private static bool IsSerialized(FieldInfo fieldInfo) diff --git a/Editor/TypeProcessors/TriSortPropertiesTypeProcessor.cs b/Editor/TypeProcessors/TriSortPropertiesTypeProcessor.cs index 15cd998..eb3bcda 100644 --- a/Editor/TypeProcessors/TriSortPropertiesTypeProcessor.cs +++ b/Editor/TypeProcessors/TriSortPropertiesTypeProcessor.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using TriInspector; using TriInspector.TypeProcessors; +using TriInspector.Utilities; [assembly: RegisterTriTypeProcessor(typeof(TriSortPropertiesTypeProcessor), 10000)] @@ -11,6 +12,14 @@ namespace TriInspector.TypeProcessors { public override void ProcessType(Type type, List properties) { + foreach (var propertyDefinition in properties) + { + if (propertyDefinition.Attributes.TryGet(out PropertyOrderAttribute orderAttribute)) + { + propertyDefinition.Order = orderAttribute.Order; + } + } + properties.Sort(PropertyOrderComparer.Instance); }