mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 01:44:35 +08:00
update debug utils/ add DebugGroup attribute
This commit is contained in:
parent
7a5aa6477d
commit
26e45a6f16
@ -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
|
||||
{
|
||||
/// <summary> Red. RGB is (255, 0, 0)</summary>
|
||||
Red = (255 << 24) + (000 << 16) + (000 << 8),
|
||||
/// <summary> Green. RGB is (0, 255, 0)</summary>
|
||||
Green = (000 << 24) + (255 << 16) + (000 << 8),
|
||||
/// <summary> Blue. RGB is (0, 0, 255)</summary>
|
||||
Blue = (000 << 24) + (000 << 16) + (255 << 8),
|
||||
public static readonly DebugColor BlackColor = new DebugColor(Black);
|
||||
/// <summary> color code Red. RGB is (255, 0, 0)</summary>
|
||||
public const int Red = (255 << 24) | (000 << 16) | (000 << 8) | 255;
|
||||
/// <summary> color code Green. RGB is (0, 255, 0)</summary>
|
||||
public const int Green = (000 << 24) | (255 << 16) | (000 << 8) | 255;
|
||||
/// <summary> color code Blue. RGB is (0, 0, 255)</summary>
|
||||
public const int Blue = (000 << 24) | (000 << 16) | (255 << 8) | 255;
|
||||
|
||||
/// <summary> Yellow. RGB is (255, 255, 0)</summary>
|
||||
Yellow = (255 << 24) + (255 << 16) + (000 << 8),
|
||||
/// <summary> Cyan. RGB is (0, 255, 255)</summary>
|
||||
Cyan = (000 << 24) + (255 << 16) + (255 << 8),
|
||||
/// <summary> Magenta. RGB is (255, 0, 255)</summary>
|
||||
Magenta = (255 << 24) + (000 << 16) + (255 << 8),
|
||||
/// <summary> color code Yellow. RGB is (255, 255, 0)</summary>
|
||||
public const int Yellow = (255 << 24) | (255 << 16) | (000 << 8) | 255;
|
||||
/// <summary> color code Cyan. RGB is (0, 255, 255)</summary>
|
||||
public const int Cyan = (000 << 24) | (255 << 16) | (255 << 8) | 255;
|
||||
/// <summary> color code Magenta. RGB is (255, 0, 255)</summary>
|
||||
public const int Magenta = (255 << 24) | (000 << 16) | (255 << 8) | 255;
|
||||
|
||||
/// <summary> Yellow. RGB is (255, 165, 0)</summary>
|
||||
Orange = (255 << 24) + (165 << 16) + (000 << 8),
|
||||
/// <summary> Yellow. RGB is (255, 69, 0)</summary>
|
||||
OrangeRed = (255 << 24) + (69 << 16) + (000 << 8),
|
||||
/// <summary> Lime. RGB is (125, 255, 0)</summary>
|
||||
Lime = (125 << 24) + (255 << 16) + (000 << 8),
|
||||
/// <summary> Lime. RGB is (127, 255, 212)</summary>
|
||||
Aquamarine = (127 << 24) + (255 << 16) + (212 << 8),
|
||||
/// <summary> Lime. RGB is (218, 165, 32)</summary>
|
||||
Goldenrod = (218 << 24) + (165 << 16) + (32 << 8),
|
||||
/// <summary> Yellow. RGB is (255, 105, 180)</summary>
|
||||
DeepPink = (255 << 24) + (105 << 16) + (180 << 8),
|
||||
/// <summary> Yellow. RGB is (220, 20, 60)</summary>
|
||||
Crimson = (220 << 24) + (20 << 16) + (60 << 8),
|
||||
/// <summary> Yellow. RGB is (138, 43, 226)</summary>
|
||||
BlueViolet = (138 << 24) + (43 << 16) + (226 << 8),
|
||||
/// <summary> Yellow. RGB is (255, 3, 62)</summary>
|
||||
AmericanRose = (255 << 24) + (3 << 16) + (62 << 8),
|
||||
/// <summary> color code Orange. RGB is (255, 165, 0)</summary>
|
||||
public const int Orange = (255 << 24) | (165 << 16) | (000 << 8) | 255;
|
||||
/// <summary> color code OrangeRed. RGB is (255, 69, 0)</summary>
|
||||
public const int OrangeRed = (255 << 24) | (69 << 16) | (000 << 8) | 255;
|
||||
/// <summary> color code Lime. RGB is (125, 255, 0)</summary>
|
||||
public const int Lime = (125 << 24) | (255 << 16) | (000 << 8) | 255;
|
||||
/// <summary> color code Aquamarine. RGB is (127, 255, 212)</summary>
|
||||
public const int Aquamarine = (127 << 24) | (255 << 16) | (212 << 8) | 255;
|
||||
/// <summary> color code Goldenrod. RGB is (218, 165, 32)</summary>
|
||||
public const int Goldenrod = (218 << 24) | (165 << 16) | (32 << 8) | 255;
|
||||
/// <summary> color code DeepPink. RGB is (255, 105, 180)</summary>
|
||||
public const int DeepPink = (255 << 24) | (105 << 16) | (180 << 8) | 255;
|
||||
/// <summary> color code Crimson. RGB is (220, 20, 60)</summary>
|
||||
public const int Crimson = (220 << 24) | (20 << 16) | (60 << 8) | 255;
|
||||
/// <summary> color code BlueViolet. RGB is (138, 43, 226)</summary>
|
||||
public const int BlueViolet = (138 << 24) | (43 << 16) | (226 << 8) | 255;
|
||||
/// <summary> color code AmericanRose. RGB is (255, 3, 62)</summary>
|
||||
public const int AmericanRose = (255 << 24) | (3 << 16) | (62 << 8) | 255;
|
||||
|
||||
/// <summary> Grey/Gray. RGB is (127, 127, 127)</summary>
|
||||
Gray = (127 << 24) + (127 << 16) + (127 << 8),
|
||||
/// <summary> Grey/Gray. RGB is (127, 127, 127)</summary>
|
||||
Grey = Gray,
|
||||
/// <summary> Grey/Gray. RGB is (192, 192, 192)</summary>
|
||||
Silver = (192 << 24) + (192 << 16) + (192 << 8),
|
||||
/// <summary> White. RGB is (255, 255, 255)</summary>
|
||||
White = -1,
|
||||
/// <summary> Black. RGB is (0, 0, 0)</summary>
|
||||
Black = 0,
|
||||
/// <summary> color code Grey/Gray. RGB is (127, 127, 127)</summary>
|
||||
public const int Gray = (127 << 24) | (127 << 16) | (127 << 8) | 255;
|
||||
/// <summary> color code Grey/Gray. RGB is (127, 127, 127)</summary>
|
||||
public const int Grey = Gray;
|
||||
/// <summary> color code Silver. RGB is (192, 192, 192)</summary>
|
||||
public const int Silver = (192 << 24) | (192 << 16) | (192 << 8) | 255;
|
||||
/// <summary> color code White. RGB is (255, 255, 255)</summary>
|
||||
public const int White = -1;
|
||||
/// <summary> color code Black. RGB is (0, 0, 0)</summary>
|
||||
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);
|
||||
}
|
||||
}
|
33
src/Debug/Attributes/DebugGroupAttribute.cs
Normal file
33
src/Debug/Attributes/DebugGroupAttribute.cs
Normal file
@ -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();
|
||||
}
|
||||
}
|
11
src/Debug/Attributes/DebugGroupAttribute.cs.meta
Normal file
11
src/Debug/Attributes/DebugGroupAttribute.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c447392c75f8b4a42a2e5c3eb49e5b82
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -72,6 +72,22 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetGroup
|
||||
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 bool TryGetGroup<T>(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<T>() => 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<Type, NameColor> _names = new Dictionary<Type, NameColor>();
|
||||
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<T>() => GetColorRGB(typeof(T));
|
||||
public static (byte, byte, byte) GetColorRGB(Type type)
|
||||
public static DebugColor GetColor<T>() => GetColor(typeof(T));
|
||||
public static DebugColor GetColor(Type type)
|
||||
{
|
||||
var atr = type.GetCustomAttribute<DebugColorAttribute>();
|
||||
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<T>(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<T>(out DebugColor color) => TryGetColor(typeof(T), out color);
|
||||
public static bool TryGetColor(Type type, out DebugColor color)
|
||||
{
|
||||
var atr = type.GetCustomAttribute<DebugColorAttribute>();
|
||||
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<T>() => 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<T>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ namespace DCFApixels.DragonECS
|
||||
public static int Count => _codes.Count;
|
||||
internal static class Cache<T>
|
||||
{
|
||||
public static readonly int code = EcsTypeCode.GetCode(typeof(T));
|
||||
public static readonly int code = GetCode(typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user