From fe3163ab3d945e5a83ae786033a1770aaaa955d2 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 14 Apr 2026 17:06:58 +0800 Subject: [PATCH] update --- src/Buildin/UnityComponent.cs | 11 ++ src/Internal/Editor/MetaObjectsDropDown.cs | 185 +++++++++++------- .../Templates/ComponentTemplateBase.cs | 23 ++- ...ownAttribute.cs => InspectorAttributes.cs} | 51 ++--- ...te.cs.meta => InspectorAttributes.cs.meta} | 0 5 files changed, 169 insertions(+), 101 deletions(-) rename src/Utils/{ReferenceDropDownAttribute.cs => InspectorAttributes.cs} (91%) rename src/Utils/{ReferenceDropDownAttribute.cs.meta => InspectorAttributes.cs.meta} (100%) diff --git a/src/Buildin/UnityComponent.cs b/src/Buildin/UnityComponent.cs index d55114c..18d6a0b 100644 --- a/src/Buildin/UnityComponent.cs +++ b/src/Buildin/UnityComponent.cs @@ -15,6 +15,7 @@ namespace DCFApixels.DragonECS [MetaDescription(AUTHOR, "Component-reference to Unity object for EcsPool.")] [MetaID("DragonECS_734F667C9201B80F1913388C2A8BB689")] [MetaTags(MetaTags.ENGINE_MEMBER)] + [MetaProxy(typeof(UnityComponent<>.MetaProxy))] public struct UnityComponent : IEcsComponent, IEnumerable//IntelliSense hack where T : Component { @@ -34,6 +35,16 @@ namespace DCFApixels.DragonECS { return $"UnityComponent<{typeof(T).GetMeta().TypeName}>"; } + private class MetaProxy : MetaProxyBase + { + protected TypeMeta Meta = typeof(T).GetMeta(); + public override string Name { get { return Meta?.Name; } } + public override MetaColor? Color { get { return Meta != null && Meta.IsCustomColor ? Meta.Color : null; } } + public override MetaGroup Group { get { return Meta?.Group; } } + public override MetaDescription Description { get { return Meta?.Description; } } + public override IEnumerable Tags { get { return Meta?.Tags; } } + public MetaProxy(Type type) : base(type) { } + } } internal static class UnityComponentConsts diff --git a/src/Internal/Editor/MetaObjectsDropDown.cs b/src/Internal/Editor/MetaObjectsDropDown.cs index 9d396d0..207336a 100644 --- a/src/Internal/Editor/MetaObjectsDropDown.cs +++ b/src/Internal/Editor/MetaObjectsDropDown.cs @@ -11,7 +11,7 @@ using UnityEngine; namespace DCFApixels.DragonECS.Unity.Editors { - internal class DragonFieldDropDown : MetaObjectsDropDown + internal class DragonFieldDropDown : MetaObjectsDropDown { private DragonFieldDropDown() { } @@ -25,15 +25,15 @@ namespace DCFApixels.DragonECS.Unity.Editors if (_dropDownsCache.TryGetValue(key, out var result) == false) { result = new DragonFieldDropDown(); - IEnumerable<(Cahce template, ITypeMeta meta)> itemMetaPairs = Cahce.All.ToArray() + IEnumerable<(DragonFieldCahce template, ITypeMeta meta)> itemMetaPairs = DragonFieldCahce.All.ToArray() .Where(o => { - return key.Check(o.Type); - + return key.Check(o); }) .Select(o => { - return (o, (ITypeMeta)o.Meta); + var info = DragonFieldCahce.GetInfoFor(o); + return (info, (ITypeMeta)info.Meta); }); //TODO оптимизировать или вырезать @@ -99,106 +99,145 @@ namespace DCFApixels.DragonECS.Unity.Editors //Event.current.Use(); } + } - internal class Cahce + internal class DragonFieldCahce + { + internal static Type[] All => UnityEditorUtility._serializableTypes; + internal static HashSet AllDict; + internal static Dictionary RuntimeDict; + + static DragonFieldCahce() { StaticInit(); } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void StaticInit() { - private static Cahce[] _all; - internal static IReadOnlyList All + AllDict = new HashSet(All); + RuntimeDict = new Dictionary(); + } + public static DragonFieldCahce GetInfoFor(Type type) + { + if (RuntimeDict.TryGetValue(type, out var info)) { - get { return _all; } + return info; } - static Cahce() { StaticInit(); } - - [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] - private static void StaticInit() + if (AllDict.Contains(type)) { - List list = new List(UnityEditorUtility._serializableTypes.Length); - foreach (var type in UnityEditorUtility._serializableTypes) - { - Cahce element = new Cahce(type); - list.Add(element); - } - _all = list.ToArray(); + info = new DragonFieldCahce(type); + RuntimeDict.Add(type, info); + return info; } - - - public readonly Type Type; - public readonly Type ComponentType; - public readonly bool IsUnique; - private TypeMeta _meta; - public TypeMeta Meta + return null; + } + public static bool TryGetInfoFor(Type type, out DragonFieldCahce info) + { + if (RuntimeDict.TryGetValue(type, out info)) { - get + return true; + } + if (AllDict.Contains(type)) + { + info = new DragonFieldCahce(type); + RuntimeDict.Add(type, info); + return true; + } + info = null; + return false; + } + + + public readonly Type Type; + public readonly Type ComponentType; + public readonly string WrappedFieldName; + public bool HasWrappedFieldName + { + get { return string.IsNullOrEmpty(WrappedFieldName) == false; } + } + public readonly bool IsUnique; + private TypeMeta _meta; + public TypeMeta Meta + { + get + { + if (_meta == null) { - if (_meta == null) { - { - _meta = Type.GetMeta(); - } + _meta = Type.GetMeta(); } - return _meta; } + return _meta; } - private bool _defaultValueTypeInit = false; - private object _defaultValueDummy; - public object DefaultValue + } + private bool _defaultValueTypeInit = false; + private object _defaultValueDummy; + public object DefaultValue + { + get { - get + if (_defaultValueTypeInit == false) { - if (_defaultValueTypeInit == false) + if (Type.IsValueType) { - if (Type.IsValueType) + FieldInfo field; + field = Type.GetField("Default", BindingFlags.Static | BindingFlags.Public); + if (field != null && field.FieldType == Type) { - FieldInfo field; - field = Type.GetField("Default", BindingFlags.Static | BindingFlags.Public); + _defaultValueDummy = field.GetValue(null).Clone_Reflection(); + } + + if (_defaultValueDummy == null) + { + field = Type.GetField("Empty", BindingFlags.Static | BindingFlags.Public); if (field != null && field.FieldType == Type) { _defaultValueDummy = field.GetValue(null).Clone_Reflection(); } - - if (_defaultValueDummy == null) - { - field = Type.GetField("Empty", BindingFlags.Static | BindingFlags.Public); - if (field != null && field.FieldType == Type) - { - _defaultValueDummy = field.GetValue(null).Clone_Reflection(); - } - } } - _defaultValueTypeInit = true; } - return _defaultValueDummy; + _defaultValueTypeInit = true; } + return _defaultValueDummy; } - public Cahce(Type type) - { - Type = type; - IsUnique = false; + } + public DragonFieldCahce(Type type) + { + Type = type; + IsUnique = false; - if (type.GetInterfaces().Contains(typeof(IComponentTemplate))) - { - var ct = (IComponentTemplate)Activator.CreateInstance(type); - IsUnique = ct.IsUnique; - ComponentType = ct.ComponentType; - } - else - { - ComponentType = Type; - } - } - public object CreateInstance() + if(type.TryGetAttribute(out var atr)) { - if (DefaultValue != null) + WrappedFieldName = atr.WrappedFieldName; + var field = type.GetField(atr.WrappedFieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + if (field != null && field.FieldType.IsConcreteType()) { - return DefaultValue.Clone_Reflection(); + ComponentType = field.FieldType; } - return Activator.CreateInstance(Type); } - public override string ToString() + if (type.GetInterfaces().Contains(typeof(IComponentTemplate))) { - return Type.ToString(); + var ct = (IComponentTemplate)Activator.CreateInstance(type); + IsUnique = ct.IsUnique; + ComponentType = ct.ComponentType; } + + if(ComponentType == null) + { + ComponentType = Type; + } + } + public object CreateInstance() + { + if (DefaultValue != null) + { + return DefaultValue.Clone_Reflection(); + } + return Activator.CreateInstance(Type); + } + + public override string ToString() + { + return Type.ToString(); } } diff --git a/src/Templates/EntityTemplate/Templates/ComponentTemplateBase.cs b/src/Templates/EntityTemplate/Templates/ComponentTemplateBase.cs index 5fc5fb0..cf2fa5b 100644 --- a/src/Templates/EntityTemplate/Templates/ComponentTemplateBase.cs +++ b/src/Templates/EntityTemplate/Templates/ComponentTemplateBase.cs @@ -1,6 +1,7 @@ #if DISABLE_DEBUG #undef DEBUG #endif +using DCFApixels.DragonECS.Unity; using DCFApixels.DragonECS.Unity.Internal; using System; using System.Collections.Generic; @@ -8,10 +9,23 @@ using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using UnityEngine; -using static DCFApixels.DragonECS.IComponentTemplate; + +namespace DCFApixels.DragonECS.Unity +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = true, AllowMultiple = false)] + public sealed class DragonMemnberWrapperAttribute : Attribute + { + public string WrappedFieldName; + public DragonMemnberWrapperAttribute(string wrappedFieldName) + { + WrappedFieldName = wrappedFieldName; + } + } +} namespace DCFApixels.DragonECS { + public interface IComponentTemplate : ITemplateNode { #region Properties @@ -35,6 +49,7 @@ namespace DCFApixels.DragonECS [Serializable] [MetaProxy(typeof(ComponentTemplateMetaProxy))] + [DragonMemnberWrapper("component")] public abstract class ComponentTemplateBase : IComponentTemplate { #region Properties @@ -45,17 +60,18 @@ namespace DCFApixels.DragonECS #region Methods public abstract object GetRaw(); public abstract void SetRaw(object raw); - public virtual void OnGizmos(Transform transform, GizmosMode mode) { } + public virtual void OnGizmos(Transform transform, IComponentTemplate.GizmosMode mode) { } public virtual void OnValidate(UnityEngine.Object obj) { } public abstract void Apply(short worldID, int entityID); #endregion + #region MetaProxy protected class ComponentTemplateMetaProxy : MetaProxyBase { protected TypeMeta Meta; public override string Name { get { return Meta?.Name; } } - public override MetaColor? Color { get { return Meta?.Color; } } + public override MetaColor? Color { get { return Meta != null && Meta.IsCustomColor ? Meta.Color : null; } } public override MetaGroup Group { get { return Meta?.Group; } } public override MetaDescription Description { get { return Meta?.Description; } } public override IEnumerable Tags { get { return Meta?.Tags; } } @@ -74,6 +90,7 @@ namespace DCFApixels.DragonECS } } + #endregion } [Serializable] [StructLayout(LayoutKind.Sequential)] diff --git a/src/Utils/ReferenceDropDownAttribute.cs b/src/Utils/InspectorAttributes.cs similarity index 91% rename from src/Utils/ReferenceDropDownAttribute.cs rename to src/Utils/InspectorAttributes.cs index defaca8..f40fd97 100644 --- a/src/Utils/ReferenceDropDownAttribute.cs +++ b/src/Utils/InspectorAttributes.cs @@ -178,9 +178,9 @@ namespace DCFApixels.DragonECS.Unity.Editors try { - if (instance is ComponentTemplateBase customTemplate) + if(DragonFieldCahce.RuntimeDict.TryGetValue(instance.GetType(), out var info) && info.HasWrappedFieldName) { - componentProp = property.FindPropertyRelative("component"); + componentProp = property.FindPropertyRelative(info.WrappedFieldName); } } catch @@ -194,16 +194,16 @@ namespace DCFApixels.DragonECS.Unity.Editors } else { - var fieldType = fieldInfo.FieldType; - if (typeof(ComponentTemplateBase).IsAssignableFrom(fieldType)) + var fieldType = PropertyType; + if (DragonFieldCahce.RuntimeDict.TryGetValue(fieldType, out var info) && info.HasWrappedFieldName) { - componentProp = property.FindPropertyRelative("component"); - if (componentProp == null) - { - componentProp = property; - } + componentProp = property.FindPropertyRelative(info.WrappedFieldName); } } + if (componentProp == null) + { + componentProp = property; + } { float result = EditorGUIUtility.singleLineHeight; @@ -239,18 +239,17 @@ namespace DCFApixels.DragonECS.Unity.Editors Rect srcRect = rect; if (isSerializeReference) { - var template = property.managedReferenceValue; - - if (template is ComponentTemplateBase) + var instance = property.managedReferenceValue; + if (DragonFieldCahce.TryGetInfoFor(instance.GetType(), out var info) && info.HasWrappedFieldName) { - componentProp = property.FindPropertyRelative("component"); + componentProp = property.FindPropertyRelative(info.WrappedFieldName); } if (componentProp == null) { DrawDamagedComponent(rect, "Damaged component template."); return; } - if (template == null) + if (instance == null) { isDrawProperty = false; } @@ -258,34 +257,36 @@ namespace DCFApixels.DragonECS.Unity.Editors //meta = template as ITypeMeta; if (meta == null) { - if (template is IComponentTemplate componentTemplate) + if (info != null) { - meta = componentTemplate.ComponentType.GetMeta(); + meta = info.ComponentType.GetMeta(); } else { - meta = template.GetMeta(); + meta = instance.GetMeta(); } } - if (isDrawDropDown && template != null && ReferenceDropDownAttribute.IsHideButtonIfNotNull) + EcsDebug.PrintJson(meta); + + if (isDrawDropDown && instance != null && ReferenceDropDownAttribute.IsHideButtonIfNotNull) { isDrawDropDown = false; } } else { - var fieldType = fieldInfo.FieldType; - if (typeof(ComponentTemplateBase).IsAssignableFrom(fieldType)) + var fieldType = PropertyType; + if (DragonFieldCahce.RuntimeDict.TryGetValue(fieldType, out var info) && info.HasWrappedFieldName) { - componentProp = property.FindPropertyRelative("component"); - if (componentProp == null) - { - componentProp = property; - } + componentProp = property.FindPropertyRelative(info.WrappedFieldName); } meta = fieldType.GetMeta(); } + if (componentProp == null) + { + componentProp = property; + } diff --git a/src/Utils/ReferenceDropDownAttribute.cs.meta b/src/Utils/InspectorAttributes.cs.meta similarity index 100% rename from src/Utils/ReferenceDropDownAttribute.cs.meta rename to src/Utils/InspectorAttributes.cs.meta