258 lines
7.4 KiB
C#
258 lines
7.4 KiB
C#
using System;
|
||
using System.Runtime.InteropServices;
|
||
using UnityEngine;
|
||
|
||
namespace TracyProfiler
|
||
{
|
||
/// <summary>
|
||
/// Tracy 性能分析器的 Unity 封装
|
||
/// 提供简单易用的 C# API 来使用 Tracy 性能分析功能
|
||
/// </summary>
|
||
public static class Tracy
|
||
{
|
||
#if UNITY_IOS && !UNITY_EDITOR
|
||
private const string DLL_NAME = "__Internal";
|
||
#else
|
||
private const string DLL_NAME = "UnityTracyPlugin";
|
||
#endif
|
||
|
||
#region Native Methods
|
||
|
||
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
|
||
private static extern void TracyInit();
|
||
|
||
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
|
||
private static extern void TracyShutdown();
|
||
|
||
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
|
||
private static extern void TracyFrameMark();
|
||
|
||
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
|
||
private static extern void TracyPlotValue(string name, double value);
|
||
|
||
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
|
||
private static extern void TracyMessage(string message);
|
||
|
||
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
|
||
private static extern void TracySetThreadName(string name);
|
||
|
||
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
|
||
private static extern void TracyZoneBegin(string name);
|
||
|
||
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
|
||
private static extern void TracyZoneEnd();
|
||
|
||
#endregion
|
||
|
||
private static bool s_initialized = false;
|
||
private static bool s_enabled = true;
|
||
|
||
/// <summary>
|
||
/// Tracy 是否已启用
|
||
/// </summary>
|
||
public static bool Enabled
|
||
{
|
||
get => s_enabled;
|
||
set => s_enabled = value;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Tracy 是否已初始化
|
||
/// </summary>
|
||
public static bool IsInitialized => s_initialized;
|
||
|
||
/// <summary>
|
||
/// 初始化 Tracy
|
||
/// </summary>
|
||
public static void Initialize()
|
||
{
|
||
if (s_initialized) return;
|
||
|
||
try
|
||
{
|
||
#if TRACY_ENABLE || UNITY_EDITOR
|
||
TracyInit();
|
||
s_initialized = true;
|
||
Debug.Log("[Tracy] 性能分析器已初始化");
|
||
#else
|
||
Debug.Log("[Tracy] 性能分析器已禁用(编译时未定义 TRACY_ENABLE)");
|
||
#endif
|
||
}
|
||
catch (DllNotFoundException e)
|
||
{
|
||
Debug.LogWarning($"[Tracy] 未找到 Tracy Plugin DLL: {e.Message}");
|
||
s_enabled = false;
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError($"[Tracy] 初始化失败: {e.Message}");
|
||
s_enabled = false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 关闭 Tracy
|
||
/// </summary>
|
||
public static void Shutdown()
|
||
{
|
||
if (!s_initialized) return;
|
||
|
||
try
|
||
{
|
||
TracyShutdown();
|
||
s_initialized = false;
|
||
Debug.Log("[Tracy] 性能分析器已关闭");
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError($"[Tracy] 关闭失败: {e.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 标记帧边界(通常在每帧末尾调用)
|
||
/// </summary>
|
||
[System.Diagnostics.Conditional("TRACY_ENABLE")]
|
||
public static void MarkFrame()
|
||
{
|
||
if (!s_initialized || !s_enabled) return;
|
||
TracyFrameMark();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 绘制数值(用于实时监控变量)
|
||
/// </summary>
|
||
[System.Diagnostics.Conditional("TRACY_ENABLE")]
|
||
public static void Plot(string name, double value)
|
||
{
|
||
if (!s_initialized || !s_enabled) return;
|
||
TracyPlotValue(name, value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 绘制整数值
|
||
/// </summary>
|
||
[System.Diagnostics.Conditional("TRACY_ENABLE")]
|
||
public static void Plot(string name, int value)
|
||
{
|
||
Plot(name, (double)value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 绘制浮点数值
|
||
/// </summary>
|
||
[System.Diagnostics.Conditional("TRACY_ENABLE")]
|
||
public static void Plot(string name, float value)
|
||
{
|
||
Plot(name, (double)value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发送消息到 Tracy
|
||
/// </summary>
|
||
[System.Diagnostics.Conditional("TRACY_ENABLE")]
|
||
public static void Message(string message)
|
||
{
|
||
if (!s_initialized || !s_enabled) return;
|
||
TracyMessage(message);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置当前线程名称
|
||
/// </summary>
|
||
[System.Diagnostics.Conditional("TRACY_ENABLE")]
|
||
public static void SetThreadName(string name)
|
||
{
|
||
if (!s_initialized || !s_enabled) return;
|
||
TracySetThreadName(name);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Tracy Zone 的作用域包装器
|
||
/// 使用 using 语句自动管理生命周期
|
||
/// </summary>
|
||
public struct ZoneScope : IDisposable
|
||
{
|
||
private bool isValid;
|
||
private string zoneName;
|
||
|
||
public ZoneScope(string name)
|
||
{
|
||
zoneName = name;
|
||
isValid = s_initialized && s_enabled;
|
||
|
||
#if TRACY_ENABLE
|
||
if (isValid)
|
||
{
|
||
TracyZoneBegin(name);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
public void Dispose()
|
||
{
|
||
#if TRACY_ENABLE
|
||
if (isValid && s_initialized && s_enabled)
|
||
{
|
||
TracyZoneEnd();
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建一个 Tracy Zone(性能追踪区域)
|
||
/// 使用 using 语句确保自动结束
|
||
/// </summary>
|
||
/// <example>
|
||
/// using (Tracy.Zone("MyFunction"))
|
||
/// {
|
||
/// // 要追踪的代码
|
||
/// }
|
||
/// </example>
|
||
public static ZoneScope Zone(string name)
|
||
{
|
||
return new ZoneScope(name);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开始一个命名的 Zone
|
||
/// 注意:必须手动调用 EndZone() 结束,推荐使用 Zone() 方法配合 using 语句
|
||
/// </summary>
|
||
[System.Diagnostics.Conditional("TRACY_ENABLE")]
|
||
public static void BeginZone(string name)
|
||
{
|
||
if (!s_initialized || !s_enabled) return;
|
||
TracyZoneBegin(name);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 结束当前 Zone
|
||
/// 注意:必须与 BeginZone() 配对使用
|
||
/// </summary>
|
||
[System.Diagnostics.Conditional("TRACY_ENABLE")]
|
||
public static void EndZone()
|
||
{
|
||
if (!s_initialized || !s_enabled) return;
|
||
TracyZoneEnd();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Tracy Zone 的属性标记版本
|
||
/// 可以标记在方法上,自动追踪整个方法
|
||
/// 注意:需要配合 AOP 或代码生成工具使用
|
||
/// </summary>
|
||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
|
||
public class TracyZoneAttribute : Attribute
|
||
{
|
||
public string Name { get; set; }
|
||
|
||
public TracyZoneAttribute(string name = null)
|
||
{
|
||
Name = name;
|
||
}
|
||
}
|
||
}
|
||
|