Files
tracy-for-unity/unity_examples/TracyWrapper.cs
2025-11-26 14:35:58 +08:00

258 lines
7.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}