mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-19 02:24:37 +08:00
update debug utils
This commit is contained in:
parent
4abef9b0d7
commit
5f4d1c0c8e
@ -6,27 +6,43 @@ namespace DCFApixels.DragonECS
|
|||||||
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
|
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
|
||||||
public sealed class DebugColorAttribute : Attribute
|
public sealed class DebugColorAttribute : Attribute
|
||||||
{
|
{
|
||||||
private ColorRecord color;
|
private Color color;
|
||||||
public byte r => color.r;
|
public byte r => color.r;
|
||||||
public byte g => color.g;
|
public byte g => color.g;
|
||||||
public byte b => color.b;
|
public byte b => color.b;
|
||||||
public DebugColorAttribute(byte r, byte g, byte b) => color = new ColorRecord(r, g, b);
|
public DebugColorAttribute(byte r, byte g, byte b) => color = new Color(r, g, b);
|
||||||
public DebugColorAttribute(DebugColor color) => this.color = new ColorRecord((int)color);
|
public DebugColorAttribute(DebugColor color) => this.color = new Color((int)color);
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Explicit, Pack = 1, Size = 4)]
|
[StructLayout(LayoutKind.Explicit, Pack = 1, Size = 4)]
|
||||||
private readonly struct ColorRecord
|
internal readonly struct Color
|
||||||
{
|
{
|
||||||
[FieldOffset(0)] public readonly int full;
|
[FieldOffset(0)] public readonly int full;
|
||||||
[FieldOffset(3)] public readonly byte r;
|
[FieldOffset(3)] public readonly byte r;
|
||||||
[FieldOffset(2)] public readonly byte g;
|
[FieldOffset(2)] public readonly byte g;
|
||||||
[FieldOffset(1)] public readonly byte b;
|
[FieldOffset(1)] public readonly byte b;
|
||||||
public ColorRecord(byte r, byte g, byte b) : this()
|
public Color(byte r, byte g, byte b) : this()
|
||||||
{
|
{
|
||||||
this.r = r;
|
this.r = r;
|
||||||
this.g = g;
|
this.g = g;
|
||||||
this.b = b;
|
this.b = b;
|
||||||
}
|
}
|
||||||
public ColorRecord(int full) : this() => this.full = full;
|
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 enum DebugColor
|
public enum DebugColor
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
@ -40,6 +41,18 @@ namespace DCFApixels.DragonECS
|
|||||||
var atr = type.GetCustomAttribute<DebugNameAttribute>();
|
var atr = type.GetCustomAttribute<DebugNameAttribute>();
|
||||||
return atr != null ? atr.name : GetGenericTypeName(type);
|
return atr != null ? atr.name : GetGenericTypeName(type);
|
||||||
}
|
}
|
||||||
|
public static bool TryGetCustomName<T>(out string name) => TryGetCustomName(typeof(T), out name);
|
||||||
|
public static bool TryGetCustomName(Type type, out string name)
|
||||||
|
{
|
||||||
|
var atr = type.GetCustomAttribute<DebugNameAttribute>();
|
||||||
|
if (atr != null)
|
||||||
|
{
|
||||||
|
name = atr.name;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
name = string.Empty;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static string GetDescription<T>() => GetDescription(typeof(T));
|
public static string GetDescription<T>() => GetDescription(typeof(T));
|
||||||
public static string GetDescription(Type type)
|
public static string GetDescription(Type type)
|
||||||
@ -47,13 +60,124 @@ namespace DCFApixels.DragonECS
|
|||||||
var atr = type.GetCustomAttribute<DebugDescriptionAttribute>();
|
var atr = type.GetCustomAttribute<DebugDescriptionAttribute>();
|
||||||
return atr != null ? atr.description : string.Empty;
|
return atr != null ? atr.description : string.Empty;
|
||||||
}
|
}
|
||||||
|
public static bool TryGetDescription<T>(out string text) => TryGetDescription(typeof(T), out text);
|
||||||
|
public static bool TryGetDescription(Type type, out string text)
|
||||||
|
{
|
||||||
|
var atr = type.GetCustomAttribute<DebugDescriptionAttribute>();
|
||||||
|
if (atr != null)
|
||||||
|
{
|
||||||
|
text = atr.description;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
text = string.Empty;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region GetColor
|
||||||
|
private static Random random = new Random();
|
||||||
|
private static Dictionary<string, WordColor> _words = new Dictionary<string, WordColor>();
|
||||||
|
private class WordColor
|
||||||
|
{
|
||||||
|
public int wordsCount;
|
||||||
|
public DebugColorAttribute.Color color;
|
||||||
|
}
|
||||||
|
private class NameColor
|
||||||
|
{
|
||||||
|
public List<WordColor> colors = new List<WordColor>();
|
||||||
|
public NameColor(IEnumerable<string> nameWords)
|
||||||
|
{
|
||||||
|
foreach (var word in nameWords)
|
||||||
|
{
|
||||||
|
if(!_words.TryGetValue(word, out WordColor color))
|
||||||
|
{
|
||||||
|
color = new WordColor();
|
||||||
|
_words.Add(word, color);
|
||||||
|
color.color = new DebugColorAttribute.Color((byte)random.Next(), (byte)random.Next(), (byte)random.Next()).UpContrastColor() / 2;
|
||||||
|
}
|
||||||
|
color.wordsCount++;
|
||||||
|
colors.Add(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private int CalcTotalWordsColor()
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
for (int i = 0, iMax = colors.Count; i < iMax; i++)
|
||||||
|
{
|
||||||
|
result += colors[i].wordsCount;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
public DebugColorAttribute.Color CalcColor()
|
||||||
|
{
|
||||||
|
float r = 0, g = 0, b = 0;
|
||||||
|
int totalWordsCount = CalcTotalWordsColor();
|
||||||
|
for (int i = 0, iMax = colors.Count; i < iMax; i++)
|
||||||
|
{
|
||||||
|
var color = colors[i];
|
||||||
|
float m = (float)color.wordsCount / totalWordsCount;
|
||||||
|
r += m * color.color.r;
|
||||||
|
g += m * color.color.g;
|
||||||
|
b += m * color.color.b;
|
||||||
|
}
|
||||||
|
return new DebugColorAttribute.Color((byte)r, (byte)g, (byte)b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static Dictionary<Type, NameColor> _names = new Dictionary<Type, NameColor>();
|
||||||
|
private static DebugColorAttribute.Color CalcNameColorFor(Type type)
|
||||||
|
{
|
||||||
|
Type targetType = type.IsGenericType ? type.GetGenericTypeDefinition() : type;
|
||||||
|
if(!_names.TryGetValue(targetType, out NameColor nameColor))
|
||||||
|
{
|
||||||
|
nameColor = new NameColor(SplitString(targetType.Name));
|
||||||
|
_names.Add(targetType, nameColor);
|
||||||
|
}
|
||||||
|
return nameColor.CalcColor();
|
||||||
|
}
|
||||||
|
public static List<string> SplitString(string s)
|
||||||
|
{
|
||||||
|
string subs;
|
||||||
|
List<string> words = new List<string>();
|
||||||
|
int start = 0;
|
||||||
|
for (int i = 1; i < s.Length; i++)
|
||||||
|
{
|
||||||
|
if (char.IsUpper(s[i]))
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
public static (byte, byte, byte) GetColorRGB<T>() => GetColorRGB(typeof(T));
|
public static (byte, byte, byte) GetColorRGB<T>() => GetColorRGB(typeof(T));
|
||||||
public static (byte, byte, byte) GetColorRGB(Type type)
|
public static (byte, byte, byte) GetColorRGB(Type type)
|
||||||
{
|
{
|
||||||
var atr = type.GetCustomAttribute<DebugColorAttribute>();
|
var atr = type.GetCustomAttribute<DebugColorAttribute>();
|
||||||
return atr != null ? (atr.r, atr.g, atr.b) : ((byte)255, (byte)255, (byte)255);
|
return atr != null ? (atr.r, atr.g, atr.b)
|
||||||
|
#if DEBUG //optimization for release build
|
||||||
|
: CalcNameColorFor(type).ToTuple();
|
||||||
|
#else
|
||||||
|
: ((byte)0, (byte)0, (byte)0);
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
var atr = type.GetCustomAttribute<DebugColorAttribute>();
|
||||||
|
if(atr != null)
|
||||||
|
{
|
||||||
|
color = (atr.r, atr.g, atr.b);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
color = ((byte)0, (byte)0, (byte)0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
public static bool IsHidden<T>() => IsHidden(typeof(T));
|
public static bool IsHidden<T>() => IsHidden(typeof(T));
|
||||||
public static bool IsHidden(Type type)
|
public static bool IsHidden(Type type)
|
||||||
|
@ -385,15 +385,11 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
list.Clear();
|
list.Clear();
|
||||||
var itemsCount = GetComponentsCount(entityID);
|
var itemsCount = GetComponentsCount(entityID);
|
||||||
if (itemsCount == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (var i = 0; i < _pools.Length; i++)
|
for (var i = 0; i < _pools.Length; i++)
|
||||||
{
|
{
|
||||||
if (_pools[i].Has(entityID))
|
if (_pools[i].Has(entityID))
|
||||||
list.Add(_pools[i].GetRaw(entityID));
|
list.Add(_pools[i].GetRaw(entityID));
|
||||||
if (list.Count >= itemsCount)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
Loading…
Reference in New Issue
Block a user