diff --git a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs index bb854c7..1178fea 100644 --- a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs +++ b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs @@ -1,13 +1,12 @@ using DCFApixels.DragonECS.Internal; using System; +using System.Runtime.InteropServices; namespace DCFApixels.DragonECS { [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)] public sealed class MetaIDAttribute : EcsMetaAttribute { - //private static HashSet _ids = new HashSet(); - public readonly string ID; public MetaIDAttribute(string id) { @@ -19,33 +18,42 @@ namespace DCFApixels.DragonECS { Throw.ArgumentException($"Аргумент {nameof(id)} не может содержать символ запятой ','"); } - //if (_ids.Add(id) == false) //этот ексепшен не работает, так как атрибуты не кешируются а пересоздаются - //{ - // //TODO перевести ексепшен - // Throw.ArgumentException($"Дублирование MetaID: {id}"); - //} ID = id; } } public static class MetaIDUtility { + [ThreadStatic] + private static System.Random _randon; + [ThreadStatic] + private static byte[] _buffer; + [ThreadStatic] + private static bool _isInit; + public static unsafe string GenerateNewUniqueID() { - long ticks = DateTime.Now.Ticks; - byte* hibits = stackalloc byte[8]; - hibits = (byte*)ticks; - - byte[] byteArray = Guid.NewGuid().ToByteArray(); - - fixed (byte* ptr = byteArray) + if (_isInit == false) { - for (int i = 0; i < 8; i++) - { - byteArray[i] = hibits[i]; - } + IntPtr prt = Marshal.AllocHGlobal(1); + long alloc = (long)prt; + Marshal.Release(prt); + _randon = new System.Random((int)alloc); + _buffer = new byte[8]; + _isInit = true; } - return BitConverter.ToString(byteArray).Replace("-", ""); + + byte* hibits = stackalloc byte[8]; + long* hibitsL = (long*)hibits; + hibitsL[0] = DateTime.Now.Ticks; + hibitsL[1] = _randon.Next(); + + for (int i = 0; i < 8; i++) + { + _buffer[i] = hibits[i]; + } + + return BitConverter.ToString(_buffer).Replace("-", ""); } public static unsafe string GenerateNewUniqueIDWithAttribute() { diff --git a/src/DebugUtils/TypeMeta.cs b/src/DebugUtils/TypeMeta.cs index f80f714..bc94b33 100644 --- a/src/DebugUtils/TypeMeta.cs +++ b/src/DebugUtils/TypeMeta.cs @@ -461,11 +461,27 @@ namespace DCFApixels.DragonECS #endregion #region GetMetaID +#if (DEBUG && !DISABLE_DEBUG) || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает + private static Dictionary _idTypePairs = new Dictionary(); +#endif public static string GetMetaID(Type type) { #if (DEBUG && !DISABLE_DEBUG) || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает var atr = type.GetCustomAttribute(); - return atr != null ? atr.ID : string.Empty; + + if (atr == null) + { + return string.Empty; + } + else + { + if (_idTypePairs.TryGetValue(atr.ID, out Type otherType) && type != otherType) //этот ексепшен не работает, так как атрибуты не кешируются а пересоздаются + { + Throw.Exception($"Types {type.Name} and {otherType.Name} have duplicate MetaID identifiers."); + } + _idTypePairs.Add(atr.ID, type); + return atr.ID; + } #else EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetTags)} method does not work."); return string.Empty;