DragonECS/src/DebugUtils/EcsDebug.cs

540 lines
18 KiB
C#
Raw Normal View History

2024-02-14 03:04:05 +08:00
using DCFApixels.DragonECS.Internal;
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;
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;
public readonly struct EcsProfilerMarker
2023-03-30 06:03:05 +08:00
{
2024-09-30 19:29:19 +08:00
#if ((DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_DEBUGGER)
public readonly int id;
2024-09-30 19:29:19 +08:00
#endif
internal EcsProfilerMarker(int id)
{
#if ((DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_DEBUGGER)
this.id = id;
#endif
}
2024-09-12 04:05:15 +08:00
public EcsProfilerMarker(string name)
{
2024-09-30 19:29:19 +08:00
#if ((DEBUG && !DISABLE_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()
{
#if ((DEBUG && !DISABLE_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()
{
#if ((DEBUG && !DISABLE_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()
{
#if ((DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_DEBUGGER)
return new AutoScope(id);
#else
return default;
#endif
}
2023-04-01 20:45:37 +08:00
public readonly ref struct AutoScope
{
2024-09-30 19:29:19 +08:00
#if ((DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_DEBUGGER)
private readonly int _id;
2024-09-30 19:29:19 +08:00
#endif
2024-06-08 02:08:20 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AutoScope(int id)
2023-03-30 06:03:05 +08:00
{
2024-09-30 19:29:19 +08:00
#if ((DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_DEBUGGER)
_id = id;
2024-10-05 00:25:42 +08:00
DebugService.CurrentThreadInstance.ProfilerMarkBegin(id);
2024-09-30 19:29:19 +08:00
#endif
}
2024-06-08 02:08:20 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-02-26 10:56:18 +08:00
public void Dispose()
{
2024-09-30 19:29:19 +08:00
#if ((DEBUG && !DISABLE_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
}
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>().")]
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
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-02-26 10:56:18 +08:00
public static void PrintWarning(object v)
{
2024-04-27 17:55:44 +08:00
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_DEBUGGER
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)
{
2024-04-27 17:55:44 +08:00
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_DEBUGGER
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)
{
2024-04-27 17:55:44 +08:00
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_DEBUGGER
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)
{
2024-04-27 17:55:44 +08:00
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_DEBUGGER
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()
{
2024-04-27 17:55:44 +08:00
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_DEBUGGER
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)
{
2024-04-27 17:55:44 +08:00
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_DEBUGGER
2024-10-05 00:25:42 +08:00
DebugService.CurrentThreadInstance.Print(v);
2023-05-27 15:59:46 +08:00
#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-03-27 17:34:12 +08:00
public static void Print(string tag, object v)
{
2024-04-27 17:55:44 +08:00
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_DEBUGGER
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()
{
2024-04-27 17:55:44 +08:00
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_DEBUGGER
2024-10-05 00:25:42 +08:00
DebugService.CurrentThreadInstance.Break();
2023-06-30 00:32:25 +08:00
#endif
}
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
public static Action<DebugService> OnServiceChanged = delegate { };
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
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
{
2023-11-22 11:28:15 +08:00
var color = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Press Enter to сontinue.");
Console.ReadKey();
Console.ForegroundColor = color;
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
{
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("> ");
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 00:25:42 +08:00
protected sealed override DebugService Clone() { return this; }
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
}
}