This commit is contained in:
Mikhail 2026-04-14 17:06:58 +08:00
parent 224a689ab6
commit fe3163ab3d
5 changed files with 169 additions and 101 deletions

View File

@ -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<T> : IEcsComponent, IEnumerable<T>//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<string> Tags { get { return Meta?.Tags; } }
public MetaProxy(Type type) : base(type) { }
}
}
internal static class UnityComponentConsts

View File

@ -11,7 +11,7 @@ using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
internal class DragonFieldDropDown : MetaObjectsDropDown<DragonFieldDropDown.Cahce>
internal class DragonFieldDropDown : MetaObjectsDropDown<DragonFieldCahce>
{
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,31 +99,60 @@ namespace DCFApixels.DragonECS.Unity.Editors
//Event.current.Use();
}
internal class Cahce
{
private static Cahce[] _all;
internal static IReadOnlyList<Cahce> All
{
get { return _all; }
}
static Cahce() { StaticInit(); }
internal class DragonFieldCahce
{
internal static Type[] All => UnityEditorUtility._serializableTypes;
internal static HashSet<Type> AllDict;
internal static Dictionary<Type, DragonFieldCahce> RuntimeDict;
static DragonFieldCahce() { StaticInit(); }
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void StaticInit()
{
List<Cahce> list = new List<Cahce>(UnityEditorUtility._serializableTypes.Length);
foreach (var type in UnityEditorUtility._serializableTypes)
{
Cahce element = new Cahce(type);
list.Add(element);
AllDict = new HashSet<Type>(All);
RuntimeDict = new Dictionary<Type, DragonFieldCahce>();
}
_all = list.ToArray();
public static DragonFieldCahce GetInfoFor(Type type)
{
if (RuntimeDict.TryGetValue(type, out var info))
{
return info;
}
if (AllDict.Contains(type))
{
info = new DragonFieldCahce(type);
RuntimeDict.Add(type, info);
return info;
}
return null;
}
public static bool TryGetInfoFor(Type type, out DragonFieldCahce info)
{
if (RuntimeDict.TryGetValue(type, out info))
{
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
@ -170,18 +199,29 @@ namespace DCFApixels.DragonECS.Unity.Editors
return _defaultValueDummy;
}
}
public Cahce(Type type)
public DragonFieldCahce(Type type)
{
Type = type;
IsUnique = false;
if(type.TryGetAttribute<DragonMemnberWrapperAttribute>(out var atr))
{
WrappedFieldName = atr.WrappedFieldName;
var field = type.GetField(atr.WrappedFieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null && field.FieldType.IsConcreteType())
{
ComponentType = field.FieldType;
}
}
if (type.GetInterfaces().Contains(typeof(IComponentTemplate)))
{
var ct = (IComponentTemplate)Activator.CreateInstance(type);
IsUnique = ct.IsUnique;
ComponentType = ct.ComponentType;
}
else
if(ComponentType == null)
{
ComponentType = Type;
}
@ -200,7 +240,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
return Type.ToString();
}
}
}
internal class SystemsDropDown : MetaObjectsDropDown<Type>
{

View File

@ -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<string> Tags { get { return Meta?.Tags; } }
@ -74,6 +90,7 @@ namespace DCFApixels.DragonECS
}
}
#endregion
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]

View File

@ -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");
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");
componentProp = property.FindPropertyRelative(info.WrappedFieldName);
}
meta = fieldType.GetMeta();
}
if (componentProp == null)
{
componentProp = property;
}
}
meta = fieldType.GetMeta();
}