From 26e45a6f16dccb541e87d58eedb84b8271cb9388 Mon Sep 17 00:00:00 2001
From: Mikhail <99481254+DCFApixels@users.noreply.github.com>
Date: Thu, 29 Jun 2023 17:57:28 +0800
Subject: [PATCH] update debug utils/ add DebugGroup attribute
---
src/Debug/Attributes/DebugColorAttribute.cs | 162 ++++++++++--------
src/Debug/Attributes/DebugGroupAttribute.cs | 33 ++++
.../Attributes/DebugGroupAttribute.cs.meta | 11 ++
src/Debug/EcsDebugUtility.cs | 80 +++++++--
src/Utils/EcsTypeCode.cs | 2 +-
5 files changed, 196 insertions(+), 92 deletions(-)
create mode 100644 src/Debug/Attributes/DebugGroupAttribute.cs
create mode 100644 src/Debug/Attributes/DebugGroupAttribute.cs.meta
diff --git a/src/Debug/Attributes/DebugColorAttribute.cs b/src/Debug/Attributes/DebugColorAttribute.cs
index fe603dc..5ec68dd 100644
--- a/src/Debug/Attributes/DebugColorAttribute.cs
+++ b/src/Debug/Attributes/DebugColorAttribute.cs
@@ -6,89 +6,99 @@ namespace DCFApixels.DragonECS
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public sealed class DebugColorAttribute : Attribute
{
- private Color color;
+ public readonly DebugColor color;
public byte r => color.r;
public byte g => color.g;
public byte b => color.b;
- public DebugColorAttribute(byte r, byte g, byte b) => color = new Color(r, g, b);
- public DebugColorAttribute(DebugColor color) => this.color = new Color((int)color);
-
- [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 4)]
- internal readonly struct Color
- {
- [FieldOffset(0)] public readonly int full;
- [FieldOffset(3)] public readonly byte r;
- [FieldOffset(2)] public readonly byte g;
- [FieldOffset(1)] public readonly byte b;
- public Color(byte r, byte g, byte b) : this()
- {
- this.r = r;
- this.g = g;
- this.b = b;
- }
- public Color(int full) : this() => this.full = full;
- public (byte, byte, byte) ToTuple() => (r, g, b);
-
- public Color UpContrastColor()
- {
- 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 Color((byte)((r - minChannel) * factor), (byte)((g - minChannel) * factor), (byte)((b - minChannel) * factor));
- }
-
- public static Color operator /(Color a, float b)
- {
- return new Color((byte)(a.r / b), (byte)(a.g / b), (byte)(a.b / b));
- }
- }
+ public DebugColorAttribute(byte r, byte g, byte b) => color = new DebugColor(r, g, b, 255);
+ public DebugColorAttribute(int colorCode) => color = new DebugColor(colorCode, true);
}
- public enum DebugColor
+ [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 4)]
+ public readonly struct DebugColor
{
- /// Red. RGB is (255, 0, 0)
- Red = (255 << 24) + (000 << 16) + (000 << 8),
- /// Green. RGB is (0, 255, 0)
- Green = (000 << 24) + (255 << 16) + (000 << 8),
- /// Blue. RGB is (0, 0, 255)
- Blue = (000 << 24) + (000 << 16) + (255 << 8),
+ public static readonly DebugColor BlackColor = new DebugColor(Black);
+ /// color code Red. RGB is (255, 0, 0)
+ public const int Red = (255 << 24) | (000 << 16) | (000 << 8) | 255;
+ /// color code Green. RGB is (0, 255, 0)
+ public const int Green = (000 << 24) | (255 << 16) | (000 << 8) | 255;
+ /// color code Blue. RGB is (0, 0, 255)
+ public const int Blue = (000 << 24) | (000 << 16) | (255 << 8) | 255;
- /// Yellow. RGB is (255, 255, 0)
- Yellow = (255 << 24) + (255 << 16) + (000 << 8),
- /// Cyan. RGB is (0, 255, 255)
- Cyan = (000 << 24) + (255 << 16) + (255 << 8),
- /// Magenta. RGB is (255, 0, 255)
- Magenta = (255 << 24) + (000 << 16) + (255 << 8),
+ /// color code Yellow. RGB is (255, 255, 0)
+ public const int Yellow = (255 << 24) | (255 << 16) | (000 << 8) | 255;
+ /// color code Cyan. RGB is (0, 255, 255)
+ public const int Cyan = (000 << 24) | (255 << 16) | (255 << 8) | 255;
+ /// color code Magenta. RGB is (255, 0, 255)
+ public const int Magenta = (255 << 24) | (000 << 16) | (255 << 8) | 255;
- /// Yellow. RGB is (255, 165, 0)
- Orange = (255 << 24) + (165 << 16) + (000 << 8),
- /// Yellow. RGB is (255, 69, 0)
- OrangeRed = (255 << 24) + (69 << 16) + (000 << 8),
- /// Lime. RGB is (125, 255, 0)
- Lime = (125 << 24) + (255 << 16) + (000 << 8),
- /// Lime. RGB is (127, 255, 212)
- Aquamarine = (127 << 24) + (255 << 16) + (212 << 8),
- /// Lime. RGB is (218, 165, 32)
- Goldenrod = (218 << 24) + (165 << 16) + (32 << 8),
- /// Yellow. RGB is (255, 105, 180)
- DeepPink = (255 << 24) + (105 << 16) + (180 << 8),
- /// Yellow. RGB is (220, 20, 60)
- Crimson = (220 << 24) + (20 << 16) + (60 << 8),
- /// Yellow. RGB is (138, 43, 226)
- BlueViolet = (138 << 24) + (43 << 16) + (226 << 8),
- /// Yellow. RGB is (255, 3, 62)
- AmericanRose = (255 << 24) + (3 << 16) + (62 << 8),
+ /// color code Orange. RGB is (255, 165, 0)
+ public const int Orange = (255 << 24) | (165 << 16) | (000 << 8) | 255;
+ /// color code OrangeRed. RGB is (255, 69, 0)
+ public const int OrangeRed = (255 << 24) | (69 << 16) | (000 << 8) | 255;
+ /// color code Lime. RGB is (125, 255, 0)
+ public const int Lime = (125 << 24) | (255 << 16) | (000 << 8) | 255;
+ /// color code Aquamarine. RGB is (127, 255, 212)
+ public const int Aquamarine = (127 << 24) | (255 << 16) | (212 << 8) | 255;
+ /// color code Goldenrod. RGB is (218, 165, 32)
+ public const int Goldenrod = (218 << 24) | (165 << 16) | (32 << 8) | 255;
+ /// color code DeepPink. RGB is (255, 105, 180)
+ public const int DeepPink = (255 << 24) | (105 << 16) | (180 << 8) | 255;
+ /// color code Crimson. RGB is (220, 20, 60)
+ public const int Crimson = (220 << 24) | (20 << 16) | (60 << 8) | 255;
+ /// color code BlueViolet. RGB is (138, 43, 226)
+ public const int BlueViolet = (138 << 24) | (43 << 16) | (226 << 8) | 255;
+ /// color code AmericanRose. RGB is (255, 3, 62)
+ public const int AmericanRose = (255 << 24) | (3 << 16) | (62 << 8) | 255;
- /// Grey/Gray. RGB is (127, 127, 127)
- Gray = (127 << 24) + (127 << 16) + (127 << 8),
- /// Grey/Gray. RGB is (127, 127, 127)
- Grey = Gray,
- /// Grey/Gray. RGB is (192, 192, 192)
- Silver = (192 << 24) + (192 << 16) + (192 << 8),
- /// White. RGB is (255, 255, 255)
- White = -1,
- /// Black. RGB is (0, 0, 0)
- Black = 0,
+ /// color code Grey/Gray. RGB is (127, 127, 127)
+ public const int Gray = (127 << 24) | (127 << 16) | (127 << 8) | 255;
+ /// color code Grey/Gray. RGB is (127, 127, 127)
+ public const int Grey = Gray;
+ /// color code Silver. RGB is (192, 192, 192)
+ public const int Silver = (192 << 24) | (192 << 16) | (192 << 8) | 255;
+ /// color code White. RGB is (255, 255, 255)
+ public const int White = -1;
+ /// color code Black. RGB is (0, 0, 0)
+ public const int Black = 0;
+
+
+ [FieldOffset(0)] public readonly int colorCode;
+ [FieldOffset(3)] public readonly byte r;
+ [FieldOffset(2)] public readonly byte g;
+ [FieldOffset(1)] public readonly byte b;
+ [FieldOffset(0)] public readonly byte a;
+ public DebugColor(byte r, byte g, byte b) : this()
+ {
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ a = 255;
+ }
+ public DebugColor(byte r, byte g, byte b, byte a) : this()
+ {
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ this.a = a;
+ }
+ public DebugColor(int colorCode) : this() => this.colorCode = colorCode;
+ public DebugColor(int colorCode, bool withoutAlpha) : this() => this.colorCode = withoutAlpha ? colorCode | 255 : colorCode;
+ public (byte, byte, byte) ToTupleRGB() => (r, g, b);
+ public (byte, byte, byte, byte) ToTupleRGBA() => (r, g, b, a);
+
+ public DebugColor UpContrastColor()
+ {
+ 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 DebugColor((byte)((r - minChannel) * factor), (byte)((g - minChannel) * factor), (byte)((b - minChannel) * factor));
+ }
+ public static DebugColor operator /(DebugColor a, float b)
+ {
+ return new DebugColor((byte)(a.r / b), (byte)(a.g / b), (byte)(a.b / b));
+ }
+ //public static explicit operator DebugColor(int colorCode) => new DebugColor(colorCode);
}
}
\ No newline at end of file
diff --git a/src/Debug/Attributes/DebugGroupAttribute.cs b/src/Debug/Attributes/DebugGroupAttribute.cs
new file mode 100644
index 0000000..e0c7567
--- /dev/null
+++ b/src/Debug/Attributes/DebugGroupAttribute.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Text.RegularExpressions;
+
+namespace DCFApixels.DragonECS
+{
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)]
+ public sealed class DebugGroupAttribute : Attribute
+ {
+ public static readonly DebugGroupAttribute Empty = new DebugGroupAttribute("");
+ public readonly string name;
+ public readonly string rootCategory;
+ public DebugGroupAttribute(string name)
+ {
+ name = Regex.Replace(name, @"^[/|\\]+|[/|\\]+$", "");
+ rootCategory = Regex.Match(name, @"^(.*?)[/\\]").Groups[1].Value;
+ this.name = name;
+ }
+ public string[] SplitCategories()
+ {
+ return Regex.Split(name, @"[/|\\]");
+ }
+ public DebugGroup GetData() => new DebugGroup(this);
+ }
+ public readonly struct DebugGroup
+ {
+ public static readonly DebugGroup Empty = new DebugGroup(DebugGroupAttribute.Empty);
+ private readonly DebugGroupAttribute _source;
+ public string Name => _source.name;
+ public string RootCategory => _source.rootCategory;
+ public DebugGroup(DebugGroupAttribute source) => _source = source;
+ public string[] SplitCategories() => _source.SplitCategories();
+ }
+}
diff --git a/src/Debug/Attributes/DebugGroupAttribute.cs.meta b/src/Debug/Attributes/DebugGroupAttribute.cs.meta
new file mode 100644
index 0000000..594d6fb
--- /dev/null
+++ b/src/Debug/Attributes/DebugGroupAttribute.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c447392c75f8b4a42a2e5c3eb49e5b82
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/Debug/EcsDebugUtility.cs b/src/Debug/EcsDebugUtility.cs
index 7985286..803c9b6 100644
--- a/src/Debug/EcsDebugUtility.cs
+++ b/src/Debug/EcsDebugUtility.cs
@@ -72,6 +72,22 @@ namespace DCFApixels.DragonECS
}
#endregion
+ #region GetGroup
+ 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(out DebugGroup text) => TryGetGroup(typeof(T), out text);
+ public static bool TryGetGroup(Type type, out DebugGroup group)
+ {
+ if (type.TryGetCustomAttribute(out DebugGroupAttribute atr))
+ {
+ group = atr.GetData();
+ return true;
+ }
+ group = DebugGroup.Empty;
+ return false;
+ }
+ #endregion
+
#region GetDescription
public static string GetDescription() => GetDescription(typeof(T));
public static string GetDescription(Type type) => type.TryGetCustomAttribute(out DebugDescriptionAttribute atr) ? atr.description : string.Empty;
@@ -94,7 +110,7 @@ namespace DCFApixels.DragonECS
private class WordColor
{
public int wordsCount;
- public DebugColorAttribute.Color color;
+ public DebugColor color;
}
private class NameColor
{
@@ -107,7 +123,7 @@ namespace DCFApixels.DragonECS
{
color = new WordColor();
_words.Add(word, color);
- color.color = new DebugColorAttribute.Color((byte)random.Next(), (byte)random.Next(), (byte)random.Next()).UpContrastColor() / 2;
+ color.color = new DebugColor((byte)random.Next(), (byte)random.Next(), (byte)random.Next()).UpContrastColor() / 2;
}
color.wordsCount++;
colors.Add(color);
@@ -122,7 +138,7 @@ namespace DCFApixels.DragonECS
}
return result;
}
- public DebugColorAttribute.Color CalcColor()
+ public DebugColor CalcColor()
{
float r = 0, g = 0, b = 0;
int totalWordsCount = CalcTotalWordsColor();
@@ -134,11 +150,11 @@ namespace DCFApixels.DragonECS
g += m * color.color.g;
b += m * color.color.b;
}
- return new DebugColorAttribute.Color((byte)r, (byte)g, (byte)b);
+ return new DebugColor((byte)r, (byte)g, (byte)b);
}
}
private static Dictionary _names = new Dictionary();
- private static DebugColorAttribute.Color CalcNameColorFor(Type type)
+ private static DebugColor CalcNameColorFor(Type type)
{
Type targetType = type.IsGenericType ? type.GetGenericTypeDefinition() : type;
if (!_names.TryGetValue(targetType, out NameColor nameColor))
@@ -169,27 +185,27 @@ namespace DCFApixels.DragonECS
return words;
}
- public static (byte, byte, byte) GetColorRGB() => GetColorRGB(typeof(T));
- public static (byte, byte, byte) GetColorRGB(Type type)
+ public static DebugColor GetColor() => GetColor(typeof(T));
+ public static DebugColor GetColor(Type type)
{
var atr = type.GetCustomAttribute();
- return atr != null ? (atr.r, atr.g, atr.b)
+ return atr != null ? atr.color
#if DEBUG //optimization for release build
- : CalcNameColorFor(type).ToTuple();
-#else
- : ((byte)0, (byte)0, (byte)0);
+ : CalcNameColorFor(type);
+#else
+ : DebugColor.BlackColor;
#endif
}
- public static bool TryGetColorRGB(out (byte, byte, byte) color) => TryGetColorRGB(typeof(T), out color);
- public static bool TryGetColorRGB(Type type, out (byte, byte, byte) color)
+ public static bool TryGetColor(out DebugColor color) => TryGetColor(typeof(T), out color);
+ public static bool TryGetColor(Type type, out DebugColor color)
{
var atr = type.GetCustomAttribute();
if (atr != null)
{
- color = (atr.r, atr.g, atr.b);
+ color = atr.color;
return true;
}
- color = ((byte)0, (byte)0, (byte)0);
+ color = DebugColor.BlackColor;
return false;
}
#endregion
@@ -199,6 +215,20 @@ namespace DCFApixels.DragonECS
public static bool IsHidden(Type type) => type.TryGetCustomAttribute(out DebugHideAttribute _);
#endregion
+ #region GenerateTypeDebugData
+ public static TypeDebugData GenerateTypeDebugData() => GenerateTypeDebugData(typeof(T));
+ public static TypeDebugData GenerateTypeDebugData(Type type)
+ {
+ return new TypeDebugData(
+ type,
+ GetName(type),
+ GetGroup(type),
+ GetColor(type),
+ GetDescription(type),
+ IsHidden(type));
+ }
+ #endregion
+
#region ReflectionExtensions
internal static bool TryGetCustomAttribute(this Type self, out T attribute) where T : Attribute
{
@@ -212,4 +242,24 @@ namespace DCFApixels.DragonECS
}
#endregion
}
+
+ [Serializable]
+ public sealed class TypeDebugData
+ {
+ public readonly Type type;
+ public readonly string name;
+ public readonly DebugGroup group;
+ public readonly DebugColor color;
+ public readonly string description;
+ public readonly bool isHidden;
+ public TypeDebugData(Type type, string name, DebugGroup group, DebugColor color, string description, bool isHidden)
+ {
+ this.type = type;
+ this.name = name;
+ this.group = group;
+ this.color = color;
+ this.description = description;
+ this.isHidden = isHidden;
+ }
+ }
}
diff --git a/src/Utils/EcsTypeCode.cs b/src/Utils/EcsTypeCode.cs
index 77d26f2..b18b4af 100644
--- a/src/Utils/EcsTypeCode.cs
+++ b/src/Utils/EcsTypeCode.cs
@@ -21,7 +21,7 @@ namespace DCFApixels.DragonECS
public static int Count => _codes.Count;
internal static class Cache
{
- public static readonly int code = EcsTypeCode.GetCode(typeof(T));
+ public static readonly int code = GetCode(typeof(T));
}
}
}