2025-03-14 16:53:25 +08:00
#if DISABLE_DEBUG
#undef DEBUG
#endif
using DCFApixels.DragonECS.Internal ;
2023-05-26 06:18:09 +08:00
using System ;
2024-09-13 11:03:51 +08:00
using System.Collections ;
2024-09-12 03:01:22 +08:00
using System.Collections.Generic ;
using System.Linq ;
2023-03-27 17:58:51 +08:00
using System.Runtime.CompilerServices ;
2023-03-27 17:34:12 +08:00
namespace DCFApixels.DragonECS
{
2024-09-30 19:29:19 +08:00
using static EcsConsts ;
2023-03-30 06:05:53 +08:00
public readonly struct EcsProfilerMarker
2023-03-30 06:03:05 +08:00
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2023-03-30 06:05:53 +08:00
public readonly int id ;
2024-09-30 19:29:19 +08:00
#endif
internal EcsProfilerMarker ( int id )
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2024-09-30 19:29:19 +08:00
this . id = id ;
#endif
}
2024-09-12 04:05:15 +08:00
public EcsProfilerMarker ( string name )
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2024-10-05 00:25:42 +08:00
id = DebugService . CurrentThreadInstance . RegisterMark ( name ) ;
2024-09-30 19:29:19 +08:00
#endif
2024-09-12 04:05:15 +08:00
}
2023-03-30 11:17:17 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-09-30 19:29:19 +08:00
public void Begin ( )
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2024-10-05 00:25:42 +08:00
DebugService . CurrentThreadInstance . ProfilerMarkBegin ( id ) ;
2024-09-30 19:29:19 +08:00
#endif
}
2023-03-30 11:17:17 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-09-30 19:29:19 +08:00
public void End ( )
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2024-10-05 00:25:42 +08:00
DebugService . CurrentThreadInstance . ProfilerMarkEnd ( id ) ;
2024-09-30 19:29:19 +08:00
#endif
}
2023-03-30 11:17:17 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-09-30 19:29:19 +08:00
public AutoScope Auto ( )
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2024-09-30 19:29:19 +08:00
return new AutoScope ( id ) ;
#else
return default ;
#endif
}
2023-04-01 20:45:37 +08:00
public readonly ref struct AutoScope
2023-03-30 06:05:53 +08:00
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2023-05-26 05:13:11 +08:00
private readonly int _id ;
2024-09-30 19:29:19 +08:00
#endif
2024-06-08 02:08:20 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-03-30 06:05:53 +08:00
public AutoScope ( int id )
2023-03-30 06:03:05 +08:00
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2023-05-26 05:13:11 +08:00
_id = id ;
2024-10-05 00:25:42 +08:00
DebugService . CurrentThreadInstance . ProfilerMarkBegin ( id ) ;
2024-09-30 19:29:19 +08:00
#endif
2023-03-30 06:05:53 +08:00
}
2024-06-08 02:08:20 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-02-26 10:56:18 +08:00
public void Dispose ( )
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2024-10-05 00:25:42 +08:00
DebugService . CurrentThreadInstance . ProfilerMarkEnd ( _id ) ;
2024-09-30 19:29:19 +08:00
#endif
2024-02-26 10:56:18 +08:00
}
2023-03-30 06:03:05 +08:00
}
2024-06-08 02:08:20 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator EcsProfilerMarker ( string markerName ) { return new EcsProfilerMarker ( markerName ) ; }
2023-03-30 06:03:05 +08:00
}
2023-03-30 06:05:53 +08:00
2024-06-13 18:04:18 +08:00
[MetaColor(MetaColor.DragonRose)]
2024-09-30 19:29:19 +08:00
[MetaGroup(PACK_GROUP, DEBUG_GROUP)]
[MetaDescription(AUTHOR, "Debugging utility. To modify or change the behavior, create a new class inherited from DebugService and set this service using DebugService.Set<T>().")]
2024-10-12 14:48:13 +08:00
[MetaID("10A4587C92013B55820D8604D718A1C3")]
2023-03-27 17:34:12 +08:00
public static class EcsDebug
{
2024-02-26 10:56:18 +08:00
public static void Set < T > ( ) where T : DebugService , new ( )
{
DebugService . Set < T > ( ) ;
}
public static void Set ( DebugService service )
{
DebugService . Set ( service ) ;
}
2023-03-27 17:34:12 +08:00
2023-03-27 17:58:51 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-02-26 10:56:18 +08:00
public static void PrintWarning ( object v )
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2024-12-18 16:17:57 +08:00
OnPrint ( DEBUG_WARNING_TAG , v ) ;
2024-10-05 00:25:42 +08:00
DebugService . CurrentThreadInstance . PrintWarning ( v ) ;
2024-02-26 10:56:18 +08:00
#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void PrintError ( object v )
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2024-12-18 16:17:57 +08:00
OnPrint ( DEBUG_ERROR_TAG , v ) ;
2024-10-05 00:25:42 +08:00
DebugService . CurrentThreadInstance . PrintError ( v ) ;
2024-02-26 10:56:18 +08:00
#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-02-03 01:12:53 +08:00
public static void PrintErrorAndBreak ( object v )
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2024-12-18 16:17:57 +08:00
OnPrint ( DEBUG_ERROR_TAG , v ) ;
2024-10-05 00:25:42 +08:00
DebugService . CurrentThreadInstance . PrintErrorAndBreak ( v ) ;
2024-02-26 10:56:18 +08:00
#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void PrintPass ( object v )
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2024-12-18 16:17:57 +08:00
OnPrint ( DEBUG_PASS_TAG , v ) ;
2024-10-05 00:25:42 +08:00
DebugService . CurrentThreadInstance . PrintPass ( v ) ;
2024-02-26 10:56:18 +08:00
#endif
2024-02-03 01:12:53 +08:00
}
2024-02-26 10:56:18 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-11-08 15:15:10 +08:00
public static void Print ( )
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2024-12-18 16:17:57 +08:00
OnPrint ( string . Empty , null ) ;
2024-10-05 00:25:42 +08:00
DebugService . CurrentThreadInstance . Print ( ) ;
2023-11-08 15:15:10 +08:00
#endif
}
2024-02-26 10:56:18 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-05-27 15:59:46 +08:00
public static void Print ( object v )
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2024-12-18 16:17:57 +08:00
OnPrint ( string . Empty , v ) ;
2024-10-05 00:25:42 +08:00
DebugService . CurrentThreadInstance . Print ( v ) ;
2023-05-27 15:59:46 +08:00
#endif
}
2023-03-27 17:58:51 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-03-27 17:34:12 +08:00
public static void Print ( string tag , object v )
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2024-12-18 16:17:57 +08:00
OnPrint ( tag , v ) ;
2024-10-05 00:25:42 +08:00
DebugService . CurrentThreadInstance . Print ( tag , v ) ;
2023-03-27 17:34:12 +08:00
#endif
}
2024-02-26 10:56:18 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-06-30 00:32:25 +08:00
public static void Break ( )
{
2025-03-14 16:53:25 +08:00
#if DEBUG | | ENABLE_DRAGONECS_DEBUGGER
2024-10-05 00:25:42 +08:00
DebugService . CurrentThreadInstance . Break ( ) ;
2023-06-30 00:32:25 +08:00
#endif
}
2024-12-18 16:17:57 +08:00
public static OnPrintHandler OnPrint = delegate { } ;
public delegate void OnPrintHandler ( string tag , object v ) ;
2023-03-27 17:34:12 +08:00
}
2023-03-30 06:03:05 +08:00
2024-10-05 00:25:42 +08:00
//------------------------------------------------------------------------------------------------------------//
2023-03-27 17:34:12 +08:00
public abstract class DebugService
{
private static DebugService _instance ;
2024-09-09 18:21:21 +08:00
private static object _lock = new object ( ) ;
2024-10-05 00:25:42 +08:00
private static HashSet < DebugService > _threadServiceClonesSet = new HashSet < DebugService > ( ) ;
[ThreadStatic]
private static DebugService _currentThreadInstanceClone ;
[ThreadStatic]
private static DebugService _currentThreadInstance ; // для сравнения
private static IdDispenser _idDispenser = new IdDispenser ( 16 , 0 ) ;
private static Dictionary < string , int > _nameIdTable = new Dictionary < string , int > ( ) ;
#region Properties
2024-10-05 10:19:52 +08:00
public static DebugService Instance
{
get { return _instance ; }
}
2024-10-05 00:25:42 +08:00
public static DebugService CurrentThreadInstance
{ // ts завист от Set
2023-06-12 20:46:51 +08:00
get
{
2024-10-05 00:25:42 +08:00
if ( _currentThreadInstance ! = _instance )
2024-02-26 10:56:18 +08:00
{
2024-09-10 19:18:46 +08:00
lock ( _lock )
{
2024-10-05 00:25:42 +08:00
if ( _currentThreadInstance ! = _instance )
{
2024-10-05 10:19:52 +08:00
_currentThreadInstanceClone = _instance . CreateThreadInstance ( ) ;
2024-10-05 00:25:42 +08:00
_threadServiceClonesSet . Add ( _currentThreadInstanceClone ) ;
_currentThreadInstance = _instance ;
foreach ( var record in _nameIdTable )
{
_currentThreadInstanceClone . OnNewProfilerMark ( record . Value , record . Key ) ;
}
}
2024-09-10 19:18:46 +08:00
}
2024-02-26 10:56:18 +08:00
}
2024-10-05 00:25:42 +08:00
return _currentThreadInstanceClone ;
2023-06-12 20:46:51 +08:00
}
}
2024-10-05 00:25:42 +08:00
#endregion
2024-09-13 11:03:51 +08:00
2024-10-05 10:19:52 +08:00
#region Constructors
2024-10-05 00:25:42 +08:00
static DebugService ( )
2024-09-12 03:01:22 +08:00
{
2024-10-05 00:25:42 +08:00
Set ( new DefaultDebugService ( ) ) ;
2024-09-12 03:01:22 +08:00
}
2024-10-05 10:19:52 +08:00
#endregion
2024-09-12 03:01:22 +08:00
2024-10-05 00:25:42 +08:00
#region Set
2024-02-26 10:56:18 +08:00
public static void Set < T > ( ) where T : DebugService , new ( )
2024-10-05 10:19:52 +08:00
{ // ts
2024-09-10 19:18:46 +08:00
lock ( _lock )
{
2024-10-05 00:25:42 +08:00
if ( CurrentThreadInstance is T = = false )
2024-09-12 03:01:22 +08:00
{
Set ( new T ( ) ) ;
}
2024-09-10 19:18:46 +08:00
}
2024-02-26 10:56:18 +08:00
}
2023-03-27 17:34:12 +08:00
public static void Set ( DebugService service )
2024-10-05 00:25:42 +08:00
{ // ts
2024-09-10 19:18:46 +08:00
lock ( _lock )
{
2024-10-05 00:25:42 +08:00
if ( service = = null )
{
service = new NullDebugService ( ) ;
}
2024-09-12 03:01:22 +08:00
if ( _instance ! = service )
{
var oldService = _instance ;
_instance = service ;
2024-10-05 10:19:52 +08:00
foreach ( var record in _nameIdTable )
{
service . OnNewProfilerMark ( record . Value , record . Key ) ;
2024-09-12 03:01:22 +08:00
}
service . OnServiceSetup ( oldService ) ;
OnServiceChanged ( service ) ;
}
2024-09-10 19:18:46 +08:00
}
2023-03-27 17:34:12 +08:00
}
2024-10-05 00:25:42 +08:00
#endregion
2023-03-27 17:34:12 +08:00
2024-10-05 10:19:52 +08:00
#region OnServiceSetup / CreateThreadInstance
2024-10-05 00:25:42 +08:00
protected virtual void OnServiceSetup ( DebugService oldService ) { }
2024-10-05 10:19:52 +08:00
protected abstract DebugService CreateThreadInstance ( ) ;
2024-10-05 00:25:42 +08:00
#endregion
2023-03-27 17:34:12 +08:00
2024-10-05 00:25:42 +08:00
#region Print / Break
2023-03-27 17:34:12 +08:00
public abstract void Print ( string tag , object v ) ;
2023-06-30 00:31:17 +08:00
public abstract void Break ( ) ;
2024-10-05 00:25:42 +08:00
#endregion
#region ProfilerMarkesrs
2023-03-27 17:34:12 +08:00
public int RegisterMark ( string name )
{
int id ;
2024-10-05 00:25:42 +08:00
if ( _nameIdTable . TryGetValue ( name , out id ) = = false )
2023-03-27 17:34:12 +08:00
{
2024-09-09 18:21:21 +08:00
lock ( _lock )
{
2024-10-05 00:25:42 +08:00
if ( _nameIdTable . TryGetValue ( name , out id ) = = false )
2024-09-12 04:05:15 +08:00
{
id = _idDispenser . UseFree ( ) ;
_nameIdTable . Add ( name , id ) ;
2024-10-05 00:25:42 +08:00
foreach ( var service in _threadServiceClonesSet )
{
service . OnNewProfilerMark ( id , name ) ;
}
2024-09-12 04:05:15 +08:00
}
2024-09-09 18:21:21 +08:00
}
2023-03-27 17:34:12 +08:00
}
return id ;
}
public void DeleteMark ( string name )
{
2024-09-10 19:18:46 +08:00
lock ( _lock )
{
int id = _nameIdTable [ name ] ;
2024-09-12 04:05:15 +08:00
_nameIdTable . Remove ( name ) ;
2024-09-10 19:18:46 +08:00
_idDispenser . Release ( id ) ;
2024-10-05 00:25:42 +08:00
foreach ( var service in _threadServiceClonesSet )
{
service . OnNewProfilerMark ( id , name ) ;
}
2024-09-10 19:18:46 +08:00
OnDelProfilerMark ( id ) ;
}
2023-03-27 17:34:12 +08:00
}
2023-06-12 20:30:44 +08:00
protected abstract void OnNewProfilerMark ( int id , string name ) ;
protected abstract void OnDelProfilerMark ( int id ) ;
2023-03-27 17:34:12 +08:00
2023-06-12 20:30:44 +08:00
public abstract void ProfilerMarkBegin ( int id ) ;
public abstract void ProfilerMarkEnd ( int id ) ;
2024-10-05 00:25:42 +08:00
#endregion
#region Utils
protected static string AutoConvertObjectToString ( object o )
{
if ( o is string str )
{
return str ;
}
if ( o is IEnumerable enumerable )
{
return string . Join ( ", " , enumerable . Cast < object > ( ) ) ;
}
return o . ToString ( ) ;
}
public readonly struct MarkerInfo
{
public readonly string Name ;
public readonly int ID ;
public MarkerInfo ( string name , int iD )
{
Name = name ;
ID = iD ;
}
public override string ToString ( ) { return this . AutoToString ( ) ; }
}
#endregion
2024-12-18 16:17:57 +08:00
public static OnServiceChangedHandler OnServiceChanged = delegate { } ;
public delegate void OnServiceChangedHandler ( DebugService service ) ;
2023-03-27 17:34:12 +08:00
}
2024-02-26 10:56:18 +08:00
public static class DebugServiceExtensions
{
public static void PrintWarning ( this DebugService self , object v )
{
2024-10-05 00:25:42 +08:00
self . Print ( DEBUG_WARNING_TAG , v ) ;
2024-02-26 10:56:18 +08:00
}
public static void PrintError ( this DebugService self , object v )
{
2024-10-05 00:25:42 +08:00
self . Print ( DEBUG_ERROR_TAG , v ) ;
2024-02-26 10:56:18 +08:00
}
public static void PrintErrorAndBreak ( this DebugService self , object v )
{
2024-10-05 00:25:42 +08:00
self . Print ( DEBUG_ERROR_TAG , v ) ;
2024-02-26 10:56:18 +08:00
self . Break ( ) ;
}
public static void PrintPass ( this DebugService self , object v )
{
2024-10-05 00:25:42 +08:00
self . Print ( DEBUG_PASS_TAG , v ) ;
2024-02-26 10:56:18 +08:00
}
public static void Print ( this DebugService self , object v )
{
self . Print ( null , v ) ;
}
public static void Print ( this DebugService self )
{
self . Print ( "" ) ;
}
2024-09-08 19:39:43 +08:00
//TODO PrintJson возможно будет добавлено когда-то
2024-02-26 10:56:18 +08:00
}
2024-10-05 00:25:42 +08:00
//------------------------------------------------------------------------------------------------------------//
public sealed class NullDebugService : DebugService
{
2024-10-05 10:19:52 +08:00
protected sealed override DebugService CreateThreadInstance ( ) { return this ; }
2024-10-05 00:25:42 +08:00
public sealed override void Break ( ) { }
public sealed override void Print ( string tag , object v ) { }
public sealed override void ProfilerMarkBegin ( int id ) { }
public sealed override void ProfilerMarkEnd ( int id ) { }
protected sealed override void OnDelProfilerMark ( int id ) { }
protected sealed override void OnNewProfilerMark ( int id , string name ) { }
}
//------------------------------------------------------------------------------------------------------------//
2023-03-27 17:34:12 +08:00
public sealed class DefaultDebugService : DebugService
{
2024-09-30 19:29:19 +08:00
#if ! UNITY_5_3_OR_NEWER
2024-04-27 17:55:44 +08:00
private const string PROFILER_MARKER = "ProfilerMark" ;
2024-09-30 19:29:19 +08:00
private const string PROFILER_MARKER_CACHE = "[" + PROFILER_MARKER + "] " ;
2024-10-05 00:25:42 +08:00
private MarkerData [ ] _stopwatchs = new MarkerData [ 64 ] ;
private char [ ] _buffer = new char [ 128 ] ;
2024-09-12 03:01:22 +08:00
2024-10-05 18:05:33 +08:00
private object _lock = new object ( ) ;
2023-03-27 17:34:12 +08:00
public DefaultDebugService ( )
{
2023-11-22 11:38:28 +08:00
Console . ForegroundColor = ConsoleColor . White ;
Console . BackgroundColor = ConsoleColor . Black ;
2023-03-27 17:34:12 +08:00
}
2024-10-05 10:19:52 +08:00
protected sealed override DebugService CreateThreadInstance ( )
2024-10-05 00:25:42 +08:00
{
return new DefaultDebugService ( ) ;
}
public sealed override void Print ( string tag , object v )
2023-03-27 17:34:12 +08:00
{
2023-11-22 11:28:15 +08:00
if ( string . IsNullOrEmpty ( tag ) )
{
2024-09-13 11:03:51 +08:00
Console . WriteLine ( AutoConvertObjectToString ( v ) ) ;
2023-11-22 11:28:15 +08:00
}
else
{
var color = Console . ForegroundColor ;
switch ( tag )
{
2024-10-04 21:47:15 +08:00
case DEBUG_ERROR_TAG :
2023-11-22 11:28:15 +08:00
Console . ForegroundColor = ConsoleColor . Red ;
break ;
2024-10-04 21:47:15 +08:00
case DEBUG_WARNING_TAG :
2023-11-22 11:28:15 +08:00
Console . ForegroundColor = ConsoleColor . Yellow ;
break ;
2024-10-04 21:47:15 +08:00
case DEBUG_PASS_TAG :
2023-12-31 21:03:00 +08:00
Console . ForegroundColor = ConsoleColor . Green ;
break ;
2023-11-22 11:28:15 +08:00
}
2024-09-13 11:03:51 +08:00
Console . WriteLine ( $"[{tag}] {AutoConvertObjectToString(v)}" ) ;
2023-11-22 11:28:15 +08:00
Console . ForegroundColor = color ;
}
2023-03-27 17:34:12 +08:00
}
2024-10-05 00:25:42 +08:00
public sealed override void Break ( )
2023-06-30 00:31:17 +08:00
{
2024-10-05 18:05:33 +08:00
lock ( _lock )
{
var color = Console . ForegroundColor ;
Console . ForegroundColor = ConsoleColor . Cyan ;
Console . WriteLine ( "Press Enter to с ontinue." ) ;
Console . ForegroundColor = color ;
Console . ReadKey ( ) ;
}
2023-06-30 00:31:17 +08:00
}
2024-04-27 17:55:44 +08:00
2024-10-05 00:25:42 +08:00
public sealed override void ProfilerMarkBegin ( int id )
2023-03-27 17:34:12 +08:00
{
2024-01-29 01:10:05 +08:00
var color = Console . ForegroundColor ;
Console . ForegroundColor = ConsoleColor . DarkGray ;
2024-09-12 03:24:06 +08:00
_stopwatchs [ id ] . Stopwatch . Start ( ) ;
2024-04-27 17:55:44 +08:00
Console . Write ( PROFILER_MARKER_CACHE ) ;
2024-09-12 03:24:06 +08:00
Console . Write ( _stopwatchs [ id ] . Name ) ;
2024-04-27 17:55:44 +08:00
Console . WriteLine ( "> " ) ;
2024-01-29 01:10:05 +08:00
Console . ForegroundColor = color ;
2023-03-27 17:34:12 +08:00
}
2024-10-05 00:25:42 +08:00
public sealed override void ProfilerMarkEnd ( int id )
2023-03-27 17:34:12 +08:00
{
2023-11-22 11:28:15 +08:00
var color = Console . ForegroundColor ;
Console . ForegroundColor = ConsoleColor . DarkGray ;
2024-09-12 03:24:06 +08:00
_stopwatchs [ id ] . Stopwatch . Stop ( ) ;
var time = _stopwatchs [ id ] . Stopwatch . Elapsed ;
_stopwatchs [ id ] . Stopwatch . Reset ( ) ;
2024-04-27 17:55:44 +08:00
Console . Write ( PROFILER_MARKER_CACHE ) ;
Console . Write ( "> " ) ;
2024-09-12 03:24:06 +08:00
Console . Write ( _stopwatchs [ id ] . Name ) ;
2024-04-27 17:55:44 +08:00
Console . Write ( " s:" ) ;
int written = 0 ;
ConvertDoubleToText ( time . TotalSeconds , _buffer , ref written ) ;
Console . WriteLine ( _buffer , 0 , written ) ;
2023-11-22 11:28:15 +08:00
Console . ForegroundColor = color ;
2023-03-27 17:34:12 +08:00
}
2024-04-27 17:55:44 +08:00
2024-10-05 00:25:42 +08:00
protected sealed override void OnDelProfilerMark ( int id )
2023-03-27 17:34:12 +08:00
{
2024-04-27 17:55:44 +08:00
_stopwatchs [ id ] = default ;
2023-03-27 17:34:12 +08:00
}
2024-10-05 00:25:42 +08:00
protected sealed override void OnNewProfilerMark ( int id , string name )
2023-03-27 17:34:12 +08:00
{
2023-03-30 16:39:16 +08:00
if ( id > = _stopwatchs . Length )
{
2024-10-05 00:25:42 +08:00
Array . Resize ( ref _stopwatchs , id < < 1 ) ;
2023-03-30 16:39:16 +08:00
}
2024-10-04 21:47:15 +08:00
_stopwatchs [ id ] = new MarkerData ( new System . Diagnostics . Stopwatch ( ) , name , id ) ;
2024-04-27 17:55:44 +08:00
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-05 00:25:42 +08:00
private static void ConvertDoubleToText ( double value , char [ ] stringBuffer , ref int written )
2024-04-27 17:55:44 +08:00
{
int bufferLength = stringBuffer . Length - 1 ;
decimal decimalValue = ( decimal ) value ;
int intValue = ( int ) decimalValue ;
decimal decimalPartValue = decimalValue - intValue ;
int index = written ;
if ( intValue = = 0 )
{
stringBuffer [ index + + ] = '0' ;
}
else
{
while ( intValue > 0 )
{
int digit = intValue % 10 ;
stringBuffer [ index + + ] = ( char ) ( '0' + digit ) ;
intValue / = 10 ;
}
Array . Reverse ( stringBuffer , 0 , index ) ;
}
if ( decimalPartValue ! = 0 )
{
stringBuffer [ index + + ] = '.' ;
}
int pathBufferLength = bufferLength - index ;
int zeroPartLength = 0 ;
for ( int i = 0 ; i < pathBufferLength ; i + + )
{
decimalPartValue = 10 * decimalPartValue ;
int digit = ( int ) decimalPartValue ;
if ( digit = = 0 )
{
zeroPartLength + + ;
}
else
{
zeroPartLength = 0 ;
}
stringBuffer [ index + + ] = ( char ) ( '0' + digit ) ;
decimalPartValue - = digit ;
}
written = bufferLength - zeroPartLength ;
2023-03-27 17:34:12 +08:00
}
2024-10-05 00:25:42 +08:00
private readonly struct MarkerData
{
public readonly System . Diagnostics . Stopwatch Stopwatch ;
public readonly string Name ;
public readonly int ID ;
public MarkerData ( System . Diagnostics . Stopwatch stopwatch , string name , int id )
{
Stopwatch = stopwatch ;
Name = name ;
ID = id ;
}
public override string ToString ( )
{
return this . AutoToString ( ) ;
}
}
2024-10-04 21:47:15 +08:00
#else
2024-10-05 11:40:01 +08:00
protected sealed override DebugService CreateThreadInstance ( ) { return this ; }
2024-10-05 00:25:42 +08:00
public sealed override void Break ( ) { }
public sealed override void Print ( string tag , object v ) { }
public sealed override void ProfilerMarkBegin ( int id ) { }
public sealed override void ProfilerMarkEnd ( int id ) { }
protected sealed override void OnDelProfilerMark ( int id ) { }
protected sealed override void OnNewProfilerMark ( int id , string name ) { }
2024-10-04 21:47:15 +08:00
#endif
2023-03-27 17:34:12 +08:00
}
}