diff --git a/src/DebugUtils/EcsDebugUtility.cs b/src/DebugUtils/EcsDebugUtility.cs index 66cfae5..a4406b4 100644 --- a/src/DebugUtils/EcsDebugUtility.cs +++ b/src/DebugUtils/EcsDebugUtility.cs @@ -280,6 +280,7 @@ namespace DCFApixels.DragonECS #region GetTypeMeta public static TypeMeta GetTypeMeta(object obj) { + if (obj == null) { return TypeMeta.NullTypeMeta; } return TypeMeta.Get(GetTypeMetaSource(obj).GetType()); } public static TypeMeta GetTypeMeta() diff --git a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs index 1178fea..cc798de 100644 --- a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs +++ b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs @@ -18,6 +18,7 @@ namespace DCFApixels.DragonECS { Throw.ArgumentException($"Аргумент {nameof(id)} не может содержать символ запятой ','"); } + id = string.Intern(id); ID = id; } } @@ -25,7 +26,7 @@ namespace DCFApixels.DragonECS public static class MetaIDUtility { [ThreadStatic] - private static System.Random _randon; + private static Random _randon; [ThreadStatic] private static byte[] _buffer; [ThreadStatic] @@ -38,7 +39,7 @@ namespace DCFApixels.DragonECS IntPtr prt = Marshal.AllocHGlobal(1); long alloc = (long)prt; Marshal.Release(prt); - _randon = new System.Random((int)alloc); + _randon = new Random((int)alloc); _buffer = new byte[8]; _isInit = true; } diff --git a/src/DebugUtils/TypeMeta.cs b/src/DebugUtils/TypeMeta.cs index bc94b33..8197599 100644 --- a/src/DebugUtils/TypeMeta.cs +++ b/src/DebugUtils/TypeMeta.cs @@ -17,15 +17,14 @@ namespace DCFApixels.DragonECS MetaDescription Description { get; } MetaGroup Group { get; } IReadOnlyList Tags { get; } - //string MetaID { get; } ITypeMeta BaseMeta { get; } } public static class ITypeMetaExstensions { public static TypeMeta FindRootTypeMeta(this ITypeMeta meta) { - ITypeMeta result = null; - while ((result = meta.BaseMeta) != null) { } + ITypeMeta result = meta; + while (result.BaseMeta != null) { result = meta.BaseMeta; } return (TypeMeta)result; } } @@ -36,8 +35,14 @@ namespace DCFApixels.DragonECS [DebuggerTypeProxy(typeof(DebuggerProxy))] public sealed class TypeMeta : ITypeMeta { - private static readonly Dictionary _metaCache = new Dictionary(); + private const string NULL_NAME = "NULL"; + public static readonly TypeMeta NullTypeMeta; + private static object _lock = new object(); + private static readonly Dictionary _metaCache = new Dictionary(); + private static int _increment = 1; + + private readonly int _uniqueID; internal readonly Type _type; private bool _isCustomName; @@ -56,38 +61,31 @@ namespace DCFApixels.DragonECS private InitFlag _initFlags = InitFlag.None; - private static object _lock = new object(); - - //private EcsMemberType _memberType; - - public ITypeMeta BaseMeta - { - get { return null; } - } - - private static bool CheckEcsMemener(Type checkedType) - { -#if (DEBUG && !DISABLE_DEBUG) || !REFLECTION_DISABLED - return checkedType.IsInterface == false && checkedType.IsAbstract == false && typeof(IEcsMember).IsAssignableFrom(checkedType); -#else - EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetTags)} method does not work."); - return false; -#endif - } - public static bool IsHasMeta(Type type) - { -#if (DEBUG && !DISABLE_DEBUG) || !REFLECTION_DISABLED - return (CheckEcsMemener(type) || Attribute.GetCustomAttributes(type, typeof(EcsMetaAttribute), false).Length > 0); -#else - EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetTags)} method does not work."); - return false; -#endif - } - #region Constructors + static TypeMeta() + { + NullTypeMeta = new TypeMeta(typeof(void)) + { + _isCustomName = false, + _isCustomColor = true, + _isHidden = true, + + _name = NULL_NAME, + _typeName = NULL_NAME, + _color = new MetaColor(MetaColor.Black), + _description = new MetaDescription("", NULL_NAME), + _group = new MetaGroup(""), + _tags = Array.Empty(), + _metaID = string.Empty, + _typeCode = EcsTypeCode.Get(typeof(void)), + + _initFlags = InitFlag.All, + }; + _metaCache.Add(typeof(void), NullTypeMeta); + } public static TypeMeta Get(Type type) { - lock (_lock) + lock (_lock) //TODO посмотреть можно ли тут убрать лок { if (_metaCache.TryGetValue(type, out TypeMeta result) == false) { @@ -99,6 +97,7 @@ namespace DCFApixels.DragonECS } private TypeMeta(Type type) { + _uniqueID = _increment++; _type = type; } #endregion @@ -110,13 +109,6 @@ namespace DCFApixels.DragonECS } #endregion - //#region EcsMemberType - //public EcsMemberType EcsMemberType - //{ - // get { return _memberType; } - //} - //#endregion - #region Name private void InitName() { @@ -308,21 +300,42 @@ namespace DCFApixels.DragonECS #endregion #region Other - public override string ToString() + ITypeMeta ITypeMeta.BaseMeta { - return Name; + get { return null; } } - public override int GetHashCode() + private static bool CheckEcsMemener(Type checkedType) { - return _color.GetHashCode() ^ _name[0].GetHashCode() ^ _name[_name.Length - 1].GetHashCode(); +#if (DEBUG && !DISABLE_DEBUG) || !REFLECTION_DISABLED + return checkedType.IsInterface == false && checkedType.IsAbstract == false && typeof(IEcsMember).IsAssignableFrom(checkedType); +#else + EcsDebug.PrintWarning($"Reflection is not available, the {nameof(TypeMeta)}.{nameof(CheckEcsMemener)} method does not work."); + return false; +#endif } + public static bool IsHasMeta(Type type) + { +#if (DEBUG && !DISABLE_DEBUG) || !REFLECTION_DISABLED + return (CheckEcsMemener(type) || Attribute.GetCustomAttributes(type, typeof(EcsMetaAttribute), false).Length > 0); +#else + EcsDebug.PrintWarning($"Reflection is not available, the {nameof(TypeMeta)}.{nameof(IsHasMeta)} method does not work."); + return false; +#endif + } + public override string ToString() { return Name; } + /// Unique ID + public override int GetHashCode() { return _uniqueID; } private class DebuggerProxy : ITypeMeta { private readonly TypeMeta _meta; - public ITypeMeta BaseMeta + public int UniqueID { - get { return _meta.BaseMeta; } + get { return _meta._uniqueID; } + } + ITypeMeta ITypeMeta.BaseMeta + { + get { return null; } } public Type Type { @@ -483,7 +496,7 @@ namespace DCFApixels.DragonECS return atr.ID; } #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(GetMetaID)} method does not work."); return string.Empty; #endif } @@ -491,13 +504,4 @@ namespace DCFApixels.DragonECS } #endregion } - - //public enum EcsMemberType : byte - //{ - // Undefined = 0, - // - // Component = 1, - // System = 2, - // Other = 3, - //} } \ No newline at end of file