From f9b70c51b2a5528ac33d8138590cabff83d7d54b Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 1 Nov 2023 02:30:19 +0800 Subject: [PATCH] update debug utils remove IEcsDebugName add IEcsDebugMetaProvider update EcsDebugUtility --- src/Debug/EcsDebugUtility.cs | 148 +++++++++++++++--- src/Debug/Interfaces/IEcsDebugMetaProvider.cs | 7 + ....cs.meta => IEcsDebugMetaProvider.cs.meta} | 2 +- src/Debug/Interfaces/IEcsDebugName.cs | 7 - src/Pools/EcsHybridPool.cs | 62 ++++++++ 5 files changed, 200 insertions(+), 26 deletions(-) create mode 100644 src/Debug/Interfaces/IEcsDebugMetaProvider.cs rename src/Debug/Interfaces/{IEcsDebugName.cs.meta => IEcsDebugMetaProvider.cs.meta} (83%) delete mode 100644 src/Debug/Interfaces/IEcsDebugName.cs diff --git a/src/Debug/EcsDebugUtility.cs b/src/Debug/EcsDebugUtility.cs index 937a838..a365fd8 100644 --- a/src/Debug/EcsDebugUtility.cs +++ b/src/Debug/EcsDebugUtility.cs @@ -2,11 +2,68 @@ using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; +using System.Text.RegularExpressions; namespace DCFApixels.DragonECS { public static class EcsDebugUtility { + private const BindingFlags RFL_FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + + private struct ProcessInterface + { + public Type interfaceType; + public string processName; + public ProcessInterface(Type interfaceType, string processName) + { + this.interfaceType = interfaceType; + this.processName = processName; + } + } + private static Dictionary _processes = new Dictionary(); + + static EcsDebugUtility() + { + foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) + { + var types = assembly.GetTypes(); + foreach (var type in types) + { + if (!type.IsInterface) + continue; + + if (type.GetInterface(nameof(IEcsProcess)) != null) + { + string name = type.Name; + if (name[0] == 'I' && name.Length > 1 && char.IsUpper(name[1])) + name = name.Substring(1); + name = Regex.Replace(name, @"\bEcs|Process\b", ""); + _processes.Add(type, new ProcessInterface(type, name)); + } + } + } + } + + #region Process + public static bool IsProcessInterface(Type type) + { + if (type.IsGenericType) type = type.GetGenericTypeDefinition(); + return _processes.ContainsKey(type); + } + public static string GetProcessInterfaceName(Type type) + { + if (type.IsGenericType) type = type.GetGenericTypeDefinition(); + return _processes[type].processName; + } + public static bool TryGetProcessInterfaceName(Type type, out string name) + { + if (type.IsGenericType) type = type.GetGenericTypeDefinition(); + bool result = _processes.TryGetValue(type, out ProcessInterface data); + name = data.processName; + return result; + } + #endregion + #region GetGenericTypeName public static string GetGenericTypeFullName(int maxDepth = 2) => GetGenericTypeFullName(typeof(T), maxDepth); public static string GetGenericTypeFullName(Type type, int maxDepth = 2) => GetGenericTypeNameInternal(type, maxDepth, true); @@ -46,7 +103,7 @@ namespace DCFApixels.DragonECS } private static string AutoToString(object target, Type type, bool isWriteName) { - var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + var fields = type.GetFields(RFL_FLAGS); string[] values = new string[fields.Length]; for (int i = 0; i < fields.Length; i++) values[i] = (fields[i].GetValue(target) ?? "NULL").ToString(); @@ -58,25 +115,21 @@ namespace DCFApixels.DragonECS #endregion #region GetName - public static string GetNameForObject(IEcsDebugName obj) => obj.DebugName; - public static string GetNameForObject(object obj) => obj is IEcsDebugName dn ? dn.DebugName : GetName(obj.GetType()); - public static string GetName() => GetName(typeof(T)); - public static string GetName(Type type) => type.TryGetCustomAttribute(out DebugNameAttribute atr) ? atr.name : GetGenericTypeName(type); - public static bool TryGetCustomNameForObject(IEcsDebugName obj, out string name) + public static string GetName(object obj, int maxGenericDepth = 2) { - name = obj.DebugName; - return true; + return obj is IEcsDebugMetaProvider intr ? + GetName(intr.DebugMetaSource, maxGenericDepth) : + GetName(type: obj.GetType(), maxGenericDepth); } - public static bool TryGetCustomNameForObject(object obj, out string name) + public static string GetName(int maxGenericDepth = 2) => GetName(typeof(T), maxGenericDepth); + public static string GetName(Type type, int maxGenericDepth = 2) => type.TryGetCustomAttribute(out DebugNameAttribute atr) ? atr.name : GetGenericTypeName(type, maxGenericDepth); + public static bool TryGetCustomName(object obj, out string name) { - if (obj is IEcsDebugName dn) - { - name = dn.DebugName; - return true; - } - return TryGetCustomName(obj.GetType(), out name); + return obj is IEcsDebugMetaProvider intr ? + TryGetCustomName(intr.DebugMetaSource, out name) : + TryGetCustomName(type: obj.GetType(), out name); } - public static bool TryGetCustomName(out string name) => TryGetCustomName(typeof(T), out name); + public static bool TryGetCustomName(out string name) => TryGetCustomName(type: typeof(T), out name); public static bool TryGetCustomName(Type type, out string name) { if (type.TryGetCustomAttribute(out DebugNameAttribute atr)) @@ -90,8 +143,20 @@ namespace DCFApixels.DragonECS #endregion #region GetGroup + public static DebugGroup GetGroup(object obj) + { + return obj is IEcsDebugMetaProvider intr ? + GetGroup(intr.DebugMetaSource) : + GetGroup(type: obj.GetType()); + } public static DebugGroup GetGroup() => GetGroup(typeof(T)); public static DebugGroup GetGroup(Type type) => type.TryGetCustomAttribute(out DebugGroupAttribute atr) ? atr.GetData() : DebugGroup.Empty; + public static bool TryGetGroup(object obj, out DebugGroup group) + { + return obj is IEcsDebugMetaProvider intr ? + TryGetGroup(intr.DebugMetaSource, out group) : + TryGetGroup(type: obj.GetType(), out group); + } public static bool TryGetGroup(out DebugGroup text) => TryGetGroup(typeof(T), out text); public static bool TryGetGroup(Type type, out DebugGroup group) { @@ -106,8 +171,20 @@ namespace DCFApixels.DragonECS #endregion #region GetDescription + public static string GetDescription(object obj) + { + return obj is IEcsDebugMetaProvider intr ? + GetDescription(intr.DebugMetaSource) : + GetDescription(type: obj.GetType()); + } public static string GetDescription() => GetDescription(typeof(T)); public static string GetDescription(Type type) => type.TryGetCustomAttribute(out DebugDescriptionAttribute atr) ? atr.description : string.Empty; + public static bool TryGetDescription(object obj, out string text) + { + return obj is IEcsDebugMetaProvider intr ? + TryGetDescription(intr.DebugMetaSource, out text) : + TryGetDescription(type: obj.GetType(), out text); + } public static bool TryGetDescription(out string text) => TryGetDescription(typeof(T), out text); public static bool TryGetDescription(Type type, out string text) { @@ -122,7 +199,7 @@ namespace DCFApixels.DragonECS #endregion #region GetColor - private static Random random = new Random(); + private static Random random = new Random(100100100); private static Dictionary _words = new Dictionary(); private class WordColor { @@ -181,7 +258,7 @@ namespace DCFApixels.DragonECS } return nameColor.CalcColor(); } - public static List SplitString(string s) + private static List SplitString(string s) { string subs; List words = new List(); @@ -202,6 +279,12 @@ namespace DCFApixels.DragonECS return words; } + public static DebugColor GetColor(object obj) + { + return obj is IEcsDebugMetaProvider intr ? + GetColor(intr.DebugMetaSource) : + GetColor(type: obj.GetType()); + } public static DebugColor GetColor() => GetColor(typeof(T)); public static DebugColor GetColor(Type type) { @@ -213,6 +296,12 @@ namespace DCFApixels.DragonECS : DebugColor.BlackColor; #endif } + public static bool TryGetColor(object obj, out DebugColor color) + { + return obj is IEcsDebugMetaProvider intr ? + TryGetColor(intr.DebugMetaSource, out color) : + TryGetColor(type: obj.GetType(), out color); + } public static bool TryGetColor(out DebugColor color) => TryGetColor(typeof(T), out color); public static bool TryGetColor(Type type, out DebugColor color) { @@ -228,11 +317,34 @@ namespace DCFApixels.DragonECS #endregion #region IsHidden + public static bool IsHidden(object obj) + { + return obj is IEcsDebugMetaProvider intr ? + IsHidden(intr.DebugMetaSource) : + IsHidden(type: obj.GetType()); + } public static bool IsHidden() => IsHidden(typeof(T)); public static bool IsHidden(Type type) => type.TryGetCustomAttribute(out DebugHideAttribute _); #endregion + #region MetaSource + public static bool IsMetaSourceProvided(object obj) + { + return obj is IEcsDebugMetaProvider; + } + public static object GetMetaSource(object obj) + { + return obj is IEcsDebugMetaProvider intr ? intr.DebugMetaSource : obj; + } + #endregion + #region GenerateTypeDebugData + public static TypeDebugData GenerateTypeDebugData(object obj) + { + return obj is IEcsDebugMetaProvider intr ? + GenerateTypeDebugData(intr.DebugMetaSource) : + GenerateTypeDebugData(type: obj.GetType()); + } public static TypeDebugData GenerateTypeDebugData() => GenerateTypeDebugData(typeof(T)); public static TypeDebugData GenerateTypeDebugData(Type type) { diff --git a/src/Debug/Interfaces/IEcsDebugMetaProvider.cs b/src/Debug/Interfaces/IEcsDebugMetaProvider.cs new file mode 100644 index 0000000..706c8b9 --- /dev/null +++ b/src/Debug/Interfaces/IEcsDebugMetaProvider.cs @@ -0,0 +1,7 @@ +namespace DCFApixels.DragonECS +{ + public interface IEcsDebugMetaProvider + { + object DebugMetaSource { get; } + } +} diff --git a/src/Debug/Interfaces/IEcsDebugName.cs.meta b/src/Debug/Interfaces/IEcsDebugMetaProvider.cs.meta similarity index 83% rename from src/Debug/Interfaces/IEcsDebugName.cs.meta rename to src/Debug/Interfaces/IEcsDebugMetaProvider.cs.meta index cdf6285..793a2f6 100644 --- a/src/Debug/Interfaces/IEcsDebugName.cs.meta +++ b/src/Debug/Interfaces/IEcsDebugMetaProvider.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 170270e2ac54ab54a9dab57f58e25a9c +guid: 2356ad2f91cd0a84db3d572a9f3c33f5 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Debug/Interfaces/IEcsDebugName.cs b/src/Debug/Interfaces/IEcsDebugName.cs deleted file mode 100644 index 90431f4..0000000 --- a/src/Debug/Interfaces/IEcsDebugName.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace DCFApixels.DragonECS -{ - public interface IEcsDebugName - { - string DebugName { get; } - } -} diff --git a/src/Pools/EcsHybridPool.cs b/src/Pools/EcsHybridPool.cs index df47d53..3cbf10a 100644 --- a/src/Pools/EcsHybridPool.cs +++ b/src/Pools/EcsHybridPool.cs @@ -252,4 +252,66 @@ namespace DCFApixels.DragonECS return self.Optional>(); } } + + + + + + + + public static class InterfaceMatrix + { + private static SparseArray _edges = new SparseArray(); + private static SparseArray64 _matrix = new SparseArray64(); + public static bool HasEdge() + { +#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS + if (!InterfaceIsDeclared() || !InterfaceIsDeclared()) + EcsDebug.PrintWarning($"{nameof(TParent)} or {nameof(TChild)} not declared."); +#endif + return _matrix.Contains(InterfaceId._id, InterfaceId._id); + } + public static bool InterfaceIsDeclared() => _edges.Contains(InterfaceId._id); + + public static void DeclareInterfacesFromClass() + { + Type type = typeof(T); + if (type.IsInterface) + throw new ArgumentException($"The argument {nameof(T)} cannot be an interface"); + } + } + internal class InterfaceMatrixEdge + { + private static int _increment = 0; + + public readonly int id; + public readonly Type parentType; + public readonly Type childType; + public readonly int parentID; + public readonly int childID; + public static InterfaceMatrixEdge New() + { + return new InterfaceMatrixEdge( + typeof(TParent), + typeof(TChild), + InterfaceId._id, + InterfaceId._id); + } + public InterfaceMatrixEdge(Type parentType, Type childType, int parentID, int childID) + { + id = _increment++; + this.parentType = parentType; + this.childType = childType; + this.parentID = parentID; + this.childID = childID; + } + } + internal static class InterfaceId + { + internal static int _increment; + } + internal static class InterfaceId + { + public static int _id = InterfaceId._increment++; + } }