Rework TriPropertyDefinition

This commit is contained in:
VladV 2022-08-17 20:46:26 +03:00
parent d601ee062a
commit 3522ac7922
17 changed files with 107 additions and 50 deletions

View File

@ -16,7 +16,9 @@ namespace TriInspector.Drawers
public override TriExtensionInitializationResult Initialize(TriPropertyDefinition propertyDefinition) 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) if (!isValidMethod)
{ {
return "[Button] valid only on methods without parameters"; return "[Button] valid only on methods without parameters";
@ -64,20 +66,21 @@ namespace TriInspector.Drawers
private static void InvokeButton(TriProperty property, object[] parameters) private static void InvokeButton(TriProperty property, object[] parameters)
{ {
var methodInfo = (MethodInfo) property.MemberInfo; if (property.TryGetMemberInfo(out var memberInfo) && memberInfo is MethodInfo methodInfo)
property.ModifyAndRecordForUndo(targetIndex =>
{ {
try property.ModifyAndRecordForUndo(targetIndex =>
{ {
var parentValue = property.Parent.GetValue(targetIndex); try
methodInfo.Invoke(parentValue, parameters); {
} var parentValue = property.Parent.GetValue(targetIndex);
catch (Exception e) methodInfo.Invoke(parentValue, parameters);
{ }
Debug.LogException(e); catch (Exception e)
} {
}); Debug.LogException(e);
}
});
}
} }
} }
} }

View File

@ -1,4 +1,6 @@
using Sirenix.OdinInspector.Editor; using System;
using System.Collections.Generic;
using Sirenix.OdinInspector.Editor;
using Sirenix.Utilities.Editor; using Sirenix.Utilities.Editor;
using UnityEditor; using UnityEditor;
using Object = UnityEngine.Object; using Object = UnityEngine.Object;
@ -27,6 +29,7 @@ namespace TriInspector.Editor.Integrations.Odin
RootPropertyDefinition = new TriPropertyDefinition( RootPropertyDefinition = new TriPropertyDefinition(
memberInfo: odinValueEntry.Property.Info.GetMemberInfo(), memberInfo: odinValueEntry.Property.Info.GetMemberInfo(),
ownerType: odinValueEntry.Property.Info.TypeOfOwner,
order: -1, order: -1,
fieldName: odinValueEntry.Property.Name, fieldName: odinValueEntry.Property.Name,
fieldType: odinValueEntry.TypeOfValue, fieldType: odinValueEntry.TypeOfValue,
@ -36,6 +39,7 @@ namespace TriInspector.Editor.Integrations.Odin
_odinValueEntry.Values[targetIndex] = (T) value; _odinValueEntry.Values[targetIndex] = (T) value;
return null; return null;
}, },
attributes: new List<Attribute>(),
isArrayElement: false isArrayElement: false
); );
RootProperty = new TriProperty(this, null, RootPropertyDefinition, -1, _serializedProperty); RootProperty = new TriProperty(this, null, RootPropertyDefinition, -1, _serializedProperty);

View File

