diff --git a/src/DebugUtils/MetaAttributes/MetaColorAttribute.cs b/src/DebugUtils/MetaAttributes/MetaColorAttribute.cs index 7d5e930..94f3431 100644 --- a/src/DebugUtils/MetaAttributes/MetaColorAttribute.cs +++ b/src/DebugUtils/MetaAttributes/MetaColorAttribute.cs @@ -26,6 +26,7 @@ namespace DCFApixels.DragonECS public sealed class MetaColorAttribute : EcsMetaAttribute, IMetaColor { public readonly MetaColor color; + public readonly Type InheritingColorType; #region Properties public byte R @@ -71,6 +72,10 @@ namespace DCFApixels.DragonECS { color = new MetaColor(colorCode, true); } + public MetaColorAttribute(Type inheritingColorType) + { + InheritingColorType = inheritingColorType; + } #endregion } [Serializable] diff --git a/src/DebugUtils/MetaAttributes/MetaGroupAttribute.cs b/src/DebugUtils/MetaAttributes/MetaGroupAttribute.cs index f2545d7..f94546c 100644 --- a/src/DebugUtils/MetaAttributes/MetaGroupAttribute.cs +++ b/src/DebugUtils/MetaAttributes/MetaGroupAttribute.cs @@ -12,61 +12,102 @@ namespace DCFApixels.DragonECS [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)] public sealed class MetaGroupAttribute : EcsMetaAttribute { - public const char SEPARATOR = '/'; - public readonly MetaGroup Data; + public const char SEPARATOR = MetaGroup.SEPARATOR; + public readonly Type InheritingGroupType = null; + public readonly string RelativeName = string.Empty; [Obsolete(EcsMetaAttributeHalper.EMPTY_NO_SENSE_MESSAGE)] - public MetaGroupAttribute() { Data = MetaGroup.Empty; } - public MetaGroupAttribute(string name) { Data = new MetaGroup(name); } - public MetaGroupAttribute(params string[] path) : this(string.Join(SEPARATOR, path)) { } + public MetaGroupAttribute() { } + public MetaGroupAttribute(string name) { RelativeName = name; } + public MetaGroupAttribute(params string[] path) { RelativeName = string.Join(SEPARATOR, path); } + public MetaGroupAttribute(Type inheritingGroupType) { InheritingGroupType = inheritingGroupType; } + public MetaGroupAttribute(Type inheritingGroupType, string relativeName) + { + InheritingGroupType = inheritingGroupType; + RelativeName = relativeName; + } + public MetaGroupAttribute(Type inheritingGroupType, params string[] relativePath) + { + InheritingGroupType = inheritingGroupType; + RelativeName = string.Join(SEPARATOR, relativePath); + } } [DebuggerDisplay("{Name}")] public class MetaGroup { - public const char SEPARATOR = MetaGroupAttribute.SEPARATOR; + public const char SEPARATOR = '/'; + private const string SEPARATOR_STR = "/"; public const string UNGROUPED = ""; private const string PATTERN = @"Module(?=/)"; - public static readonly MetaGroup Empty = new MetaGroup(UNGROUPED); + public static readonly MetaGroup Empty = new MetaGroup(null, UNGROUPED); + public readonly MetaGroup ParentGroup; public readonly string Name; - private string[] _path = null; + private string[] _splited = null; public IReadOnlyCollection Splited { get { - if (_path == null) + if (_splited == null) { - _path = EcsMetaAttributeHalper.Split(SEPARATOR, Name); + _splited = EcsMetaAttributeHalper.Split(SEPARATOR, Name); } - return _path; + return _splited; } } public bool IsEmpty { get { return this == Empty; } } - public MetaGroup(string name) + private MetaGroup(MetaGroup parentGroup, string name) { if (string.IsNullOrEmpty(name)) { Name = UNGROUPED; return; } - name = name.Replace('\\', SEPARATOR); + name = Regex.Replace(name, @"(\s*[\/\\]+\s*)+", SEPARATOR_STR).Trim(); if (name[name.Length - 1] != SEPARATOR) { name += SEPARATOR; } + if (name[0] == SEPARATOR) + { + name = name.Substring(1); + } Name = Regex.Replace(name, PATTERN, ""); Name = string.Intern(Name); } + public static MetaGroup FromName(string name) + { + return FromName(null, name); + } + public static MetaGroup FromName(MetaGroup parentGroup, string name) + { + if(parentGroup == null || parentGroup == Empty) + { + if (string.IsNullOrWhiteSpace(name)) + { + return Empty; + } + return new MetaGroup(null, name); + } + else + { + if (string.IsNullOrWhiteSpace(name)) + { + return new MetaGroup(parentGroup, parentGroup.Name); + } + return new MetaGroup(parentGroup, parentGroup.Name + name); + } + } public static MetaGroup FromNameSpace(Type type) { if (string.IsNullOrWhiteSpace(type.Namespace)) { return Empty; } - return new MetaGroup(type.Namespace.Replace('.', SEPARATOR)); + return new MetaGroup(null, type.Namespace.Replace('.', SEPARATOR)); } public override string ToString() { return Name; } } diff --git a/src/DebugUtils/TypeMeta.cs b/src/DebugUtils/TypeMeta.cs index bca81fe..373482a 100644 --- a/src/DebugUtils/TypeMeta.cs +++ b/src/DebugUtils/TypeMeta.cs @@ -86,7 +86,7 @@ namespace DCFApixels.DragonECS _typeName = NULL_NAME, _color = new MetaColor(MetaColor.Black), _description = new MetaDescription("", NULL_NAME), - _group = new MetaGroup(""), + _group = MetaGroup.Empty, _tags = Array.Empty(), _metaID = string.Empty, _typeCode = EcsTypeCodeManager.Get(typeof(void)), @@ -508,7 +508,6 @@ namespace DCFApixels.DragonECS #endregion #region GetColor - private static MetaColor AutoColor(TypeMeta meta) { int hash; @@ -522,14 +521,22 @@ namespace DCFApixels.DragonECS } return MetaColor.FromHashCode(hash).UpContrast(); } + private static MetaColor GetColorFromAttribute(MetaColorAttribute atr) + { + if(atr.InheritingColorType == null) + { + return atr.color; + } + return atr.InheritingColorType.ToMeta().Color; + } public static (MetaColor, bool) GetColor(TypeMeta meta) { #if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает bool isCustom = meta.Type.TryGetAttribute(out MetaColorAttribute atr); - return (isCustom ? atr.color : AutoColor(meta), isCustom); + return (isCustom ? GetColorFromAttribute(atr) : AutoColor(meta), isCustom); #else EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetColor)} method does not work."); - return (AutoColor(type), false); + return (MetaColor.White, false); #endif } #endregion @@ -538,7 +545,7 @@ namespace DCFApixels.DragonECS public static MetaGroup GetGroup(Type type) { #if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает - return type.TryGetAttribute(out MetaGroupAttribute atr) ? atr.Data : MetaGroup.FromNameSpace(type); + return type.TryGetAttribute(out MetaGroupAttribute atr) ? MetaGroup.FromName(atr.InheritingGroupType.GetMeta().Group, atr.RelativeName) : MetaGroup.FromNameSpace(type); #else EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetGroup)} method does not work."); return MetaGroup.Empty;