mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2026-04-22 01:45:55 +08:00
add MetaProxyAttribute
This commit is contained in:
parent
68d3d2bc4f
commit
371472e851
@ -6,7 +6,6 @@ using DCFApixels.DragonECS.Core.Internal;
|
|||||||
using DCFApixels.DragonECS.PoolsCore;
|
using DCFApixels.DragonECS.PoolsCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
#if DEBUG || !REFLECTION_DISABLED
|
#if DEBUG || !REFLECTION_DISABLED
|
||||||
@ -51,6 +50,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
private readonly int _uniqueID;
|
private readonly int _uniqueID;
|
||||||
internal readonly Type _type;
|
internal readonly Type _type;
|
||||||
|
private readonly MetaProxy _proxy;
|
||||||
|
|
||||||
private bool _isCustomName;
|
private bool _isCustomName;
|
||||||
private bool _isCustomColor;
|
private bool _isCustomColor;
|
||||||
@ -93,6 +93,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
_initFlags = InitFlag.All,
|
_initFlags = InitFlag.All,
|
||||||
};
|
};
|
||||||
|
|
||||||
_metaCache.Add(typeof(void).TypeHandle, NullTypeMeta);
|
_metaCache.Add(typeof(void).TypeHandle, NullTypeMeta);
|
||||||
}
|
}
|
||||||
public static TypeMeta Get(Type type) { return Get(type.TypeHandle); }
|
public static TypeMeta Get(Type type) { return Get(type.TypeHandle); }
|
||||||
@ -108,10 +109,45 @@ namespace DCFApixels.DragonECS
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private static Type FindDeclaringType(Type targetPureType, Type currentType)
|
||||||
|
{
|
||||||
|
if (currentType == typeof(object)) { return null; }
|
||||||
|
var pure = currentType.GetPureType();
|
||||||
|
if (pure == targetPureType)
|
||||||
|
{
|
||||||
|
return currentType;
|
||||||
|
}
|
||||||
|
return FindDeclaringType(targetPureType, currentType.BaseType);
|
||||||
|
}
|
||||||
private TypeMeta(Type type)
|
private TypeMeta(Type type)
|
||||||
{
|
{
|
||||||
_uniqueID = _increment++;
|
_uniqueID = _increment++;
|
||||||
_type = type;
|
_type = type;
|
||||||
|
_proxy = MetaProxy.EmptyProxy;
|
||||||
|
|
||||||
|
if (type.ContainsGenericParameters == false &&
|
||||||
|
type.TryGetAttribute<MetaProxyAttribute>(out var proxyAtr))
|
||||||
|
{
|
||||||
|
Type proxyType = proxyAtr.Type;
|
||||||
|
if (proxyType.ContainsGenericParameters && proxyType.IsNested)
|
||||||
|
{
|
||||||
|
var baseType = FindDeclaringType(proxyType.DeclaringType, type);
|
||||||
|
if(baseType != null)
|
||||||
|
{
|
||||||
|
var args = baseType.GetGenericArguments();
|
||||||
|
proxyType = proxyType.MakeGenericType(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proxyType.ContainsGenericParameters == false)
|
||||||
|
{
|
||||||
|
var proxy = Activator.CreateInstance(proxyType, type) as MetaProxy;
|
||||||
|
if (proxy != null)
|
||||||
|
{
|
||||||
|
_proxy = proxy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -127,7 +163,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
if (_initFlags.HasFlag(InitFlag.Name) == false)
|
if (_initFlags.HasFlag(InitFlag.Name) == false)
|
||||||
{
|
{
|
||||||
(_name, _isCustomName) = MetaGenerator.GetMetaName(_type);
|
(_name, _isCustomName) = MetaGenerator.GetMetaName(this);
|
||||||
_typeName = _isCustomName ? MetaGenerator.GetTypeName(_type) : _name;
|
_typeName = _isCustomName ? MetaGenerator.GetTypeName(_type) : _name;
|
||||||
_initFlags |= InitFlag.Name;
|
_initFlags |= InitFlag.Name;
|
||||||
}
|
}
|
||||||
@ -192,7 +228,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
if (_initFlags.HasFlag(InitFlag.Description) == false)
|
if (_initFlags.HasFlag(InitFlag.Description) == false)
|
||||||
{
|
{
|
||||||
_description = MetaGenerator.GetDescription(_type);
|
_description = MetaGenerator.GetDescription(this);
|
||||||
_initFlags |= InitFlag.Description;
|
_initFlags |= InitFlag.Description;
|
||||||
}
|
}
|
||||||
return _description;
|
return _description;
|
||||||
@ -207,7 +243,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
if (_initFlags.HasFlag(InitFlag.Group) == false)
|
if (_initFlags.HasFlag(InitFlag.Group) == false)
|
||||||
{
|
{
|
||||||
_group = MetaGenerator.GetGroup(_type);
|
_group = MetaGenerator.GetGroup(this);
|
||||||
_initFlags |= InitFlag.Group;
|
_initFlags |= InitFlag.Group;
|
||||||
}
|
}
|
||||||
return _group;
|
return _group;
|
||||||
@ -220,7 +256,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
if (_initFlags.HasFlag(InitFlag.Tags) == false)
|
if (_initFlags.HasFlag(InitFlag.Tags) == false)
|
||||||
{
|
{
|
||||||
_tags = MetaGenerator.GetTags(_type);
|
_tags = MetaGenerator.GetTags(this);
|
||||||
_initFlags |= InitFlag.Tags;
|
_initFlags |= InitFlag.Tags;
|
||||||
_isHidden = _tags.Contains(MetaTags.HIDDEN);
|
_isHidden = _tags.Contains(MetaTags.HIDDEN);
|
||||||
_isObsolete = _tags.Contains(MetaTags.OBSOLETE);
|
_isObsolete = _tags.Contains(MetaTags.OBSOLETE);
|
||||||
@ -480,9 +516,14 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
return EcsDebugUtility.GetGenericTypeName(type, GENERIC_NAME_DEPTH);
|
return EcsDebugUtility.GetGenericTypeName(type, GENERIC_NAME_DEPTH);
|
||||||
}
|
}
|
||||||
public static (string, bool) GetMetaName(Type type)
|
public static (string, bool) GetMetaName(TypeMeta meta)
|
||||||
{
|
{
|
||||||
#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
|
#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
|
||||||
|
if (meta._proxy.Name != null)
|
||||||
|
{
|
||||||
|
return (meta._proxy.Name, true);
|
||||||
|
}
|
||||||
|
var type = meta.Type;
|
||||||
bool isCustom = type.TryGetAttribute(out MetaNameAttribute atr) && string.IsNullOrEmpty(atr.name) == false;
|
bool isCustom = type.TryGetAttribute(out MetaNameAttribute atr) && string.IsNullOrEmpty(atr.name) == false;
|
||||||
if (isCustom)
|
if (isCustom)
|
||||||
{
|
{
|
||||||
@ -524,6 +565,10 @@ namespace DCFApixels.DragonECS
|
|||||||
public static (MetaColor, bool) GetColor(TypeMeta meta)
|
public static (MetaColor, bool) GetColor(TypeMeta meta)
|
||||||
{
|
{
|
||||||
#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
|
#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
|
||||||
|
if (meta._proxy.Color != null)
|
||||||
|
{
|
||||||
|
return (meta._proxy.Color.Value, true);
|
||||||
|
}
|
||||||
bool isCustom = meta.Type.TryGetAttribute(out MetaColorAttribute atr);
|
bool isCustom = meta.Type.TryGetAttribute(out MetaColorAttribute atr);
|
||||||
return (isCustom ? atr.color : AutoColor(meta), isCustom);
|
return (isCustom ? atr.color : AutoColor(meta), isCustom);
|
||||||
#else
|
#else
|
||||||
@ -534,16 +579,20 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GetGroup
|
#region GetGroup
|
||||||
public static MetaGroup GetGroup(Type type)
|
public static MetaGroup GetGroup(TypeMeta meta)
|
||||||
{
|
{
|
||||||
#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
|
#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
|
||||||
if (type.TryGetAttribute(out MetaGroupAttribute atr))
|
if (meta._proxy.Group != null)
|
||||||
|
{
|
||||||
|
return meta._proxy.Group;
|
||||||
|
}
|
||||||
|
if (meta.Type.TryGetAttribute(out MetaGroupAttribute atr))
|
||||||
{
|
{
|
||||||
return MetaGroup.FromName(atr.Name);
|
return MetaGroup.FromName(atr.Name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return MetaGroup.FromNameSpace(type);
|
return MetaGroup.FromNameSpace(meta.Type);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetGroup)} method does not work.");
|
EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetGroup)} method does not work.");
|
||||||
@ -553,10 +602,14 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GetDescription
|
#region GetDescription
|
||||||
public static MetaDescription GetDescription(Type type)
|
public static MetaDescription GetDescription(TypeMeta meta)
|
||||||
{
|
{
|
||||||
#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
|
#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
|
||||||
bool isCustom = type.TryGetAttribute(out MetaDescriptionAttribute atr);
|
if (meta._proxy.Description != null)
|
||||||
|
{
|
||||||
|
return meta._proxy.Description;
|
||||||
|
}
|
||||||
|
bool isCustom = meta.Type.TryGetAttribute(out MetaDescriptionAttribute atr);
|
||||||
return isCustom ? atr.Data : MetaDescription.Empty;
|
return isCustom ? atr.Data : MetaDescription.Empty;
|
||||||
#else
|
#else
|
||||||
EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetDescription)} method does not work.");
|
EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetDescription)} method does not work.");
|
||||||
@ -566,10 +619,14 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GetTags
|
#region GetTags
|
||||||
public static IReadOnlyList<string> GetTags(Type type)
|
public static IReadOnlyList<string> GetTags(TypeMeta meta)
|
||||||
{
|
{
|
||||||
#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
|
#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
|
||||||
var atr = type.GetCustomAttribute<MetaTagsAttribute>();
|
if (meta._proxy.Tags != null)
|
||||||
|
{
|
||||||
|
return meta._proxy.Tags.ToArray();
|
||||||
|
}
|
||||||
|
var atr = meta.Type.GetCustomAttribute<MetaTagsAttribute>();
|
||||||
return atr != null ? atr.Tags : Array.Empty<string>();
|
return atr != null ? atr.Tags : Array.Empty<string>();
|
||||||
#else
|
#else
|
||||||
EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetTags)} method does not work.");
|
EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetTags)} method does not work.");
|
||||||
@ -624,4 +681,28 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
|
||||||
|
public sealed class MetaProxyAttribute : EcsMetaAttribute
|
||||||
|
{
|
||||||
|
public Type Type;
|
||||||
|
public MetaProxyAttribute(Type type)
|
||||||
|
{
|
||||||
|
Type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class MetaProxy
|
||||||
|
{
|
||||||
|
public static readonly MetaProxy EmptyProxy = new MetaProxy(typeof(void));
|
||||||
|
public static TypeMeta EmptyMeta => TypeMeta.NullTypeMeta;
|
||||||
|
public readonly Type Type;
|
||||||
|
public virtual string Name { get { return null; } }
|
||||||
|
public virtual MetaColor? Color { get { return null; } }
|
||||||
|
public virtual MetaDescription Description { get { return null; } }
|
||||||
|
public virtual MetaGroup Group { get { return null; } }
|
||||||
|
public virtual IEnumerable<string> Tags { get { return null; } }
|
||||||
|
public MetaProxy(Type type)
|
||||||
|
{
|
||||||
|
Type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -9,6 +9,15 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
{
|
{
|
||||||
internal static class ReflectionUtility
|
internal static class ReflectionUtility
|
||||||
{
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Type GetPureType(this Type type)
|
||||||
|
{
|
||||||
|
if (type.IsGenericType)
|
||||||
|
{
|
||||||
|
return type.GetGenericTypeDefinition();
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool TryGetAttribute<T>(this MemberInfo self, out T attribute) where T : Attribute
|
public static bool TryGetAttribute<T>(this MemberInfo self, out T attribute) where T : Attribute
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user