Files
tracy-for-unity/unity_examples/TracyWrapper.cs

258 lines
7.4 KiB
C#
Raw Normal View History

2025-11-26 14:35:58 +08:00
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;
}
}
}