Remove: depth limit

This commit is contained in:
AnnulusGames 2024-03-04 23:36:38 +09:00
parent ea19961861
commit cd3c0f2a00
17 changed files with 96 additions and 75 deletions

View File

@ -92,7 +92,7 @@ namespace Alchemy.Editor
} }
// Add elements // Add elements
InspectorHelper.BuildElements(serializedObject, root, target, name => serializedObject.FindProperty(name), 0); InspectorHelper.BuildElements(serializedObject, root, target, name => serializedObject.FindProperty(name));
return root; return root;
} }

View File

@ -21,7 +21,7 @@ namespace Alchemy.Editor
var serializedObject = new SerializedObject(this); var serializedObject = new SerializedObject(this);
// Build visual elements and bind serialized object // Build visual elements and bind serialized object
InspectorHelper.BuildElements(serializedObject, windowElement, this, name => serializedObject.FindProperty(name), 0); InspectorHelper.BuildElements(serializedObject, windowElement, this, name => serializedObject.FindProperty(name));
windowElement.Bind(serializedObject); windowElement.Bind(serializedObject);
// Remove "Serialized Data Model Controller" field // Remove "Serialized Data Model Controller" field

View File

@ -11,9 +11,8 @@ namespace Alchemy.Editor.Elements
/// </summary> /// </summary>
public sealed class AlchemyPropertyField : BindableElement public sealed class AlchemyPropertyField : BindableElement
{ {
public AlchemyPropertyField(SerializedProperty property, Type type, int depth, bool isArrayElement = false) public AlchemyPropertyField(SerializedProperty property, Type type, bool isArrayElement = false)
{ {
if (depth > 20) return;
var labelText = ObjectNames.NicifyVariableName(property.displayName); var labelText = ObjectNames.NicifyVariableName(property.displayName);
switch (property.propertyType) switch (property.propertyType)
@ -24,7 +23,7 @@ namespace Alchemy.Editor.Elements
case SerializedPropertyType.ObjectReference: case SerializedPropertyType.ObjectReference:
if (property.GetAttribute<InlineEditorAttribute>() != null) if (property.GetAttribute<InlineEditorAttribute>() != null)
{ {
element = new InlineEditorObjectField(property, type, depth); element = new InlineEditorObjectField(property, type);
} }
else else
{ {
@ -40,14 +39,14 @@ namespace Alchemy.Editor.Elements
} }
else if (property.isArray) else if (property.isArray)
{ {
element = new PropertyListView(property, depth); element = new PropertyListView(property);
} }
else if (targetType.TryGetCustomAttribute<PropertyGroupAttribute>(out var groupAttribute)) // custom group else if (targetType.TryGetCustomAttribute<PropertyGroupAttribute>(out var groupAttribute)) // custom group
{ {
var drawer = AlchemyEditorUtility.CreateGroupDrawer(groupAttribute, targetType); var drawer = AlchemyEditorUtility.CreateGroupDrawer(groupAttribute, targetType);
var root = drawer.CreateRootElement(labelText); var root = drawer.CreateRootElement(labelText);
InspectorHelper.BuildElements(property.serializedObject, root, property.GetValue<object>(), name => property.FindPropertyRelative(name), depth + 1); InspectorHelper.BuildElements(property.serializedObject, root, property.GetValue<object>(), name => property.FindPropertyRelative(name));
if (root is BindableElement bindableElement) bindableElement.BindProperty(property); if (root is BindableElement bindableElement) bindableElement.BindProperty(property);
element = root; element = root;
} }
@ -57,13 +56,13 @@ namespace Alchemy.Editor.Elements
var clickable = InternalAPIHelper.GetClickable(foldout.Q<Toggle>()); var clickable = InternalAPIHelper.GetClickable(foldout.Q<Toggle>());
InternalAPIHelper.SetAcceptClicksIfDisabled(clickable, true); InternalAPIHelper.SetAcceptClicksIfDisabled(clickable, true);
InspectorHelper.BuildElements(property.serializedObject, foldout, property.GetValue<object>(), name => property.FindPropertyRelative(name), depth + 1); InspectorHelper.BuildElements(property.serializedObject, foldout, property.GetValue<object>(), name => property.FindPropertyRelative(name));
foldout.BindProperty(property); foldout.BindProperty(property);
element = foldout; element = foldout;
} }
break; break;
case SerializedPropertyType.ManagedReference: case SerializedPropertyType.ManagedReference:
element = new SerializeReferenceField(property, depth); element = new SerializeReferenceField(property);
break; break;
} }
Add(element); Add(element);

