This commit is contained in:
Mikhail 2026-03-02 14:55:10 +08:00
parent c08c7ab50f
commit dc0aae1c67
5 changed files with 145 additions and 16 deletions

View File

@ -855,6 +855,21 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
return result; return result;
} }
internal static bool HasSerializableData(this SerializedProperty property)
{
var propsCounter = property.Copy();
int lastDepth = propsCounter.depth;
bool next = propsCounter.Next(true) && lastDepth < propsCounter.depth;
while (next)
{
if(propsCounter.propertyType != SerializedPropertyType.Generic)
{
return true;
}
next = propsCounter.Next(true) && lastDepth < propsCounter.depth;
}
return false;
}
#endregion #endregion
#region SelectPanelColor #region SelectPanelColor

View File

@ -222,20 +222,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
protected virtual void OnStaticInit() { } protected virtual void OnStaticInit() { }
protected virtual void OnInit() { } protected virtual void OnInit() { }
//private Stopwatch _stopwatch = new Stopwatch();
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{ {
//_stopwatch.Restart();
using (EcsGUI.CheckChanged(property.serializedObject)) using (EcsGUI.CheckChanged(property.serializedObject))
{ {
StaticInit(); StaticInit();
Init(); Init();
DrawCustom(position, property, label); DrawCustom(position, property, label);
} }
//_stopwatch.Stop();
//var result = _stopwatch.Elapsed;
//UnityEngine.Debug.Log($"{result.Minutes}:{result.Seconds}:{result.Milliseconds}");
} }
protected abstract void DrawCustom(Rect position, SerializedProperty property, GUIContent label); protected abstract void DrawCustom(Rect position, SerializedProperty property, GUIContent label);
} }

View File

@ -99,7 +99,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
else else
{ {
meta = dummy.Type.GetMeta(); meta = dummy.Type.ToMeta();
} }
return (dummy, meta); return (dummy, meta);
}); });

View File

