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

288 lines
7.2 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.

/*
* Tracy Unity Plugin - 简化版实现
*
* 这是一个简化的 Tracy Unity Plugin 实现
* 用于演示如何将 Tracy 集成到 Unity Native Plugin 中
*
* 编译说明:
* Windows: cl /LD /MD SimplifiedPlugin.cpp /I"path/to/tracy/public" ws2_32.lib dbghelp.lib
* macOS: clang++ -shared -fPIC SimplifiedPlugin.cpp -I"path/to/tracy/public" -o libUnityTracyPlugin.dylib
* Linux: g++ -shared -fPIC SimplifiedPlugin.cpp -I"path/to/tracy/public" -o libUnityTracyPlugin.so -lpthread -ldl
*/
// 定义 Tracy 启用标志
#define TRACY_ENABLE
#define TRACY_ON_DEMAND
#include "tracy/Tracy.hpp"
#include <string>
#include <cstring>
// 平台特定的导出定义
#if defined(_WIN32) || defined(_WIN64)
#define UNITY_PLUGIN_EXPORT __declspec(dllexport)
#elif defined(__APPLE__) || defined(__linux__)
#define UNITY_PLUGIN_EXPORT __attribute__((visibility("default")))
#else
#define UNITY_PLUGIN_EXPORT
#endif
// C 导出函数Unity 需要 C 链接)
extern "C" {
/**
* 初始化 Tracy
* Unity C# 调用: [DllImport] private static extern void TracyInit();
*/
UNITY_PLUGIN_EXPORT void TracyInit()
{
// Tracy 会自动初始化,这里可以添加额外的初始化逻辑
// 例如:设置采样率、配置选项等
}
/**
* 关闭 Tracy
* Unity C# 调用: [DllImport] private static extern void TracyShutdown();
*/
UNITY_PLUGIN_EXPORT void TracyShutdown()
{
// Tracy 会在程序退出时自动清理
// 这里可以添加自定义的清理逻辑
}
/**
* 标记帧边界
* Unity C# 调用: [DllImport] private static extern void TracyFrameMark();
*/
UNITY_PLUGIN_EXPORT void TracyFrameMark()
{
FrameMark;
}
/**
* 绘制数值
* Unity C# 调用: [DllImport] private static extern void TracyPlotValue(string name, double value);
*/
UNITY_PLUGIN_EXPORT void TracyPlotValue(const char* name, double value)
{
if (name != nullptr)
{
TracyPlot(name, value);
}
}
/**
* 发送消息
* Unity C# 调用: [DllImport] private static extern void TracyMessage(string message);
*/
UNITY_PLUGIN_EXPORT void TracyMessage(const char* message)
{
if (message != nullptr)
{
TracyMessage(message, std::strlen(message));
}
}
/**
* 设置线程名称
* Unity C# 调用: [DllImport] private static extern void TracySetThreadName(string name);
*/
UNITY_PLUGIN_EXPORT void TracySetThreadName(const char* name)
{
if (name != nullptr)
{
tracy::SetThreadName(name);
}
}
/**
* 开始一个命名的 Zone
* Unity C# 调用: [DllImport] private static extern void TracyZoneBegin(string name);
*
* 注意: 这是简化版实现,实际使用中需要更复杂的 Zone 管理
*/
UNITY_PLUGIN_EXPORT void TracyZoneBegin(const char* name)
{
if (name != nullptr)
{
// 简化版: 使用动态分配的 Zone
// 实际应用中需要管理 Zone 的生命周期
// 方案1: 使用全局 Zone 栈(简单但不支持多线程)
// 方案2: 使用线程局部存储(复杂但支持多线程)
// 方案3: 返回 Zone ID 给 C#,让 C# 管理(推荐)
// 这里使用宏创建一个 Zone
// 注意:这只是示例,实际使用需要更好的管理方式
ZoneName(name, std::strlen(name));
}
}
/**
* 结束当前 Zone
* Unity C# 调用: [DllImport] private static extern void TracyZoneEnd();
*/
UNITY_PLUGIN_EXPORT void TracyZoneEnd()
{
// 简化版: 与 ZoneBegin 配对使用
// 实际应用中需要管理 Zone 的结束
}
/**
* Unity 插件生命周期函数 - 加载时调用
*/
UNITY_PLUGIN_EXPORT void UnityPluginLoad()
{
// 可选:在插件加载时执行初始化
}
/**
* Unity 插件生命周期函数 - 卸载时调用
*/
UNITY_PLUGIN_EXPORT void UnityPluginUnload()
{
// 可选:在插件卸载时执行清理
}
} // extern "C"
/*
* 高级实现示例 - Zone 管理
*
* 下面是一个更完善的 Zone 管理实现示例
* 可以根据需要扩展
*/
#ifdef ADVANCED_ZONE_MANAGEMENT
#include <unordered_map>
#include <stack>
#include <mutex>
// Zone 管理器(线程安全)
class ZoneManager
{
private:
struct ThreadZones
{
std::stack<tracy::ScopedZone*> zones;
};
std::unordered_map<std::thread::id, ThreadZones> threadZones;
std::mutex mutex;
public:
void BeginZone(const char* name, const char* function, const char* file, uint32_t line)
{
std::lock_guard<std::mutex> lock(mutex);
auto threadId = std::this_thread::get_id();
auto& zones = threadZones[threadId].zones;
// 创建源位置信息
static const tracy::SourceLocationData loc{name, function, file, line, 0};
// 创建 Zone注意需要在堆上分配
auto* zone = new tracy::ScopedZone(&loc, true);
zones.push(zone);
}
void EndZone()
{
std::lock_guard<std::mutex> lock(mutex);
auto threadId = std::this_thread::get_id();
auto it = threadZones.find(threadId);
if (it != threadZones.end() && !it->second.zones.empty())
{
auto* zone = it->second.zones.top();
it->second.zones.pop();
delete zone;
}
}
void ClearThread()
{
std::lock_guard<std::mutex> lock(mutex);
auto threadId = std::this_thread::get_id();
auto it = threadZones.find(threadId);
if (it != threadZones.end())
{
// 清理所有未结束的 Zone
while (!it->second.zones.empty())
{
delete it->second.zones.top();
it->second.zones.pop();
}
threadZones.erase(it);
}
}
};
// 全局 Zone 管理器实例
static ZoneManager g_zoneManager;
extern "C" {
UNITY_PLUGIN_EXPORT void TracyZoneBeginAdvanced(const char* name, const char* function, const char* file, int line)
{
g_zoneManager.BeginZone(name, function, file, static_cast<uint32_t>(line));
}
UNITY_PLUGIN_EXPORT void TracyZoneEndAdvanced()
{
g_zoneManager.EndZone();
}
UNITY_PLUGIN_EXPORT void TracyClearThreadZones()
{
g_zoneManager.ClearThread();
}
} // extern "C"
#endif // ADVANCED_ZONE_MANAGEMENT
/*
* 编译和部署说明:
*
* 1. Windows (Visual Studio):
* - 创建 DLL 项目
* - 添加 Tracy 源文件: tracy/public/TracyClient.cpp
* - 包含目录: tracy/public
* - 链接库: ws2_32.lib dbghelp.lib
* - 输出: UnityTracyPlugin.dll
*
* 2. macOS:
* clang++ -std=c++17 -shared -fPIC \
* SimplifiedPlugin.cpp \
* tracy/public/TracyClient.cpp \
* -I tracy/public \
* -DTRACY_ENABLE -DTRACY_ON_DEMAND \
* -o libUnityTracyPlugin.dylib
*
* 3. Linux:
* g++ -std=c++17 -shared -fPIC \
* SimplifiedPlugin.cpp \
* tracy/public/TracyClient.cpp \
* -I tracy/public \
* -DTRACY_ENABLE -DTRACY_ON_DEMAND \
* -lpthread -ldl \
* -o libUnityTracyPlugin.so
*
* 4. Android (NDK):
* 在 Android.mk 或 CMakeLists.txt 中配置
*
* 5. iOS:
* 使用 Xcode 编译为静态库 (.a)
*
* 部署到 Unity:
* - 将编译好的库文件复制到 Unity 项目的 Assets/Plugins/ 目录
* - 根据平台放置在相应的子目录中
* - 配置 Plugin Import Settings 以匹配目标平台
*/