View File

@ -7,11 +7,9 @@ namespace Alchemy.Editor.Elements
{ {
public sealed class ClassField : VisualElement public sealed class ClassField : VisualElement
{ {
public ClassField(Type type, string label, int depth) : this(TypeHelper.CreateDefaultInstance(type), type, label, depth) { } public ClassField(Type type, string label) : this(TypeHelper.CreateDefaultInstance(type), type, label) { }
public ClassField(object obj, Type type, string label, int depth) public ClassField(object obj, Type type, string label)
{ {
if (depth > InspectorHelper.MaxDepth) return;
var foldout = new Foldout var foldout = new Foldout
{ {
text = label, text = label,
@ -46,7 +44,7 @@ namespace Alchemy.Editor.Elements
// Add member elements // Add member elements
foreach (var member in node.Members.OrderByAttributeThenByMemberType()) foreach (var member in node.Members.OrderByAttributeThenByMemberType())
{ {
var element = new ReflectionField(obj, member, depth + 1); var element = new ReflectionField(obj, member);
element.style.width = Length.Percent(100f); element.style.width = Length.Percent(100f);
element.OnValueChanged += x => OnValueChanged?.Invoke(obj); element.OnValueChanged += x => OnValueChanged?.Invoke(obj);

View File

@ -8,7 +8,7 @@ namespace Alchemy.Editor.Elements
{ {
public sealed class DictionaryField : HashMapFieldBase public sealed class DictionaryField : HashMapFieldBase
{ {
public DictionaryField(object collection, string label, int depth) : base(collection, label, depth) public DictionaryField(object collection, string label) : base(collection, label)
{ {
if (collection != null) if (collection != null)
{ {
@ -60,14 +60,14 @@ namespace Alchemy.Editor.Elements
ReflectionHelper.Invoke(Collection, "Clear"); ReflectionHelper.Invoke(Collection, "Clear");
} }
public override HashMapItemBase CreateItem(object collection, object elementObj, string label, int depth) public override HashMapItemBase CreateItem(object collection, object elementObj, string label)
{ {
return new Item(collection, elementObj, depth + 1); return new Item(collection, elementObj);
} }
public sealed class Item : HashMapItemBase public sealed class Item : HashMapItemBase
{ {
public Item(object collection, object keyValuePair, int depth) public Item(object collection, object keyValuePair)
{ {
var box = new Box() var box = new Box()
{ {
@ -97,14 +97,14 @@ namespace Alchemy.Editor.Elements
}; };
box.Add(keyValueElement); box.Add(keyValueElement);
keyField = new GenericField(key, keyType, KeyName, depth) keyField = new GenericField(key, keyType, KeyName)
{ {
style = { flexGrow = 1f } style = { flexGrow = 1f }
}; };
keyField.OnValueChanged += SetKey; keyField.OnValueChanged += SetKey;
keyValueElement.Add(keyField); keyValueElement.Add(keyField);
valueField = new GenericField(value, valueType, ValueName, depth) valueField = new GenericField(value, valueType, ValueName)
{ {
style = { flexGrow = 1f } style = { flexGrow = 1f }
}; };

View File

@ -15,15 +15,14 @@ namespace Alchemy.Editor.Elements
{ {
const string CreateButtonText = "Create..."; const string CreateButtonText = "Create...";
public GenericField(object obj, Type type, string label, int depth, bool isDelayed = false) public GenericField(object obj, Type type, string label,bool isDelayed = false)
{ {
Build(obj, type, label, depth, isDelayed); Build(obj, type, label, isDelayed);
GUIHelper.ScheduleAdjustLabelWidth(this); GUIHelper.ScheduleAdjustLabelWidth(this);
} }
void Build(object obj, Type type, string label, int depth, bool isDelayed) void Build(object obj, Type type, string label, bool isDelayed)
{ {
if (depth > InspectorHelper.MaxDepth) return;
Clear(); Clear();
// Add [Create...] button // Add [Create...] button
@ -53,7 +52,7 @@ namespace Alchemy.Editor.Elements
nullLabelElement.Add(new Button(() => nullLabelElement.Add(new Button(() =>
{ {
var instance = ""; var instance = "";
Build(instance, type, label, depth, isDelayed); Build(instance, type, label, isDelayed);
OnValueChanged?.Invoke(instance); OnValueChanged?.Invoke(instance);
}) })
{ {
@ -65,7 +64,7 @@ namespace Alchemy.Editor.Elements
nullLabelElement.Add(new Button(() => nullLabelElement.Add(new Button(() =>
{ {
var instance = Activator.CreateInstance(type, Activator.CreateInstance(type.GenericTypeArguments[0])); var instance = Activator.CreateInstance(type, Activator.CreateInstance(type.GenericTypeArguments[0]));
Build(instance, type, label, depth, isDelayed); Build(instance, type, label, isDelayed);
OnValueChanged?.Invoke(instance); OnValueChanged?.Invoke(instance);
}) })
{ {
@ -77,7 +76,7 @@ namespace Alchemy.Editor.Elements
nullLabelElement.Add(new Button(() => nullLabelElement.Add(new Button(() =>
{ {
var instance = TypeHelper.CreateDefaultInstance(type); var instance = TypeHelper.CreateDefaultInstance(type);
Build(instance, type, label, depth, isDelayed); Build(instance, type, label, isDelayed);
OnValueChanged?.Invoke(instance); OnValueChanged?.Invoke(instance);
}) })
{ {
@ -228,26 +227,26 @@ namespace Alchemy.Editor.Elements
} }
else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(HashSet<>)) else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(HashSet<>))
{ {
var field = new HashSetField(obj, label, depth + 1); var field = new HashSetField(obj, label);
field.OnValueChanged += x => OnValueChanged?.Invoke(x); field.OnValueChanged += x => OnValueChanged?.Invoke(x);
Add(field); Add(field);
} }
else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>)) else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>))
{ {
var field = new DictionaryField(obj, label, depth + 1); var field = new DictionaryField(obj, label);
field.OnValueChanged += x => OnValueChanged?.Invoke(x); field.OnValueChanged += x => OnValueChanged?.Invoke(x);
Add(field); Add(field);
} }
else if (typeof(IList).IsAssignableFrom(type)) else if (typeof(IList).IsAssignableFrom(type))
{ {
var field = new ListField((IList)obj, label, depth + 1); var field = new ListField((IList)obj, label);
field.OnValueChanged += x => OnValueChanged?.Invoke(x); field.OnValueChanged += x => OnValueChanged?.Invoke(x);
Add(field); Add(field);
} }
else else
{ {
var field = new ClassField(obj, type, label, depth + 1); var field = new ClassField(obj, type, label);
field.OnValueChanged += x => OnValueChanged?.Invoke(x); field.OnValueChanged += x => OnValueChanged?.Invoke(x);
Add(field); Add(field);
} }

View File

@ -8,9 +8,8 @@ namespace Alchemy.Editor.Elements
{ {
public abstract class HashMapFieldBase : VisualElement public abstract class HashMapFieldBase : VisualElement
{ {
public HashMapFieldBase(object collection, string label, int depth) public HashMapFieldBase(object collection, string label)
{ {
this.depth = depth;
this.collection = collection; this.collection = collection;
var foldout = new Foldout() var foldout = new Foldout()
@ -51,7 +50,6 @@ namespace Alchemy.Editor.Elements
public object Collection => collection; public object Collection => collection;
readonly object collection; readonly object collection;
readonly int depth;
bool isInputting; bool isInputting;
@ -75,7 +73,7 @@ namespace Alchemy.Editor.Elements
isInputting = true; isInputting = true;
var initValue = CreateElement(); var initValue = CreateElement();
var form = CreateItem(collection, initValue, "New Value", depth); var form = CreateItem(collection, initValue, "New Value");
inputForm.Clear(); inputForm.Clear();
inputForm.Add(form); inputForm.Add(form);
form.OnValueChanged += ValidateValue; form.OnValueChanged += ValidateValue;
@ -119,7 +117,7 @@ namespace Alchemy.Editor.Elements
var i = 0; var i = 0;
foreach (var item in (IEnumerable)collection) foreach (var item in (IEnumerable)collection)
{ {
var element = CreateItem(collection, item, "Element " + i, depth); var element = CreateItem(collection, item, "Element " + i);
element.OnClose += () => element.OnClose += () =>
{ {
if (isInputting) return; if (isInputting) return;
@ -151,7 +149,7 @@ namespace Alchemy.Editor.Elements
} }
} }
public abstract HashMapItemBase CreateItem(object collection, object elementObj, string label, int depth); public abstract HashMapItemBase CreateItem(object collection, object elementObj, string label);
public abstract bool CheckElement(object element); public abstract bool CheckElement(object element);
public abstract object CreateElement(); public abstract object CreateElement();
public abstract void AddElement(object element); public abstract void AddElement(object element);

View File

@ -6,7 +6,7 @@ namespace Alchemy.Editor.Elements
{ {
public sealed class HashSetField : HashMapFieldBase public sealed class HashSetField : HashMapFieldBase
{ {
public HashSetField(object collection, string label, int depth) : base(collection, label, depth) { } public HashSetField(object collection, string label) : base(collection, label) { }
public override string CollectionTypeName => "HashSet"; public override string CollectionTypeName => "HashSet";
@ -35,14 +35,14 @@ namespace Alchemy.Editor.Elements
ReflectionHelper.Invoke(Collection, "Clear"); ReflectionHelper.Invoke(Collection, "Clear");
} }
public override HashMapItemBase CreateItem(object collection, object elementObj, string label, int depth) public override HashMapItemBase CreateItem(object collection, object elementObj, string label)
{ {
return new Item(collection, elementObj, label, depth); return new Item(collection, elementObj, label);
} }
public sealed class Item : HashMapItemBase public sealed class Item : HashMapItemBase
{ {
public Item(object collection, object elementObj, string label, int depth) public Item(object collection, object elementObj, string label)
{ {
var box = new Box() var box = new Box()
{ {
@ -55,7 +55,7 @@ namespace Alchemy.Editor.Elements
var valueType = elementObj == null ? collection.GetType().GenericTypeArguments[0] : elementObj.GetType(); var valueType = elementObj == null ? collection.GetType().GenericTypeArguments[0] : elementObj.GetType();
inputField = new GenericField(elementObj, valueType, label, depth); inputField = new GenericField(elementObj, valueType, label);
inputField.style.flexGrow = 1f; inputField.style.flexGrow = 1f;
inputField.OnValueChanged += x => inputField.OnValueChanged += x =>
{ {

View File

@ -12,12 +12,10 @@ namespace Alchemy.Editor.Elements
/// </summary> /// </summary>
public sealed class InlineEditorObjectField : BindableElement public sealed class InlineEditorObjectField : BindableElement
{ {
public InlineEditorObjectField(SerializedProperty property, Type type, int depth) public InlineEditorObjectField(SerializedProperty property, Type type)
{ {
Assert.IsTrue(property.propertyType == SerializedPropertyType.ObjectReference); Assert.IsTrue(property.propertyType == SerializedPropertyType.ObjectReference);
this.depth = depth;
style.minHeight = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; style.minHeight = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
foldout = new Foldout() foldout = new Foldout()
@ -55,7 +53,6 @@ namespace Alchemy.Editor.Elements
readonly Foldout foldout; readonly Foldout foldout;
readonly ObjectField field; readonly ObjectField field;
readonly int depth;
bool isNull; bool isNull;
public bool IsObjectNull => isNull; public bool IsObjectNull => isNull;
@ -101,7 +98,7 @@ namespace Alchemy.Editor.Elements
{ {
foldout.Add(new VisualElement() { style = { height = EditorGUIUtility.standardVerticalSpacing } }); foldout.Add(new VisualElement() { style = { height = EditorGUIUtility.standardVerticalSpacing } });
var so = new SerializedObject(property.objectReferenceValue); var so = new SerializedObject(property.objectReferenceValue);
InspectorHelper.BuildElements(so, foldout, so.targetObject, name => so.FindProperty(name), depth); InspectorHelper.BuildElements(so, foldout, so.targetObject, name => so.FindProperty(name));
this.Bind(so); this.Bind(so);
} }
else else

View File

@ -18,7 +18,7 @@ namespace Alchemy.Editor.Elements
const string ItemClassName = "unity-list-view__item"; const string ItemClassName = "unity-list-view__item";
public ListField(IList target, string label, int depth) public ListField(IList target, string label)
{ {
Assert.IsNotNull(target); Assert.IsNotNull(target);
list = target; list = target;
@ -32,7 +32,7 @@ namespace Alchemy.Editor.Elements
var value = list[index]; var value = list[index];
var listType = list.GetType(); var listType = list.GetType();
var valueType = value != null ? value.GetType() : listType.IsGenericType ? listType.GenericTypeArguments[0] : typeof(object); var valueType = value != null ? value.GetType() : listType.IsGenericType ? listType.GenericTypeArguments[0] : typeof(object);
var fieldElement = new GenericField(value, valueType, label, depth); var fieldElement = new GenericField(value, valueType, label);
element.Add(fieldElement); element.Add(fieldElement);
var labelElement = fieldElement.Q<Label>(); var labelElement = fieldElement.Q<Label>();
if (labelElement != null) labelElement.text = "Element " + index; if (labelElement != null) labelElement.text = "Element " + index;

View File

@ -60,7 +60,7 @@ namespace Alchemy.Editor.Elements
var index = i; var index = i;
var parameter = parameters[index]; var parameter = parameters[index];
parameterObjects[index] = TypeHelper.CreateDefaultInstance(parameter.ParameterType); parameterObjects[index] = TypeHelper.CreateDefaultInstance(parameter.ParameterType);
var element = new GenericField(parameterObjects[index], parameter.ParameterType, ObjectNames.NicifyVariableName(parameter.Name), 0); var element = new GenericField(parameterObjects[index], parameter.ParameterType, ObjectNames.NicifyVariableName(parameter.Name));
element.OnValueChanged += x => parameterObjects[index] = x; element.OnValueChanged += x => parameterObjects[index] = x;
element.style.paddingRight = 4f; element.style.paddingRight = 4f;
foldout.Add(element); foldout.Add(element);

View File

@ -12,7 +12,7 @@ namespace Alchemy.Editor.Elements
/// </summary> /// </summary>
public sealed class PropertyListView : BindableElement public sealed class PropertyListView : BindableElement
{ {
public PropertyListView(SerializedProperty property, int depth) public PropertyListView(SerializedProperty property)
{ {
Assert.IsTrue(property.isArray); Assert.IsTrue(property.isArray);
@ -24,7 +24,7 @@ namespace Alchemy.Editor.Elements
listView.bindItem = (element, index) => listView.bindItem = (element, index) =>
{ {
var arrayElement = property.GetArrayElementAtIndex(index); var arrayElement = property.GetArrayElementAtIndex(index);
var e = new AlchemyPropertyField(arrayElement, property.GetPropertyType(true), depth + 1, true); var e = new AlchemyPropertyField(arrayElement, property.GetPropertyType(true), true);
element.Add(e); element.Add(e);
element.Bind(arrayElement.serializedObject); element.Bind(arrayElement.serializedObject);
if (events != null) if (events != null)

View File

@ -9,12 +9,12 @@ namespace Alchemy.Editor.Elements
{ {
public sealed class ReflectionField : VisualElement public sealed class ReflectionField : VisualElement
{ {
public ReflectionField(object target, MemberInfo memberInfo, int depth) public ReflectionField(object target, MemberInfo memberInfo)
{ {
Rebuild(target, memberInfo, depth); Rebuild(target, memberInfo);
} }
public void Rebuild(object target, MemberInfo memberInfo, int depth) public void Rebuild(object target, MemberInfo memberInfo)
{ {
Clear(); Clear();
@ -36,7 +36,7 @@ namespace Alchemy.Editor.Elements
case FieldInfo fieldInfo: case FieldInfo fieldInfo:
value = fieldInfo.IsStatic ? fieldInfo.GetValue(null) : target == null ? TypeHelper.GetDefaultValue(fieldInfo.FieldType) : fieldInfo.GetValue(target); value = fieldInfo.IsStatic ? fieldInfo.GetValue(null) : target == null ? TypeHelper.GetDefaultValue(fieldInfo.FieldType) : fieldInfo.GetValue(target);
var fieldType = target == null ? fieldInfo.FieldType : fieldInfo.GetValue(target)?.GetType() ?? fieldInfo.FieldType; var fieldType = target == null ? fieldInfo.FieldType : fieldInfo.GetValue(target)?.GetType() ?? fieldInfo.FieldType;
element = new GenericField(value, fieldType, ObjectNames.NicifyVariableName(memberInfo.Name), depth, true); element = new GenericField(value, fieldType, ObjectNames.NicifyVariableName(memberInfo.Name), true);
element.OnValueChanged += x => element.OnValueChanged += x =>
{ {
OnBeforeValueChange?.Invoke(target); OnBeforeValueChange?.Invoke(target);
@ -57,7 +57,7 @@ namespace Alchemy.Editor.Elements
value = propertyInfo.GetMethod.IsStatic ? propertyInfo.GetValue(null) : target == null ? TypeHelper.GetDefaultValue(propertyInfo.PropertyType) : propertyInfo.GetValue(target); value = propertyInfo.GetMethod.IsStatic ? propertyInfo.GetValue(null) : target == null ? TypeHelper.GetDefaultValue(propertyInfo.PropertyType) : propertyInfo.GetValue(target);
var propertyType = target == null ? propertyInfo.PropertyType : propertyInfo.GetValue(target)?.GetType() ?? propertyInfo.PropertyType; var propertyType = target == null ? propertyInfo.PropertyType : propertyInfo.GetValue(target)?.GetType() ?? propertyInfo.PropertyType;
element = new GenericField(value, propertyType, ObjectNames.NicifyVariableName(memberInfo.Name), depth, true); element = new GenericField(value, propertyType, ObjectNames.NicifyVariableName(memberInfo.Name), true);
element.OnValueChanged += x => element.OnValueChanged += x =>
{ {
OnBeforeValueChange?.Invoke(target); OnBeforeValueChange?.Invoke(target);

View File

@ -14,7 +14,7 @@ namespace Alchemy.Editor.Elements
/// </summary> /// </summary>
public sealed class SerializeReferenceField : VisualElement public sealed class SerializeReferenceField : VisualElement
{ {
public SerializeReferenceField(SerializedProperty property, int depth) public SerializeReferenceField(SerializedProperty property)
{ {
Assert.IsTrue(property.propertyType == SerializedPropertyType.ManagedReference); Assert.IsTrue(property.propertyType == SerializedPropertyType.ManagedReference);
@ -76,7 +76,7 @@ namespace Alchemy.Editor.Elements
property.serializedObject.ApplyModifiedProperties(); property.serializedObject.ApplyModifiedProperties();
property.serializedObject.Update(); property.serializedObject.Update();
Rebuild(property, depth); Rebuild(property);
}; };
dropdown.Show(position); dropdown.Show(position);
@ -100,7 +100,7 @@ namespace Alchemy.Editor.Elements
buttonContainer.style.right = 0f; buttonContainer.style.right = 0f;
Add(buttonContainer); Add(buttonContainer);
Rebuild(property, depth); Rebuild(property);
} }
public readonly Foldout foldout; public readonly Foldout foldout;
@ -109,7 +109,7 @@ namespace Alchemy.Editor.Elements
/// <summary> /// <summary>
/// Rebuild child elements /// Rebuild child elements
/// </summary> /// </summary>
void Rebuild(SerializedProperty property, int depth) void Rebuild(SerializedProperty property)
{ {
foldout.Clear(); foldout.Clear();
@ -120,7 +120,7 @@ namespace Alchemy.Editor.Elements
} }
else else
{ {
InspectorHelper.BuildElements(property.serializedObject, foldout, property.managedReferenceValue, x => property.FindPropertyRelative(x), depth + 1); InspectorHelper.BuildElements(property.serializedObject, foldout, property.managedReferenceValue, x => property.FindPropertyRelative(x));
} }
this.Bind(property.serializedObject); this.Bind(property.serializedObject);

View File

@ -16,8 +16,6 @@ namespace Alchemy.Editor
{ {
internal static class InspectorHelper internal static class InspectorHelper
{ {
public const int MaxDepth = 15;
public sealed class GroupNode public sealed class GroupNode
{ {
public GroupNode(string name, AlchemyGroupDrawer drawer) public GroupNode(string name, AlchemyGroupDrawer drawer)
@ -74,9 +72,8 @@ namespace Alchemy.Editor
} }
} }
public static void BuildElements(SerializedObject serializedObject, VisualElement rootElement, object target, Func<string, SerializedProperty> findPropertyFunc, int depth) public static void BuildElements(SerializedObject serializedObject, VisualElement rootElement, object target, Func<string, SerializedProperty> findPropertyFunc)
{ {
if (depth >= MaxDepth) return;
if (target == null) return; if (target == null) return;
// Build node // Build node
@ -133,7 +130,7 @@ namespace Alchemy.Editor
} }
else else
{ {
element = CreateMemberElement(serializedObject, target, member, findPropertyFunc, depth + 1); element = CreateMemberElement(serializedObject, target, member, findPropertyFunc);
} }
if (element == null) continue; if (element == null) continue;
@ -197,10 +194,8 @@ namespace Alchemy.Editor
return rootNode; return rootNode;
} }
public static VisualElement CreateMemberElement(SerializedObject serializedObject, object target, MemberInfo memberInfo, Func<string, SerializedProperty> findPropertyFunc, int depth) public static VisualElement CreateMemberElement(SerializedObject serializedObject, object target, MemberInfo memberInfo, Func<string, SerializedProperty> findPropertyFunc)
{ {
if (depth > MaxDepth) return null;
switch (memberInfo) switch (memberInfo)
{ {
case MethodInfo methodInfo: case MethodInfo methodInfo:
@ -224,11 +219,11 @@ namespace Alchemy.Editor
{ {
if (memberInfo is FieldInfo fieldInfo) if (memberInfo is FieldInfo fieldInfo)
{ {
return new AlchemyPropertyField(property, fieldInfo.FieldType, depth); return new AlchemyPropertyField(property, fieldInfo.FieldType);
} }
else else
{ {
return new AlchemyPropertyField(property, ((PropertyInfo)memberInfo).PropertyType, depth); return new AlchemyPropertyField(property, ((PropertyInfo)memberInfo).PropertyType);
} }
} }
} }
@ -246,12 +241,12 @@ namespace Alchemy.Editor
var p = GetProperty(); var p = GetProperty();
if (p != null) if (p != null)
{ {
var field = new ReflectionField(target, fieldInfo, depth); var field = new ReflectionField(target, fieldInfo);
var foldout = field.Q<Foldout>(); var foldout = field.Q<Foldout>();
foldout?.BindProperty(p); foldout?.BindProperty(p);
field.TrackPropertyValue(p, p => field.TrackPropertyValue(p, p =>
{ {
field.Rebuild(target, memberInfo, depth); field.Rebuild(target, memberInfo);
var foldout = field.Q<Foldout>(); var foldout = field.Q<Foldout>();
foldout?.BindProperty(p); foldout?.BindProperty(p);
}); });
@ -279,7 +274,7 @@ namespace Alchemy.Editor
// Create element if member has ShowInInspector attribute // Create element if member has ShowInInspector attribute
if (memberInfo.HasCustomAttribute<ShowInInspectorAttribute>()) if (memberInfo.HasCustomAttribute<ShowInInspectorAttribute>())
{ {
return new ReflectionField(target, memberInfo, depth); return new ReflectionField(target, memberInfo);
} }
break; break;
} }

View File

@ -0,0 +1,24 @@
using System;
using Alchemy.Inspector;
using UnityEngine;
public class DepthTest : MonoBehaviour
{
[Serializable]
[BoxGroup]
public class NodeA
{
[SerializeField] float foo;
[SerializeField] NodeB node;
}
[Serializable]
[BoxGroup]
public class NodeB
{
[SerializeField] float bar;
[SerializeField] NodeA node;
}
public NodeA node;
}

View File

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