@ -10,6 +10,26 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
#if UNITY_EDITOR #if UNITY_EDITOR
namespace DCFApixels.DragonECS.Unity.Internal
{
using DCFApixels.DragonECS.Unity.Editors;
using UnityEditor;
internal partial class UnityReflectionCache
{
public bool IsReferenceButtonCacheInit_Editor;
public bool InitReferenceButtonCache_Editor(SerializedProperty sp)
{
if (IsReferenceButtonCacheInit_Editor) { return false; }
HasSerializableData_Editor = sp.HasSerializableData();
IsReferenceButtonCacheInit_Editor = true;
return true;
}
public bool HasSerializableData_Editor;
}
}
namespace DCFApixels.DragonECS.Unity.Editors namespace DCFApixels.DragonECS.Unity.Editors
{ {
using DCFApixels.DragonECS.Unity.Internal; using DCFApixels.DragonECS.Unity.Internal;
@ -26,19 +46,30 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
Type fieldType = fieldInfo.FieldType; Type fieldType = fieldInfo.FieldType;
_withOutTypes = fieldType.TryGetAttribute(out ReferenceButtonWithOutAttribute a) ? a.PredicateTypes : Array.Empty<Type>(); _withOutTypes = fieldType.TryGetAttribute(out ReferenceButtonWithOutAttribute a) ? a.PredicateTypes : Array.Empty<Type>();
if (fieldType.IsGenericType) //if (fieldType.IsGenericType)
//{
// if (fieldType.IsGenericTypeDefinition == false)
// {
// fieldType = fieldType.GetGenericTypeDefinition();
// }
//}
}
private UnityReflectionCache _reflectionCache;
private UnityReflectionCache Cahce(SerializedProperty sp)
{
if (UnityReflectionCache.InitLocal(sp.managedReferenceValue.GetType(), ref _reflectionCache))
{ {
if (fieldType.IsGenericTypeDefinition == false) _reflectionCache.InitReferenceButtonCache_Editor(sp);
{
fieldType = fieldType.GetGenericTypeDefinition();
}
} }
return _reflectionCache;
} }
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{ {
Init(); Init();
if (property.managedReferenceValue != null) if (property.managedReferenceValue != null &&
Cahce(property).HasSerializableData_Editor)
{ {
return EditorGUI.GetPropertyHeight(property, label, true); return EditorGUI.GetPropertyHeight(property, label, true);
} }
@ -58,7 +89,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
selButtnoRect.height = OneLineHeight; selButtnoRect.height = OneLineHeight;
DrawSelectionPopupButton(selButtnoRect, property); DrawSelectionPopupButton(selButtnoRect, property);
if (property.managedReferenceValue != null) if (property.managedReferenceValue != null &&
Cahce(property).HasSerializableData_Editor)
{ {
EditorGUI.PropertyField(position, property, label, true); EditorGUI.PropertyField(position, property, label, true);
} }

View File

@ -1,7 +1,9 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using System; using System;
using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using UnityEngine;
using UnityObject = UnityEngine.Object; using UnityObject = UnityEngine.Object;
namespace DCFApixels.DragonECS.Unity.Internal namespace DCFApixels.DragonECS.Unity.Internal
@ -33,20 +35,106 @@ namespace DCFApixels.DragonECS.Unity.Internal
{ {
return self.IsSubclassOf(typeof(UnityObject)); return self.IsSubclassOf(typeof(UnityObject));
} }
public static bool HasUnitySerializableFields(this Type self)
{
var fields = self.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (fields.Length <= 0)
{
return false;
}
foreach (var field in fields)
{
if (field.IsUnitySerializableField() &&
(field.FieldType.IsUnitySerializableLeafType() ||
HasUnitySerializableFields(field.FieldType)))
{
return true;
}
}
return false;
}
public static bool IsUnitySerializableField(this FieldInfo self)
{
if ((self.IsPublic || self.HasAttribute<SerializeField>()) && self.FieldType.IsUnitySerializableType())
{
return true;
}
{
if (self.HasAttribute<SerializeReference>())
{
return true;
}
return false;
}
}
public static bool IsUnitySerializableLeafType(this Type self)
{
if (self.IsPrimitive)
{
return true;
}
if (self.IsEnum)
{
return true;
}
if (self == typeof(string))
{
return true;
}
return false;
}
public static bool IsUnitySerializableType(this Type self)
{
if (self.IsAbstract)
{
return false;
}
if (self.IsUnitySerializableLeafType())
{
return true;
}
return self.HasAttribute<SerializableAttribute>();
}
private static MethodInfo memberwiseCloneMethdo = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic); private static MethodInfo _memberwiseCloneMethdo = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);
internal static object Clone_Reflection(this object obj) internal static object Clone_Reflection(this object obj)
{ {
if (obj is ICloneable cloneable) if (obj is ICloneable cloneable)
{ {
return cloneable.Clone(); return cloneable.Clone();
} }
return memberwiseCloneMethdo.Invoke(obj, null); return _memberwiseCloneMethdo.Invoke(obj, null);
} }
internal static object Clone_Reflection<T>(this T obj) internal static object Clone_Reflection<T>(this T obj)
{ {
return Clone_Reflection((object)obj); return Clone_Reflection((object)obj);
} }
} }
internal partial class UnityReflectionCache
{
private static readonly Dictionary<Type, UnityReflectionCache> _cache = new Dictionary<Type, UnityReflectionCache>();
public static bool InitLocal(Type type, ref UnityReflectionCache localCache)
{
if (localCache != null && localCache.Type == type) { return false; }
localCache = Get(type);
return true;
}
public static UnityReflectionCache Get(Type type)
{
if(_cache.TryGetValue(type, out var result) == false)
{
result = new UnityReflectionCache(type);
_cache.Add(type, result);
}
return result;
}
public readonly Type Type;
public UnityReflectionCache(Type type)
{
Type = type;
}
}
} }
#endif #endif