Update RuntimeComponentsDrawer.cs

This commit is contained in:
DCFApixels 2025-05-14 20:26:17 +08:00
parent 6d0a572c80
commit 64bc896457

View File

@ -16,7 +16,8 @@ namespace DCFApixels.DragonECS.Unity.Editors.X
using static RuntimeComponentsDrawer.RuntimeComponentReflectionCache; using static RuntimeComponentsDrawer.RuntimeComponentReflectionCache;
internal class RuntimeComponentsDrawer internal class RuntimeComponentsDrawer
{ {
private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private const BindingFlags INSTANCE_FIELD_FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void ResetRuntimeComponentReflectionCache() private static void ResetRuntimeComponentReflectionCache()
{ {
@ -160,7 +161,7 @@ namespace DCFApixels.DragonECS.Unity.Editors.X
if (Drawer == DrawerType.UnityNotSerializableComposite) if (Drawer == DrawerType.UnityNotSerializableComposite)
{ {
var fieldInfos = type.GetFields(fieldFlags); var fieldInfos = type.GetFields(INSTANCE_FIELD_FLAGS);
Fields = new FieldInfoData[fieldInfos.Length]; Fields = new FieldInfoData[fieldInfos.Length];
for (int i = 0; i < fieldInfos.Length; i++) for (int i = 0; i < fieldInfos.Length; i++)
{ {
@ -451,272 +452,273 @@ namespace DCFApixels.DragonECS.Unity.Editors.X
#region draw data #region draw data
private bool DrawRuntimeData(ref RuntimeComponentReflectionCache.FieldInfoData fieldInfoData, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData, int depth) private bool DrawRuntimeData(ref RuntimeComponentReflectionCache.FieldInfoData fieldInfoData, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData, int depth)
{ {
const int DEPTH_MAX = 16; const int DEPTH_MAX = 24;
EditorGUI.BeginChangeCheck(); using (EcsGUI.CheckChanged())
outData = data;
object newData = data;
Type type = data == null ? typeof(void) : data.GetType();
RuntimeComponentReflectionCache cache = fieldInfoData.GetReflectionCache(type);
bool isUnityObjectField = fieldInfoData.IsUnityObjectField;
if (isUnityObjectField == false && data == null)
{ {
EditorGUILayout.TextField(label, "Null");
return false;
}
if (depth >= DEPTH_MAX || cache == null)
{
EditorGUILayout.TextField(label, "error");
return false;
}
ref bool isExpanded = ref expandMatrix.Down(); outData = data;
bool childElementChanged = false; object newData = data;
var eventType = Event.current.type; Type type = data == null ? typeof(void) : data.GetType();
bool isUnityObjectField = fieldInfoData.IsUnityObjectField;
if (isUnityObjectField == false && data == null)
{
EditorGUILayout.TextField(label, "Null");
return false;
}
var label2 = UnityEditorUtility.GetLabel2(cache.Type.FullName + " " + type.FullName); RuntimeComponentReflectionCache cache = fieldInfoData.GetReflectionCache(type);
var drawer = cache.Drawer; if (depth >= DEPTH_MAX || cache == null)
{
EditorGUILayout.TextField(label, "error");
return false;
}
if (isUnityObjectField) ref bool isExpanded = ref expandMatrix.Down();
{ bool childElementChanged = false;
drawer = DrawerType.UnityObject; var eventType = Event.current.type;
}
switch (drawer)
{
case DrawerType.UNDEFINED:
EditorGUILayout.LabelField(label, label2);
break;
case DrawerType.Ignored:
EditorGUILayout.LabelField(label, label2);
break;
case DrawerType.UnitySerializableComposite:
using (EcsGUI.CheckChanged()) var label2 = UnityEditorUtility.GetLabel2(cache.Type.FullName + " " + type.FullName);
{ var drawer = cache.Drawer;
RefEditorWrapper wrapper = cache.GetWrapper(_runtimeComponentsDepth);
wrapper.data = data;
wrapper.SO.Update();
wrapper.IsExpanded = isExpanded;
EditorGUILayout.PropertyField(wrapper.Property, label, true);
if (EcsGUI.Changed) if (isUnityObjectField)
{
drawer = DrawerType.UnityObject;
}
switch (drawer)
{
case DrawerType.UNDEFINED:
EditorGUILayout.LabelField(label, label2);
break;
case DrawerType.Ignored:
EditorGUILayout.LabelField(label, label2);
break;
case DrawerType.UnitySerializableComposite:
using (EcsGUI.CheckChanged())
{ {
wrapper.SO.ApplyModifiedProperties(); RefEditorWrapper wrapper = cache.GetWrapper(_runtimeComponentsDepth);
newData = wrapper.Data; wrapper.data = data;
childElementChanged = true; wrapper.SO.Update();
} wrapper.IsExpanded = isExpanded;
isExpanded = wrapper.IsExpanded; EditorGUILayout.PropertyField(wrapper.Property, label, true);
}
break; if (EcsGUI.Changed)
case DrawerType.UnityNotSerializableComposite:
GUILayout.Space(EcsGUI.Spacing);
var foldoutStyle = EditorStyles.foldout;
Rect rect = GUILayoutUtility.GetRect(label, foldoutStyle);
//rect.xMin += EcsGUI.Indent;
isExpanded = EditorGUI.BeginFoldoutHeaderGroup(rect, isExpanded, label, foldoutStyle, null, null);
EditorGUILayout.EndFoldoutHeaderGroup();
if (isExpanded)
{
using (EcsGUI.UpIndentLevel())
{
for (int j = 0, jMax = cache.Fields.Length; j < jMax; j++)
{ {
var field = cache.Fields[j]; wrapper.SO.ApplyModifiedProperties();
if (DrawRuntimeData(ref field, UnityEditorUtility.GetLabel(field.UnityFormatName), expandMatrix, field.FieldInfo.GetValue(data), out object fieldData, depth + 1)) newData = wrapper.Data;
childElementChanged = true;
}
isExpanded = wrapper.IsExpanded;
}
break;
case DrawerType.UnityNotSerializableComposite:
GUILayout.Space(EcsGUI.Spacing);
var foldoutStyle = EditorStyles.foldout;
Rect rect = GUILayoutUtility.GetRect(label, foldoutStyle);
//rect.xMin += EcsGUI.Indent;
isExpanded = EditorGUI.BeginFoldoutHeaderGroup(rect, isExpanded, label, foldoutStyle, null, null);
EditorGUILayout.EndFoldoutHeaderGroup();
if (isExpanded)
{
using (EcsGUI.UpIndentLevel())
{
for (int j = 0, jMax = cache.Fields.Length; j < jMax; j++)
{ {
field.FieldInfo.SetValue(data, fieldData); var field = cache.Fields[j];
newData = data; if (DrawRuntimeData(ref field, UnityEditorUtility.GetLabel(field.UnityFormatName), expandMatrix, field.FieldInfo.GetValue(data), out object fieldData, depth + 1))
childElementChanged = true; {
field.FieldInfo.SetValue(data, fieldData);
newData = data;
childElementChanged = true;
}
} }
} }
} }
}
break; break;
case DrawerType.UnityObject: case DrawerType.UnityObject:
using (EcsGUI.CheckChanged()) using (EcsGUI.CheckChanged())
{
var uobj = UnsafeUtility.As<object, UnityObject>(ref data);
bool isComponent = typeof(UnityComponent).IsAssignableFrom(fieldInfoData.FieldType);
var newuobj = EditorGUILayout.ObjectField(label, uobj, fieldInfoData.FieldType, true);
if (uobj != newuobj)
{ {
if (isComponent && newuobj is GameObject go) var uobj = UnsafeUtility.As<object, UnityObject>(ref data);
bool isComponent = typeof(UnityComponent).IsAssignableFrom(fieldInfoData.FieldType);
var newuobj = EditorGUILayout.ObjectField(label, uobj, fieldInfoData.FieldType, true);
if (uobj != newuobj)
{ {
newuobj = go.GetComponent(fieldInfoData.FieldType); if (isComponent && newuobj is GameObject go)
{
newuobj = go.GetComponent(fieldInfoData.FieldType);
}
newData = newuobj;
childElementChanged = true;
} }
newData = newuobj;
childElementChanged = true;
} }
}
break; break;
case DrawerType.Enum: case DrawerType.Enum:
if (eventType != EventType.Layout) if (eventType != EventType.Layout)
{ {
var enumData = UnsafeUtility.As<object, Enum>(ref data); var enumData = UnsafeUtility.As<object, Enum>(ref data);
newData = EditorGUILayout.EnumPopup(label, enumData); newData = EditorGUILayout.EnumPopup(label, enumData);
} }
else else
{ {
EditorGUILayout.EnumPopup(label, default); EditorGUILayout.EnumPopup(label, default);
} }
break; break;
case DrawerType.EnumFlags: case DrawerType.EnumFlags:
if (eventType != EventType.Layout) if (eventType != EventType.Layout)
{ {
var enumData = UnsafeUtility.As<object, Enum>(ref data); var enumData = UnsafeUtility.As<object, Enum>(ref data);
newData = EditorGUILayout.EnumFlagsField(label, enumData); newData = EditorGUILayout.EnumFlagsField(label, enumData);
} }
else else
{ {
EditorGUILayout.EnumFlagsField(label, default); EditorGUILayout.EnumFlagsField(label, default);
} }
break; break;
case DrawerType.Bool: case DrawerType.Bool:
if (eventType != EventType.Layout) if (eventType != EventType.Layout)
{ {
newData = EditorGUILayout.Toggle(label, (bool)data); newData = EditorGUILayout.Toggle(label, (bool)data);
} }
else else
{ {
EditorGUILayout.Toggle(label, default); EditorGUILayout.Toggle(label, default);
} }
break; break;
case DrawerType.String: case DrawerType.String:
if (eventType != EventType.Layout) if (eventType != EventType.Layout)
{ {
newData = EditorGUILayout.TextField(label, (string)data); newData = EditorGUILayout.TextField(label, (string)data);
} }
else else
{ {
EditorGUILayout.TextField(label, default); EditorGUILayout.TextField(label, default);
} }
break; break;
case DrawerType.Float: case DrawerType.Float:
if (eventType != EventType.Layout) if (eventType != EventType.Layout)
{ {
newData = EditorGUILayout.FloatField(label, (float)data); newData = EditorGUILayout.FloatField(label, (float)data);
} }
else else
{ {
EditorGUILayout.FloatField(label, default); EditorGUILayout.FloatField(label, default);
} }
break; break;
case DrawerType.Double: case DrawerType.Double:
if (eventType != EventType.Layout) if (eventType != EventType.Layout)
{ {
newData = EditorGUILayout.DoubleField(label, (double)data); newData = EditorGUILayout.DoubleField(label, (double)data);
} }
else else
{ {
EditorGUILayout.DoubleField(label, default); EditorGUILayout.DoubleField(label, default);
} }
break; break;
case DrawerType.Byte: case DrawerType.Byte:
if (eventType != EventType.Layout) if (eventType != EventType.Layout)
{ {
newData = (byte)EditorGUILayout.IntField(label, (byte)data); newData = (byte)EditorGUILayout.IntField(label, (byte)data);
} }
else else
{ {
EditorGUILayout.IntField(label, default); EditorGUILayout.IntField(label, default);
} }
break; break;
case DrawerType.SByte: case DrawerType.SByte:
if (eventType != EventType.Layout) if (eventType != EventType.Layout)
{ {
newData = (sbyte)EditorGUILayout.IntField(label, (sbyte)data); newData = (sbyte)EditorGUILayout.IntField(label, (sbyte)data);
} }
else else
{ {
EditorGUILayout.IntField(label, default); EditorGUILayout.IntField(label, default);
} }
break; break;
case DrawerType.Short: case DrawerType.Short:
if (eventType != EventType.Layout) if (eventType != EventType.Layout)
{ {
newData = (short)EditorGUILayout.IntField(label, (short)data); newData = (short)EditorGUILayout.IntField(label, (short)data);
} }
else else
{ {
EditorGUILayout.IntField(label, default); EditorGUILayout.IntField(label, default);
} }
break; break;
case DrawerType.UShort: case DrawerType.UShort:
if (eventType != EventType.Layout) if (eventType != EventType.Layout)
{ {
newData = (ushort)EditorGUILayout.IntField(label, (ushort)data); newData = (ushort)EditorGUILayout.IntField(label, (ushort)data);
} }
else else
{ {
EditorGUILayout.IntField(label, default); EditorGUILayout.IntField(label, default);
} }
break; break;
case DrawerType.Int: case DrawerType.Int:
if (eventType != EventType.Layout) if (eventType != EventType.Layout)
{ {
newData = (int)EditorGUILayout.IntField(label, (int)data); newData = (int)EditorGUILayout.IntField(label, (int)data);
} }
else else
{ {
EditorGUILayout.IntField(label, default); EditorGUILayout.IntField(label, default);
} }
break; break;
case DrawerType.UInt: case DrawerType.UInt:
if (eventType != EventType.Layout) if (eventType != EventType.Layout)
{ {
newData = (uint)EditorGUILayout.IntField(label, (int)(uint)data); newData = (uint)EditorGUILayout.IntField(label, (int)(uint)data);
} }
else else
{ {
EditorGUILayout.IntField(label, default); EditorGUILayout.IntField(label, default);
} }
break; break;
case DrawerType.Long: case DrawerType.Long:
if (eventType != EventType.Layout) if (eventType != EventType.Layout)
{ {
newData = EditorGUILayout.LongField(label, (long)data); newData = EditorGUILayout.LongField(label, (long)data);
} }
else else
{ {
EditorGUILayout.LongField(label, default); EditorGUILayout.LongField(label, default);
} }
break; break;
case DrawerType.ULong: case DrawerType.ULong:
if (eventType != EventType.Layout) if (eventType != EventType.Layout)
{ {
newData = (ulong)EditorGUILayout.LongField(label, (long)(ulong)data); newData = (ulong)EditorGUILayout.LongField(label, (long)(ulong)data);
} }
else else
{ {
EditorGUILayout.LongField(label, default); EditorGUILayout.LongField(label, default);
} }
break; break;
default: default:
EditorGUILayout.LabelField(label, label2); EditorGUILayout.LabelField(label, label2);
break; break;
}
expandMatrix.Up();
if (childElementChanged || EcsGUI.Changed)
{
outData = newData;
return true;
}
} }
expandMatrix.Up();
if (childElementChanged || EditorGUI.EndChangeCheck())
{
outData = newData;
return true;
}
return false; return false;
} }
#endregion #endregion