@ -11,7 +11,7 @@ namespace TriInspector.Resolvers
public static bool TryResolve(TriPropertyDefinition propertyDefinition, string method, public static bool TryResolve(TriPropertyDefinition propertyDefinition, string method,
out ActionResolver resolver) out ActionResolver resolver)
{ {
var parentType = propertyDefinition.MemberInfo.DeclaringType; var parentType = propertyDefinition.OwnerType;
if (parentType == null) if (parentType == null)
{ {
resolver = null; resolver = null;

View File

@ -11,7 +11,7 @@ namespace TriInspector.Resolvers
public static bool TryResolve(TriPropertyDefinition propertyDefinition, string expression, public static bool TryResolve(TriPropertyDefinition propertyDefinition, string expression,
out ValueResolver<T> resolver) out ValueResolver<T> resolver)
{ {
var parentType = propertyDefinition.MemberInfo.DeclaringType; var parentType = propertyDefinition.OwnerType;
if (parentType == null) if (parentType == null)
{ {
resolver = null; resolver = null;

View File

@ -11,7 +11,7 @@ namespace TriInspector.Resolvers
public static bool TryResolve(TriPropertyDefinition propertyDefinition, string expression, public static bool TryResolve(TriPropertyDefinition propertyDefinition, string expression,
out ValueResolver<T> resolver) out ValueResolver<T> resolver)
{ {
var parentType = propertyDefinition.MemberInfo.DeclaringType; var parentType = propertyDefinition.OwnerType;
if (parentType == null) if (parentType == null)
{ {
resolver = null; resolver = null;

View File

@ -11,7 +11,7 @@ namespace TriInspector.Resolvers
public static bool TryResolve(TriPropertyDefinition propertyDefinition, string expression, public static bool TryResolve(TriPropertyDefinition propertyDefinition, string expression,
out ValueResolver<T> resolver) out ValueResolver<T> resolver)
{ {
var parentType = propertyDefinition.MemberInfo.DeclaringType; var parentType = propertyDefinition.OwnerType;
if (parentType == null) if (parentType == null)
{ {
resolver = null; resolver = null;

View File

@ -169,9 +169,6 @@ namespace TriInspector
} }
} }
[PublicAPI]
public MemberInfo MemberInfo => _definition.MemberInfo;
[PublicAPI] [PublicAPI]
public Type FieldType => _definition.FieldType; public Type FieldType => _definition.FieldType;
@ -209,7 +206,7 @@ namespace TriInspector
if (_isExpandedPrefsKey == null) if (_isExpandedPrefsKey == null)
{ {
_isExpandedPrefsKey = $"TriInspector.expanded.{PropertyTree.TargetObjectType}.{MemberInfo}"; _isExpandedPrefsKey = $"TriInspector.expanded.{PropertyTree.TargetObjectType}.{RawName}";
} }
return EditorPrefs.GetBool(_isExpandedPrefsKey, false); 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) public object GetValue(int targetIndex)
{ {
return _definition.GetValue(this, targetIndex); return _definition.GetValue(this, targetIndex);

View File

@ -16,6 +16,8 @@ namespace TriInspector
[CanBeNull] private readonly ValueSetterDelegate _valueSetter; [CanBeNull] private readonly ValueSetterDelegate _valueSetter;
private readonly List<string> _extensionErrors = new List<string>(); private readonly List<string> _extensionErrors = new List<string>();
private readonly MemberInfo _memberInfo;
private readonly List<Attribute> _attributes;
private TriPropertyDefinition _arrayElementDefinitionBackingField; private TriPropertyDefinition _arrayElementDefinitionBackingField;
@ -24,40 +26,54 @@ namespace TriInspector
private IReadOnlyList<TriPropertyHideProcessor> _hideProcessorsBackingField; private IReadOnlyList<TriPropertyHideProcessor> _hideProcessorsBackingField;
private IReadOnlyList<TriPropertyDisableProcessor> _disableProcessorsBackingField; private IReadOnlyList<TriPropertyDisableProcessor> _disableProcessorsBackingField;
internal TriPropertyDefinition(int order, FieldInfo fi) public static TriPropertyDefinition CreateForFieldInfo(int order, FieldInfo fi)
: this(fi, order, fi.Name, fi.FieldType, MakeGetter(fi), MakeSetter(fi), false)
{ {
return CreateForMemberInfo(fi, order, fi.Name, fi.FieldType, MakeGetter(fi), MakeSetter(fi));
} }
internal TriPropertyDefinition(int order, PropertyInfo pi) public static TriPropertyDefinition CreateForPropertyInfo(int order, PropertyInfo pi)
: this(pi, order, pi.Name, pi.PropertyType, MakeGetter(pi), MakeSetter(pi), false)
{ {
return CreateForMemberInfo(pi, order, pi.Name, pi.PropertyType, MakeGetter(pi), MakeSetter(pi));
} }
internal TriPropertyDefinition(int order, MethodInfo mi) public static TriPropertyDefinition CreateForMethodInfo(int order, MethodInfo mi)
: this(mi, order, mi.Name, typeof(MethodInfo), MakeGetter(mi), MakeSetter(mi), false)
{ {
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( internal TriPropertyDefinition(
MemberInfo memberInfo, MemberInfo memberInfo,
Type ownerType,
int order, int order,
string fieldName, string fieldName,
Type fieldType, Type fieldType,
ValueGetterDelegate valueGetter, ValueGetterDelegate valueGetter,
ValueSetterDelegate valueSetter, ValueSetterDelegate valueSetter,
List<Attribute> attributes,
bool isArrayElement) bool isArrayElement)
{ {
MemberInfo = memberInfo; OwnerType = ownerType;
Name = fieldName; Name = fieldName;
FieldType = fieldType; FieldType = fieldType;
IsArrayElement = isArrayElement; IsArrayElement = isArrayElement;
_attributes = attributes ?? new List<Attribute>();
_memberInfo = memberInfo;
_valueGetter = valueGetter; _valueGetter = valueGetter;
_valueSetter = valueSetter; _valueSetter = valueSetter;
Attributes = memberInfo?.GetCustomAttributes().ToList() ?? new List<Attribute>(); Order = order;
Order = Attributes.TryGet(out PropertyOrderAttribute orderAttribute) ? orderAttribute.Order : order;
IsReadOnly = _valueSetter == null || Attributes.TryGet(out ReadOnlyAttribute _); IsReadOnly = _valueSetter == null || Attributes.TryGet(out ReadOnlyAttribute _);
if (TriReflectionUtilities.IsArrayOrList(FieldType, out var elementType)) 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 Type FieldType { get; }
public string Name { get; } public string Name { get; }
public int Order { get; } public int Order { get; internal set; }
public IReadOnlyList<Attribute> Attributes { get; } public IReadOnlyList<Attribute> Attributes => _attributes;
public bool IsReadOnly { get; } public bool IsReadOnly { get; }
@ -114,6 +130,17 @@ namespace TriInspector
} }
} }
public List<Attribute> GetEditableAttributes()
{
return _attributes;
}
public bool TryGetMemberInfo(out MemberInfo memberInfo)
{
memberInfo = _memberInfo;
return memberInfo != null;
}
public object GetValue(TriProperty property, int targetIndex) public object GetValue(TriProperty property, int targetIndex)
{ {
return _valueGetter(property, targetIndex); return _valueGetter(property, targetIndex);
@ -144,7 +171,6 @@ namespace TriInspector
$"Cannot get array element definition for non array property: {FieldType}"); $"Cannot get array element definition for non array property: {FieldType}");
} }
var elementMember = MemberInfo;
var elementGetter = new ValueGetterDelegate((self, targetIndex) => var elementGetter = new ValueGetterDelegate((self, targetIndex) =>
{ {
var parentValue = (IList) self.Parent.GetValue(targetIndex); var parentValue = (IList) self.Parent.GetValue(targetIndex);
@ -157,8 +183,8 @@ namespace TriInspector
return parentValue; return parentValue;
}); });
_arrayElementDefinitionBackingField = new TriPropertyDefinition(elementMember, 0, "Element", _arrayElementDefinitionBackingField = new TriPropertyDefinition(_memberInfo, OwnerType, 0,
ArrayElementType, elementGetter, elementSetter, true); "Element", ArrayElementType, elementGetter, elementSetter, _attributes, true);
} }
return _arrayElementDefinitionBackingField; return _arrayElementDefinitionBackingField;

View File

@ -56,7 +56,7 @@ namespace TriInspector
{ {
_rootPropertyElement = new TriPropertyElement(RootProperty, new TriPropertyElement.Props _rootPropertyElement = new TriPropertyElement(RootProperty, new TriPropertyElement.Props
{ {
forceInline = RootProperty.MemberInfo == null, forceInline = !RootProperty.TryGetMemberInfo(out _),
}); });
_rootPropertyElement.AttachInternal(); _rootPropertyElement.AttachInternal();
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using JetBrains.Annotations; using JetBrains.Annotations;
using UnityEditor; using UnityEditor;
@ -19,11 +20,13 @@ namespace TriInspector
RootPropertyDefinition = new TriPropertyDefinition( RootPropertyDefinition = new TriPropertyDefinition(
memberInfo: null, memberInfo: null,
ownerType: null,
order: -1, order: -1,
fieldName: "ROOT", fieldName: "ROOT",
fieldType: TargetObjectType, fieldType: TargetObjectType,
valueGetter: (self, targetIndex) => _serializedObject.targetObjects[targetIndex], valueGetter: (self, targetIndex) => _serializedObject.targetObjects[targetIndex],
valueSetter: (self, targetIndex, value) => _serializedObject.targetObjects[targetIndex], valueSetter: (self, targetIndex, value) => _serializedObject.targetObjects[targetIndex],
attributes: new List<Attribute>(),
isArrayElement: false); isArrayElement: false);
RootProperty = new TriProperty(this, null, RootPropertyDefinition, serializedObject); RootProperty = new TriProperty(this, null, RootPropertyDefinition, serializedObject);

View File

@ -5,10 +5,6 @@ namespace TriInspector
{ {
public abstract class TriTypeProcessor public abstract class TriTypeProcessor
{ {
internal int Order { get; set; } public abstract void ProcessType(Type type, List<TriPropertyDefinition> properties);
public virtual void ProcessType(Type type, List<TriPropertyDefinition> properties)
{
}
} }
} }

View File

@ -1,3 +1,11 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 0a7c26cf735e465d8373066f830cf5c4 guid: 0a7c26cf735e465d8373066f830cf5c4
timeCreated: 1660754122 MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,3 +1,8 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 52aec2fc04054420970349733f05237b guid: 52aec2fc04054420970349733f05237b
timeCreated: 1660755366 folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -19,7 +19,7 @@ namespace TriInspector.TypeProcessors
properties.AddRange(TriReflectionUtilities properties.AddRange(TriReflectionUtilities
.GetAllInstanceMethodsInDeclarationOrder(type) .GetAllInstanceMethodsInDeclarationOrder(type)
.Where(IsSerialized) .Where(IsSerialized)
.Select((it, ind) => new TriPropertyDefinition(ind + methodsOffset, it))); .Select((it, ind) => TriPropertyDefinition.CreateForMethodInfo(ind + methodsOffset, it)));
} }
private static bool IsSerialized(MethodInfo methodInfo) private static bool IsSerialized(MethodInfo methodInfo)

View File

@ -19,7 +19,7 @@ namespace TriInspector.TypeProcessors
properties.AddRange(TriReflectionUtilities properties.AddRange(TriReflectionUtilities
.GetAllInstancePropertiesInDeclarationOrder(type) .GetAllInstancePropertiesInDeclarationOrder(type)
.Where(IsSerialized) .Where(IsSerialized)
.Select((it, ind) => new TriPropertyDefinition(ind + propertiesOffset, it))); .Select((it, ind) => TriPropertyDefinition.CreateForPropertyInfo(ind + propertiesOffset, it)));
} }
private static bool IsSerialized(PropertyInfo propertyInfo) private static bool IsSerialized(PropertyInfo propertyInfo)

View File

@ -19,7 +19,7 @@ namespace TriInspector.TypeProcessors
properties.AddRange(TriReflectionUtilities properties.AddRange(TriReflectionUtilities
.GetAllInstanceFieldsInDeclarationOrder(type) .GetAllInstanceFieldsInDeclarationOrder(type)
.Where(IsSerialized) .Where(IsSerialized)
.Select((it, ind) => new TriPropertyDefinition(ind + fieldsOffset, it))); .Select((it, ind) => TriPropertyDefinition.CreateForFieldInfo(ind + fieldsOffset, it)));
} }
private static bool IsSerialized(FieldInfo fieldInfo) private static bool IsSerialized(FieldInfo fieldInfo)

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using TriInspector; using TriInspector;
using TriInspector.TypeProcessors; using TriInspector.TypeProcessors;
using TriInspector.Utilities;
[assembly: RegisterTriTypeProcessor(typeof(TriSortPropertiesTypeProcessor), 10000)] [assembly: RegisterTriTypeProcessor(typeof(TriSortPropertiesTypeProcessor), 10000)]
@ -11,6 +12,14 @@ namespace TriInspector.TypeProcessors
{ {
public override void ProcessType(Type type, List<TriPropertyDefinition> properties) public override void ProcessType(Type type, List<TriPropertyDefinition> properties)
{ {
foreach (var propertyDefinition in properties)
{
if (propertyDefinition.Attributes.TryGet(out PropertyOrderAttribute orderAttribute))
{
propertyDefinition.Order = orderAttribute.Order;
}
}
properties.Sort(PropertyOrderComparer.Instance); properties.Sort(PropertyOrderComparer.Instance);
} }