2025-03-14 16:53:25 +08:00
#if DISABLE_DEBUG
#undef DEBUG
#endif
2025-05-18 10:52:24 +08:00
using DCFApixels.DragonECS.Core.Internal ;
2025-03-14 16:53:25 +08:00
using System ;
2023-06-16 11:53:59 +08:00
using System.Collections.Generic ;
2025-03-14 16:53:25 +08:00
#if DEBUG | | ! REFLECTION_DISABLED
2023-05-23 01:47:28 +08:00
using System.Reflection ;
2024-08-07 09:45:34 +08:00
#endif
2023-05-23 01:47:28 +08:00
namespace DCFApixels.DragonECS
{
public static class EcsDebugUtility
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ! REFLECTION_DISABLED
2023-11-01 02:30:19 +08:00
private const BindingFlags RFL_FLAGS = BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic ;
2024-08-07 09:45:34 +08:00
#endif
2023-11-01 02:30:19 +08:00
2023-06-16 12:34:54 +08:00
#region GetGenericTypeName
2024-03-06 21:35:34 +08:00
public static string GetGenericTypeFullName < T > ( int maxDepth = 2 )
{
return GetGenericTypeFullName ( typeof ( T ) , maxDepth ) ;
}
public static string GetGenericTypeFullName ( Type type , int maxDepth = 2 )
{
2024-08-07 09:45:34 +08:00
return GetGenericTypeName_Internal ( type , maxDepth , true ) ;
2024-03-06 21:35:34 +08:00
}
public static string GetGenericTypeName < T > ( int maxDepth = 2 )
{
return GetGenericTypeName ( typeof ( T ) , maxDepth ) ;
}
public static string GetGenericTypeName ( Type type , int maxDepth = 2 )
{
2024-08-07 09:45:34 +08:00
return GetGenericTypeName_Internal ( type , maxDepth , false ) ;
2024-03-06 21:35:34 +08:00
}
2024-08-07 09:45:34 +08:00
private static string GetGenericTypeName_Internal ( Type type , int maxDepth , bool isFull )
2023-05-23 01:47:28 +08:00
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ! REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
2024-03-06 21:35:34 +08:00
string typeName = isFull ? type . FullName : type . Name ;
2023-05-23 01:47:28 +08:00
if ( ! type . IsGenericType | | maxDepth = = 0 )
2024-03-06 21:35:34 +08:00
{
return typeName ;
}
int genericInfoIndex = typeName . LastIndexOf ( '`' ) ;
if ( genericInfoIndex > 0 )
{
typeName = typeName . Remove ( genericInfoIndex ) ;
}
2023-05-23 01:47:28 +08:00
2024-03-06 21:35:34 +08:00
string genericParams = "" ;
2023-05-23 01:47:28 +08:00
Type [ ] typeParameters = type . GetGenericArguments ( ) ;
for ( int i = 0 ; i < typeParameters . Length ; + + i )
{
2024-03-06 21:35:34 +08:00
//чтобы строка не была слишком длинной, используются сокращенные имена для типов аргументов
2024-08-07 09:50:14 +08:00
string paramTypeName = GetGenericTypeName_Internal ( typeParameters [ i ] , maxDepth - 1 , false ) ;
2024-03-06 21:35:34 +08:00
genericParams + = ( i = = 0 ? paramTypeName : $", {paramTypeName}" ) ;
2023-05-23 01:47:28 +08:00
}
2024-03-06 21:35:34 +08:00
return $"{typeName}<{genericParams}>" ;
2024-08-07 09:45:34 +08:00
#else
EcsDebug . PrintWarning ( $"Reflection is not available, the {nameof(GetGenericTypeName_Internal)} method does not work." ) ;
return isFull ? type . FullName : type . Name ;
#endif
2023-05-23 01:47:28 +08:00
}
2023-06-16 12:34:54 +08:00
#endregion
2023-05-23 01:47:28 +08:00
2023-06-22 10:50:47 +08:00
#region AutoToString
2023-06-22 10:58:57 +08:00
/// <summary> slow but automatic conversion of ValueType to string in the format "name(field1, field2... fieldn)" </summary>
2023-06-22 10:50:47 +08:00
public static string AutoToString < T > ( this T self , bool isWriteName = true ) where T : struct
{
return AutoToString ( self , typeof ( T ) , isWriteName ) ;
}
2024-08-14 21:23:34 +08:00
2024-09-13 11:03:51 +08:00
internal static string AutoToString ( object target , Type type , bool isWriteName )
2023-06-22 10:50:47 +08:00
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ! REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает
2024-02-23 18:34:40 +08:00
#pragma warning disable IL2070 // 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The parameter of method does not have matching annotations.
2023-11-01 02:30:19 +08:00
var fields = type . GetFields ( RFL_FLAGS ) ;
2024-02-23 18:34:40 +08:00
#pragma warning restore IL2070
2023-06-22 10:50:47 +08:00
string [ ] values = new string [ fields . Length ] ;
for ( int i = 0 ; i < fields . Length ; i + + )
2024-02-26 11:54:18 +08:00
{
2023-06-22 11:00:33 +08:00
values [ i ] = ( fields [ i ] . GetValue ( target ) ? ? "NULL" ) . ToString ( ) ;
2024-02-26 11:54:18 +08:00
}
2023-06-22 10:58:57 +08:00
if ( isWriteName )
2024-02-26 11:54:18 +08:00
{
2023-06-22 10:50:47 +08:00
return $"{type.Name}({string.Join(" , ", values)})" ;
2024-02-26 11:54:18 +08:00
}
2023-06-22 10:50:47 +08:00
else
2024-02-26 11:54:18 +08:00
{
2023-06-22 10:50:47 +08:00
return $"({string.Join(" , ", values)})" ;
2024-02-26 11:54:18 +08:00
}
2024-02-26 10:43:37 +08:00
#else
2024-02-23 18:34:40 +08:00
EcsDebug . PrintWarning ( $"Reflection is not available, the {nameof(AutoToString)} method does not work." ) ;
return string . Empty ;
2024-02-26 10:43:37 +08:00
#endif
2023-06-22 10:50:47 +08:00
}
#endregion
2023-06-16 12:34:54 +08:00
#region GetName
2024-03-06 21:35:34 +08:00
public static string GetMetaName ( object obj )
2023-10-31 03:03:13 +08:00
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta ( obj ) . Name ;
2023-10-31 03:03:13 +08:00
}
2024-03-06 21:35:34 +08:00
public static string GetMetaName < T > ( )
2023-10-31 03:03:13 +08:00
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta < T > ( ) . Name ;
2023-10-31 03:03:13 +08:00
}
2024-03-06 21:35:34 +08:00
public static string GetMetaName ( Type type )
2023-06-16 11:53:59 +08:00
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta ( type ) . Name ;
}
public static bool TryGetMetaName ( object obj , out string name )
{
TypeMeta meta = GetTypeMeta ( obj ) ;
name = meta . Name ;
return meta . IsCustomName ;
}
public static bool TryGetMetaName < T > ( out string name )
{
TypeMeta meta = GetTypeMeta < T > ( ) ;
name = meta . Name ;
return meta . IsCustomName ;
}
public static bool TryGetMetaName ( Type type , out string name )
{
TypeMeta meta = GetTypeMeta ( type ) ;
name = meta . Name ;
return meta . IsCustomName ;
2023-06-16 11:53:59 +08:00
}
2023-06-16 12:34:54 +08:00
#endregion
2023-05-23 01:47:28 +08:00
2024-03-06 21:35:34 +08:00
#region GetColor
public static MetaColor GetColor ( object obj )
2023-11-01 02:30:19 +08:00
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta ( obj ) . Color ;
2023-11-01 02:30:19 +08:00
}
2024-03-06 21:35:34 +08:00
public static MetaColor GetColor < T > ( )
2023-11-01 02:30:19 +08:00
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta < T > ( ) . Color ;
2023-11-01 02:30:19 +08:00
}
2024-03-06 21:35:34 +08:00
public static MetaColor GetColor ( Type type )
2023-06-29 17:57:28 +08:00
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta ( type ) . Color ;
}
public static bool TryGetColor ( object obj , out MetaColor color )
{
TypeMeta meta = GetTypeMeta ( obj ) ;
color = meta . Color ;
return meta . IsCustomColor ;
}
public static bool TryGetColor < T > ( out MetaColor color )
{
TypeMeta meta = GetTypeMeta < T > ( ) ;
color = meta . Color ;
return meta . IsCustomColor ;
}
public static bool TryGetColor ( Type type , out MetaColor color )
{
TypeMeta meta = GetTypeMeta ( type ) ;
color = meta . Color ;
return meta . IsCustomColor ;
2023-06-29 17:57:28 +08:00
}
#endregion
2023-06-16 12:34:54 +08:00
#region GetDescription
2024-05-01 13:38:08 +08:00
public static MetaDescription GetDescription ( object obj )
2023-11-01 02:30:19 +08:00
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta ( obj ) . Description ;
2023-11-01 02:30:19 +08:00
}
2024-05-01 13:38:08 +08:00
public static MetaDescription GetDescription < T > ( )
2023-11-01 02:30:19 +08:00
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta < T > ( ) . Description ;
2023-11-01 02:30:19 +08:00
}
2024-05-01 13:38:08 +08:00
public static MetaDescription GetDescription ( Type type )
2023-06-16 11:53:59 +08:00
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta ( type ) . Description ;
2023-06-16 11:53:59 +08:00
}
2024-05-01 13:38:08 +08:00
public static bool TryGetDescription ( object obj , out MetaDescription description )
2023-11-01 02:30:19 +08:00
{
2024-03-06 21:35:34 +08:00
TypeMeta meta = GetTypeMeta ( obj ) ;
description = meta . Description ;
2024-05-01 13:38:08 +08:00
return description ! = MetaDescription . Empty ;
2023-11-01 02:30:19 +08:00
}
2024-05-01 13:38:08 +08:00
public static bool TryGetDescription < T > ( out MetaDescription description )
2024-02-26 11:54:18 +08:00
{
2024-03-06 21:35:34 +08:00
TypeMeta meta = GetTypeMeta < T > ( ) ;
description = meta . Description ;
2024-05-01 13:38:08 +08:00
return description ! = MetaDescription . Empty ;
2024-02-26 11:54:18 +08:00
}
2024-05-01 13:38:08 +08:00
public static bool TryGetDescription ( Type type , out MetaDescription description )
2023-05-23 01:47:28 +08:00
{
2024-03-06 21:35:34 +08:00
TypeMeta meta = GetTypeMeta ( type ) ;
description = meta . Description ;
2024-05-01 13:38:08 +08:00
return description ! = MetaDescription . Empty ;
2024-03-03 00:28:16 +08:00
}
2024-03-06 21:35:34 +08:00
#endregion
#region GetGroup
2024-03-06 23:29:37 +08:00
public static MetaGroup GetGroup ( object obj )
2024-03-03 00:28:16 +08:00
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta ( obj ) . Group ;
2023-06-16 11:53:59 +08:00
}
2024-03-06 23:29:37 +08:00
public static MetaGroup GetGroup < T > ( )
2023-11-01 02:30:19 +08:00
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta < T > ( ) . Group ;
2023-11-01 02:30:19 +08:00
}
2024-03-06 23:29:37 +08:00
public static MetaGroup GetGroup ( Type type )
2024-02-26 11:54:18 +08:00
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta ( type ) . Group ;
2024-02-26 11:54:18 +08:00
}
2024-03-06 21:35:34 +08:00
2024-03-06 23:29:37 +08:00
public static bool TryGetGroup ( object obj , out MetaGroup group )
2023-06-16 11:53:59 +08:00
{
2024-03-06 21:35:34 +08:00
TypeMeta meta = GetTypeMeta ( obj ) ;
group = meta . Group ;
2024-05-01 13:38:08 +08:00
return group ! = MetaGroup . Empty ;
2024-03-06 21:35:34 +08:00
}
2024-03-06 23:29:37 +08:00
public static bool TryGetGroup < T > ( out MetaGroup group )
2024-03-06 21:35:34 +08:00
{
TypeMeta meta = GetTypeMeta < T > ( ) ;
group = meta . Group ;
2024-05-01 13:38:08 +08:00
return group ! = MetaGroup . Empty ;
2024-03-06 21:35:34 +08:00
}
2024-03-06 23:29:37 +08:00
public static bool TryGetGroup ( Type type , out MetaGroup group )
2024-03-06 21:35:34 +08:00
{
TypeMeta meta = GetTypeMeta ( type ) ;
group = meta . Group ;
2024-05-01 13:38:08 +08:00
return group ! = MetaGroup . Empty ;
2023-12-20 23:16:57 +08:00
}
#endregion
#region GetTags
public static IReadOnlyCollection < string > GetTags ( object obj )
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta ( obj ) . Tags ;
2023-12-20 23:16:57 +08:00
}
2024-02-26 11:54:18 +08:00
public static IReadOnlyCollection < string > GetTags < T > ( )
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta < T > ( ) . Tags ;
2024-02-26 11:54:18 +08:00
}
2023-12-20 23:16:57 +08:00
public static IReadOnlyCollection < string > GetTags ( Type type )
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta ( type ) . Tags ;
2023-12-20 23:16:57 +08:00
}
public static bool TryGetTags ( object obj , out IReadOnlyCollection < string > tags )
{
2024-03-06 21:35:34 +08:00
TypeMeta meta = GetTypeMeta ( obj ) ;
tags = meta . Tags ;
return tags . Count < = 0 ;
2023-12-20 23:16:57 +08:00
}
2024-02-26 11:54:18 +08:00
public static bool TryGetTags < T > ( out IReadOnlyCollection < string > tags )
{
2024-03-06 21:35:34 +08:00
TypeMeta meta = GetTypeMeta < T > ( ) ;
tags = meta . Tags ;
return tags . Count < = 0 ;
2024-02-26 11:54:18 +08:00
}
2023-12-20 23:16:57 +08:00
public static bool TryGetTags ( Type type , out IReadOnlyCollection < string > tags )
{
2024-03-06 21:35:34 +08:00
TypeMeta meta = GetTypeMeta ( type ) ;
tags = meta . Tags ;
return tags . Count < = 0 ;
2023-05-23 01:47:28 +08:00
}
2023-06-16 11:53:59 +08:00
#endregion
2023-05-31 04:09:55 +08:00
2023-06-16 12:34:54 +08:00
#region IsHidden
2023-11-01 02:30:19 +08:00
public static bool IsHidden ( object obj )
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta ( obj ) . IsHidden ;
2023-11-01 02:30:19 +08:00
}
2024-02-26 11:54:18 +08:00
public static bool IsHidden < T > ( )
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta < T > ( ) . IsHidden ;
2024-02-26 11:54:18 +08:00
}
public static bool IsHidden ( Type type )
{
2024-03-06 21:35:34 +08:00
return GetTypeMeta ( type ) . IsHidden ;
2024-02-26 11:54:18 +08:00
}
2023-06-16 12:34:54 +08:00
#endregion
2024-03-06 21:35:34 +08:00
#region GetTypeMeta
public static TypeMeta GetTypeMeta ( object obj )
2023-11-01 02:30:19 +08:00
{
2024-09-27 21:46:16 +08:00
if ( obj = = null ) { return TypeMeta . NullTypeMeta ; }
2024-06-05 14:39:19 +08:00
return TypeMeta . Get ( GetTypeMetaSource ( obj ) . GetType ( ) ) ;
2023-11-01 02:30:19 +08:00
}
2024-03-06 21:35:34 +08:00
public static TypeMeta GetTypeMeta < T > ( )
2023-11-01 02:30:19 +08:00
{
2024-06-05 14:39:19 +08:00
return TypeMeta . Get ( typeof ( T ) ) ;
2023-11-01 02:30:19 +08:00
}
2024-03-06 21:35:34 +08:00
public static TypeMeta GetTypeMeta ( Type type )
2023-11-01 02:30:19 +08:00
{
2024-06-05 14:39:19 +08:00
return TypeMeta . Get ( type ) ;
2023-06-29 17:57:28 +08:00
}
#endregion
2024-08-07 09:45:34 +08:00
#region TypeMetaProvider
2024-03-06 21:35:34 +08:00
public static bool IsTypeMetaProvided ( object obj )
2023-05-31 04:09:55 +08:00
{
2024-03-06 21:35:34 +08:00
return obj is IEcsTypeMetaProvider ;
2023-05-31 04:09:55 +08:00
}
2024-03-06 21:35:34 +08:00
public static object GetTypeMetaSource ( object obj )
2023-06-16 12:34:54 +08:00
{
2024-03-06 21:35:34 +08:00
return obj is IEcsTypeMetaProvider intr ? intr . MetaSource : obj ;
2023-06-16 12:34:54 +08:00
}
#endregion
2024-02-26 11:54:18 +08:00
}
2024-03-10 01:25:08 +08:00
public static class TypeMetaDataCachedExtensions
{
public static TypeMeta GetMeta ( this object self )
2024-03-06 21:35:34 +08:00
{
2025-03-23 21:12:58 +08:00
#if DEBUG & & DRAGONECS_DEEP_DEBUG
if ( self is Type type ) { Throw . DeepDebugException ( ) ; }
#endif
2024-03-10 01:25:08 +08:00
return EcsDebugUtility . GetTypeMeta ( self ) ;
2024-03-06 21:35:34 +08:00
}
2024-03-10 01:25:08 +08:00
public static TypeMeta ToMeta ( this Type self )
2024-03-06 21:35:34 +08:00
{
2024-03-10 01:25:08 +08:00
return EcsDebugUtility . GetTypeMeta ( self ) ;
2024-03-06 21:35:34 +08:00
}
2023-06-29 17:57:28 +08:00
}
2024-02-26 11:54:18 +08:00
}