From 2cbdb4f99438556b328ca2d7a58ef1bab2006744 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 26 Feb 2024 11:54:18 +0800 Subject: [PATCH] update EcsDebugUtility/ add cached meta --- src/Debug/EcsDebugUtility.cs | 260 ++++++++++++++++-- .../MetaAttributes/MetaColorAttribute.cs | 2 + .../MetaAttributes/MetaGroupAttribute.cs | 24 +- src/Internal/BitsUtility.cs | 30 +- 4 files changed, 287 insertions(+), 29 deletions(-) diff --git a/src/Debug/EcsDebugUtility.cs b/src/Debug/EcsDebugUtility.cs index 1ab8c58..8806499 100644 --- a/src/Debug/EcsDebugUtility.cs +++ b/src/Debug/EcsDebugUtility.cs @@ -1,4 +1,5 @@ -using System; +using DCFApixels.DragonECS.Internal; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -56,11 +57,17 @@ namespace DCFApixels.DragonECS #pragma warning restore IL2070 string[] values = new string[fields.Length]; for (int i = 0; i < fields.Length; i++) + { values[i] = (fields[i].GetValue(target) ?? "NULL").ToString(); + } if (isWriteName) + { return $"{type.Name}({string.Join(", ", values)})"; + } else + { return $"({string.Join(", ", values)})"; + } #else EcsDebug.PrintWarning($"Reflection is not available, the {nameof(AutoToString)} method does not work."); return string.Empty; @@ -153,7 +160,8 @@ namespace DCFApixels.DragonECS #endregion #region GetColor - private static Random random = new Random(100100100); + + #region Auto Color private static Dictionary _words = new Dictionary(); private class WordColor { @@ -171,7 +179,10 @@ namespace DCFApixels.DragonECS { color = new WordColor(); _words.Add(word, color); - color.color = new MetaColor((byte)random.Next(), (byte)random.Next(), (byte)random.Next()).UpContrastColor() / 2; + + MetaColor newColor = new MetaColor(BitsUtility.NextXorShiftState(word.GetHashCode())); + newColor = new MetaColor(newColor.r, newColor.g, newColor.b); + color.color = newColor.UpContrastColor() / 2; } color.wordsCount++; colors.Add(color); @@ -223,15 +234,20 @@ namespace DCFApixels.DragonECS { subs = s.Substring(start, i - start); if (subs.Length > 2 && subs.ToLower() != "system") + { words.Add(subs); + } start = i; } } subs = s.Substring(start); if (subs.Length > 2 && subs.ToLower() != "system") + { words.Add(subs); + } return words; } + #endregion public static MetaColor GetColor(object obj) { @@ -239,7 +255,10 @@ namespace DCFApixels.DragonECS GetColor(intr.MetaSource) : GetColor(type: obj.GetType()); } - public static MetaColor GetColor() => GetColor(typeof(T)); + public static MetaColor GetColor() + { + return GetColor(typeof(T)); + } public static MetaColor GetColor(Type type) { var atr = type.GetCustomAttribute(); @@ -256,7 +275,10 @@ namespace DCFApixels.DragonECS TryGetColor(intr.MetaSource, out color) : TryGetColor(type: obj.GetType(), out color); } - public static bool TryGetColor(out MetaColor color) => TryGetColor(typeof(T), out color); + public static bool TryGetColor(out MetaColor color) + { + return TryGetColor(typeof(T), out color); + } public static bool TryGetColor(Type type, out MetaColor color) { var atr = type.GetCustomAttribute(); @@ -277,7 +299,10 @@ namespace DCFApixels.DragonECS GetTags(intr.MetaSource) : GetTags(type: obj.GetType()); } - public static IReadOnlyCollection GetTags() => GetTags(typeof(T)); + public static IReadOnlyCollection GetTags() + { + return GetTags(typeof(T)); + } public static IReadOnlyCollection GetTags(Type type) { var atr = type.GetCustomAttribute(); @@ -290,7 +315,10 @@ namespace DCFApixels.DragonECS TryGetTags(intr.MetaSource, out tags) : TryGetTags(type: obj.GetType(), out tags); } - public static bool TryGetTags(out IReadOnlyCollection tags) => TryGetTags(typeof(T), out tags); + public static bool TryGetTags(out IReadOnlyCollection tags) + { + return TryGetTags(typeof(T), out tags); + } public static bool TryGetTags(Type type, out IReadOnlyCollection tags) { var atr = type.GetCustomAttribute(); @@ -311,8 +339,14 @@ namespace DCFApixels.DragonECS IsHidden(intr.MetaSource) : IsHidden(type: obj.GetType()); } - public static bool IsHidden() => IsHidden(typeof(T)); - public static bool IsHidden(Type type) => type.TryGetCustomAttribute(out MetaTagsAttribute atr) && atr.Tags.Contains(MetaTags.HIDDEN); + public static bool IsHidden() + { + return IsHidden(typeof(T)); + } + public static bool IsHidden(Type type) + { + return type.TryGetCustomAttribute(out MetaTagsAttribute atr) && atr.Tags.Contains(MetaTags.HIDDEN); + } #endregion #region MetaSource @@ -326,15 +360,18 @@ namespace DCFApixels.DragonECS } #endregion - #region GenerateTypeDebugData - public static TypeMetaData GenerateTypeDebugData(object obj) + #region GenerateTypeMeta + public static TypeMetaData GenerateTypeMeta(object obj) { return obj is IEcsMetaProvider intr ? - GenerateTypeDebugData(intr.MetaSource) : - GenerateTypeDebugData(type: obj.GetType()); + GenerateTypeMeta(intr.MetaSource) : + GenerateTypeMeta(type: obj.GetType()); } - public static TypeMetaData GenerateTypeDebugData() => GenerateTypeDebugData(typeof(T)); - public static TypeMetaData GenerateTypeDebugData(Type type) + public static TypeMetaData GenerateTypeMeta() + { + return GenerateTypeMeta(typeof(T)); + } + public static TypeMetaData GenerateTypeMeta(Type type) { return new TypeMetaData( type, @@ -342,7 +379,30 @@ namespace DCFApixels.DragonECS GetGroup(type), GetColor(type), GetDescription(type), - GetTags(type).ToArray()); + GetTags(type)); + } + #endregion + + #region GetCachedTypeMeta + private static readonly Dictionary _metaCache = new Dictionary(); + public static TypeMetaDataCached GetCachedTypeMeta(object obj) + { + return obj is IEcsMetaProvider intr ? + GetCachedTypeMeta(intr.MetaSource) : + GetCachedTypeMeta(type: obj.GetType()); + } + public static TypeMetaDataCached GetCachedTypeMeta() + { + return GetCachedTypeMeta(typeof(T)); + } + public static TypeMetaDataCached GetCachedTypeMeta(Type type) + { + if(_metaCache.TryGetValue(type, out TypeMetaDataCached result) == false) + { + result = new TypeMetaDataCached(type); + _metaCache.Add(type, result); + } + return result; } #endregion @@ -362,6 +422,8 @@ namespace DCFApixels.DragonECS #endregion } + + [Serializable] public sealed class TypeMetaData { @@ -370,15 +432,175 @@ namespace DCFApixels.DragonECS public readonly MetaGroup group; public readonly MetaColor color; public readonly string description; - public readonly string[] tags; - public TypeMetaData(Type type, string name, MetaGroup group, MetaColor color, string description, string[] tags) + public readonly IReadOnlyCollection tags; + public TypeMetaData(Type type, string name, MetaGroup group, MetaColor color, string description, IReadOnlyCollection tags) { this.type = type; this.name = name; this.group = group; this.color = color; this.description = description; - this.tags = tags; + this.tags = tags; + } + } + + + + + public class TypeMetaDataCached + { + internal readonly Type _type; + + internal string _name; + internal MetaGroup _group; + internal MetaColor? _color; + internal string _description; + internal IReadOnlyCollection _tags; + + private TypeMetaData _typeMetaData = null; + private InitFlag _initFlags = InitFlag.None; + + public TypeMetaDataCached(Type type) + { + _type = type; + } + + public Type Type + { + get { return _type; } + } + public string Name + { + get + { + if (string.IsNullOrEmpty(_name)) + { + _name = EcsDebugUtility.GetName(_type); + _initFlags |= InitFlag.Name; + } + return _name; + } + } + public MetaGroup Group + { + get + { + if (_group.IsNull) + { + _group = EcsDebugUtility.GetGroup(_type); + _initFlags |= InitFlag.Group; + } + return _group; + } + } + public MetaColor Color + { + get + { + if (_color.HasValue == false) + { + _color = EcsDebugUtility.GetColor(_type); + _initFlags |= InitFlag.Color; + } + return _color.Value; + } + } + public string Description + { + get + { + if (_description == null) + { + _description = EcsDebugUtility.GetDescription(_type); + _initFlags |= InitFlag.Description; + } + return _description; + } + } + public IReadOnlyCollection Tags + { + get + { + if (_tags == null) + { + _tags = EcsDebugUtility.GetTags(_type); + _initFlags |= InitFlag.Tags; + } + return _tags; + } + } + public TypeMetaData AllData + { + get + { + if(_typeMetaData == null) + { + _typeMetaData = new TypeMetaData( + Type, + Name, + Group, + Color, + Description, + Tags); + } + return _typeMetaData; + } + } + + public void InitializeAll() + { + if (_initFlags == InitFlag.All) + { + return; + } + _ = Name; + _ = Group; + _ = Color; + _ = Description; + _ = Tags; + } + + private enum InitFlag : byte + { + None = 0, + Name = 1 << 0, + Group = 1 << 1, + Color = 1 << 2, + Description = 1 << 3, + Tags = 1 << 4, + All = Name | Group | Color | Description | Tags } } } + + +namespace DCFApixels.DragonECS.Internal +{ + internal static class EcsTypeMeta + { + private static readonly Dictionary _codes = new Dictionary(); + private static int _increment = 1; + public static int Count + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _codes.Count; } + } + public static int Get(Type type) + { + if (!_codes.TryGetValue(type, out int code)) + { + code = _increment++; + _codes.Add(type, code); + } + return code; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Get() { return EcsTypeCodeCache.code; } + public static bool Has(Type type) { return _codes.ContainsKey(type); } + public static bool Has() { return _codes.ContainsKey(typeof(T)); } + } + internal static class EcsTypeMetaCache + { + public static readonly int code = EcsTypeMeta.Get(typeof(T)); + } +} \ No newline at end of file diff --git a/src/Debug/MetaAttributes/MetaColorAttribute.cs b/src/Debug/MetaAttributes/MetaColorAttribute.cs index 3538942..fa9fb54 100644 --- a/src/Debug/MetaAttributes/MetaColorAttribute.cs +++ b/src/Debug/MetaAttributes/MetaColorAttribute.cs @@ -97,7 +97,9 @@ namespace DCFApixels.DragonECS byte minChannel = Math.Min(Math.Min(r, g), b); byte maxChannel = Math.Max(Math.Max(r, g), b); if (maxChannel == minChannel) + { return default; + } float factor = 255f / (maxChannel - minChannel); return new MetaColor((byte)((r - minChannel) * factor), (byte)((g - minChannel) * factor), (byte)((b - minChannel) * factor)); } diff --git a/src/Debug/MetaAttributes/MetaGroupAttribute.cs b/src/Debug/MetaAttributes/MetaGroupAttribute.cs index 455877e..92fc420 100644 --- a/src/Debug/MetaAttributes/MetaGroupAttribute.cs +++ b/src/Debug/MetaAttributes/MetaGroupAttribute.cs @@ -25,9 +25,25 @@ namespace DCFApixels.DragonECS { public static readonly MetaGroup Empty = new MetaGroup(MetaGroupAttribute.Empty); private readonly MetaGroupAttribute _source; - public string Name => _source.name; - public string RootCategory => _source.rootCategory; - public MetaGroup(MetaGroupAttribute source) => _source = source; - public string[] SplitCategories() => _source.SplitCategories(); + public string Name + { + get { return _source.name; } + } + public string RootCategory + { + get { return _source.rootCategory; } + } + public bool IsNull + { + get { return _source == null; } + } + public MetaGroup(MetaGroupAttribute source) + { + _source = source; + } + public string[] SplitCategories() + { + return _source.SplitCategories(); + } } } diff --git a/src/Internal/BitsUtility.cs b/src/Internal/BitsUtility.cs index c1f7497..2e06d1b 100644 --- a/src/Internal/BitsUtility.cs +++ b/src/Internal/BitsUtility.cs @@ -521,24 +521,42 @@ namespace DCFApixels.DragonECS.Internal [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int NextXorShiftState(int state) { - unchecked { return (state << 13) ^ (state >> 17) ^ (state << 5); }; + unchecked + { + return (int)NextXorShiftState((uint)state); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint NextXorShiftState(uint state) { - unchecked { return (state << 13) ^ (state >> 17) ^ (state << 5); }; + unchecked + { + state ^= state << 13; + state ^= state >> 17; + state ^= state << 5; + return state; + }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long NextXorShiftState(long state) { - const long m = 0x2545F491_4F6CDD1D; - unchecked { return ((state >> 13) ^ (state << 25) ^ (state >> 27)) * m; }; + unchecked + { + return (long)NextXorShiftState((ulong)state); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong NextXorShiftState(ulong state) { - const ulong m = 0x2545F491_4F6CDD1D; - unchecked { return ((state >> 13) ^ (state << 25) ^ (state >> 27)) * m; }; + unchecked + { + const ulong m = 0x2545F491_4F6CDD1D; + state ^= state >> 13; + state ^= state << 25; + state ^= state >> 27; + state *= m; + return state; + } } #endregion