update debug utils

remove IEcsDebugName
add IEcsDebugMetaProvider
update EcsDebugUtility
This commit is contained in:
Mikhail 2023-11-01 02:30:19 +08:00
parent f858529325
commit f9b70c51b2
5 changed files with 200 additions and 26 deletions

View File

@ -2,11 +2,68 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
public static class EcsDebugUtility 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<Type, ProcessInterface> _processes = new Dictionary<Type, ProcessInterface>();
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 #region GetGenericTypeName
public static string GetGenericTypeFullName<T>(int maxDepth = 2) => GetGenericTypeFullName(typeof(T), maxDepth); public static string GetGenericTypeFullName<T>(int maxDepth = 2) => GetGenericTypeFullName(typeof(T), maxDepth);
public static string GetGenericTypeFullName(Type type, int maxDepth = 2) => GetGenericTypeNameInternal(type, maxDepth, true); 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) 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]; string[] values = new string[fields.Length];
for (int i = 0; i < fields.Length; i++) for (int i = 0; i < fields.Length; i++)
values[i] = (fields[i].GetValue(target) ?? "NULL").ToString(); values[i] = (fields[i].GetValue(target) ?? "NULL").ToString();
@ -58,25 +115,21 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region GetName #region GetName
public static string GetNameForObject(IEcsDebugName obj) => obj.DebugName; public static string GetName(object obj, int maxGenericDepth = 2)
public static string GetNameForObject(object obj) => obj is IEcsDebugName dn ? dn.DebugName : GetName(obj.GetType());
public static string GetName<T>() => 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)
{ {
name = obj.DebugName; return obj is IEcsDebugMetaProvider intr ?
return true; GetName(intr.DebugMetaSource, maxGenericDepth) :
GetName(type: obj.GetType(), maxGenericDepth);
} }
public static bool TryGetCustomNameForObject(object obj, out string name) public static string GetName<T>(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) return obj is IEcsDebugMetaProvider intr ?
{ TryGetCustomName(intr.DebugMetaSource, out name) :
name = dn.DebugName; TryGetCustomName(type: obj.GetType(), out name);
return true;
} }
return TryGetCustomName(obj.GetType(), out name); public static bool TryGetCustomName<T>(out string name) => TryGetCustomName(type: typeof(T), out name);
}
public static bool TryGetCustomName<T>(out string name) => TryGetCustomName(typeof(T), out name);
public static bool TryGetCustomName(Type type, out string name) public static bool TryGetCustomName(Type type, out string name)
{ {
if (type.TryGetCustomAttribute(out DebugNameAttribute atr)) if (type.TryGetCustomAttribute(out DebugNameAttribute atr))
@ -90,8 +143,20 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region GetGroup #region GetGroup
public static DebugGroup GetGroup(object obj)
{
return obj is IEcsDebugMetaProvider intr ?
GetGroup(intr.DebugMetaSource) :
GetGroup(type: obj.GetType());
}
public static DebugGroup GetGroup<T>() => GetGroup(typeof(T)); public static DebugGroup GetGroup<T>() => GetGroup(typeof(T));
public static DebugGroup GetGroup(Type type) => type.TryGetCustomAttribute(out DebugGroupAttribute atr) ? atr.GetData() : DebugGroup.Empty; 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<T>(out DebugGroup text) => TryGetGroup(typeof(T), out text); public static bool TryGetGroup<T>(out DebugGroup text) => TryGetGroup(typeof(T), out text);
public static bool TryGetGroup(Type type, out DebugGroup group) public static bool TryGetGroup(Type type, out DebugGroup group)
{ {
@ -106,8 +171,20 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region GetDescription #region GetDescription
public static string GetDescription(object obj)
{
return obj is IEcsDebugMetaProvider intr ?
GetDescription(intr.DebugMetaSource) :
GetDescription(type: obj.GetType());
}
public static string GetDescription<T>() => GetDescription(typeof(T)); public static string GetDescription<T>() => GetDescription(typeof(T));
public static string GetDescription(Type type) => type.TryGetCustomAttribute(out DebugDescriptionAttribute atr) ? atr.description : string.Empty; 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<T>(out string text) => TryGetDescription(typeof(T), out text); public static bool TryGetDescription<T>(out string text) => TryGetDescription(typeof(T), out text);
public static bool TryGetDescription(Type type, out string text) public static bool TryGetDescription(Type type, out string text)
{ {
@ -122,7 +199,7 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region GetColor #region GetColor
private static Random random = new Random(); private static Random random = new Random(100100100);
private static Dictionary<string, WordColor> _words = new Dictionary<string, WordColor>(); private static Dictionary<string, WordColor> _words = new Dictionary<string, WordColor>();
private class WordColor private class WordColor
{ {
@ -181,7 +258,7 @@ namespace DCFApixels.DragonECS
} }
return nameColor.CalcColor(); return nameColor.CalcColor();
} }
public static List<string> SplitString(string s) private static List<string> SplitString(string s)
{ {
string subs; string subs;
List<string> words = new List<string>(); List<string> words = new List<string>();
@ -202,6 +279,12 @@ namespace DCFApixels.DragonECS
return words; return words;
} }
public static DebugColor GetColor(object obj)
{
return obj is IEcsDebugMetaProvider intr ?
GetColor(intr.DebugMetaSource) :
GetColor(type: obj.GetType());
}
public static DebugColor GetColor<T>() => GetColor(typeof(T)); public static DebugColor GetColor<T>() => GetColor(typeof(T));
public static DebugColor GetColor(Type type) public static DebugColor GetColor(Type type)
{ {
@ -213,6 +296,12 @@ namespace DCFApixels.DragonECS
: DebugColor.BlackColor; : DebugColor.BlackColor;
#endif #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<T>(out DebugColor color) => TryGetColor(typeof(T), out color); public static bool TryGetColor<T>(out DebugColor color) => TryGetColor(typeof(T), out color);
public static bool TryGetColor(Type type, out DebugColor color) public static bool TryGetColor(Type type, out DebugColor color)
{ {
@ -228,11 +317,34 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region IsHidden #region IsHidden
public static bool IsHidden(object obj)
{
return obj is IEcsDebugMetaProvider intr ?
IsHidden(intr.DebugMetaSource) :
IsHidden(type: obj.GetType());
}
public static bool IsHidden<T>() => IsHidden(typeof(T)); public static bool IsHidden<T>() => IsHidden(typeof(T));
public static bool IsHidden(Type type) => type.TryGetCustomAttribute(out DebugHideAttribute _); public static bool IsHidden(Type type) => type.TryGetCustomAttribute(out DebugHideAttribute _);
#endregion #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 #region GenerateTypeDebugData
public static TypeDebugData GenerateTypeDebugData(object obj)
{
return obj is IEcsDebugMetaProvider intr ?
GenerateTypeDebugData(intr.DebugMetaSource) :
GenerateTypeDebugData(type: obj.GetType());
}
public static TypeDebugData GenerateTypeDebugData<T>() => GenerateTypeDebugData(typeof(T)); public static TypeDebugData GenerateTypeDebugData<T>() => GenerateTypeDebugData(typeof(T));
public static TypeDebugData GenerateTypeDebugData(Type type) public static TypeDebugData GenerateTypeDebugData(Type type)
{ {

View File

@ -0,0 +1,7 @@
namespace DCFApixels.DragonECS
{
public interface IEcsDebugMetaProvider
{
object DebugMetaSource { get; }
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 170270e2ac54ab54a9dab57f58e25a9c guid: 2356ad2f91cd0a84db3d572a9f3c33f5
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -1,7 +0,0 @@
namespace DCFApixels.DragonECS
{
public interface IEcsDebugName
{
string DebugName { get; }
}
}

View File

@ -252,4 +252,66 @@ namespace DCFApixels.DragonECS
return self.Optional<EcsHybridPool<T>>(); return self.Optional<EcsHybridPool<T>>();
} }
} }
public static class InterfaceMatrix
{
private static SparseArray<InterfaceMatrixEdge> _edges = new SparseArray<InterfaceMatrixEdge>();
private static SparseArray64<InterfaceMatrixEdge> _matrix = new SparseArray64<InterfaceMatrixEdge>();
public static bool HasEdge<TParent, TChild>()
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (!InterfaceIsDeclared<TParent>() || !InterfaceIsDeclared<TChild>())
EcsDebug.PrintWarning($"{nameof(TParent)} or {nameof(TChild)} not declared.");
#endif
return _matrix.Contains(InterfaceId<TParent>._id, InterfaceId<TChild>._id);
}
public static bool InterfaceIsDeclared<T>() => _edges.Contains(InterfaceId<T>._id);
public static void DeclareInterfacesFromClass<T>()
{
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<TParent, TChild>()
{
return new InterfaceMatrixEdge(
typeof(TParent),
typeof(TChild),
InterfaceId<TParent>._id,
InterfaceId<TChild>._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<T>
{
public static int _id = InterfaceId._increment++;
}
} }