Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tracy.LuaTracyPlot and tracy.LuaTracyPlotConfig #1651

Merged
merged 1 commit into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions rts/Lua/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ set(sources_engine_Lua
"${CMAKE_CURRENT_SOURCE_DIR}/LuaSyncedTable.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/LuaTableExtra.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/LuaTextures.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/LuaTracyExtra.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/LuaAtlasTextures.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/LuaUI.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/LuaUICommand.cpp"
Expand Down
8 changes: 7 additions & 1 deletion rts/Lua/LuaHandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "LuaBitOps.h"
#include "LuaMathExtra.h"
#include "LuaTableExtra.h"
#include "LuaTracyExtra.h"
#include "LuaUtils.h"
#include "LuaZip.h"
#include "Game/Game.h"
Expand Down Expand Up @@ -149,6 +150,11 @@ CLuaHandle::CLuaHandle(const string& _name, int _order, bool _userMode, bool _sy

// register tracy functions in global scope
tracy::LuaRegister(L);
#ifdef TRACY_ENABLE
lua_getglobal(L, "tracy");
LuaTracyExtra::PushEntries(L);
lua_pop(L, 1);
#endif
}


Expand Down Expand Up @@ -498,7 +504,7 @@ bool CLuaHandle::LoadCode(lua_State* L, std::string code, const string& debug)

const LuaUtils::ScopedDebugTraceBack traceBack(L);

tracy::LuaRemove(code.data());
LuaUtils::TracyRemoveAlsoExtras(code.data());
const int error = luaL_loadbuffer(L, code.c_str(), code.size(), debug.c_str());

if (error != 0) {
Expand Down
4 changes: 2 additions & 2 deletions rts/Lua/LuaParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ bool LuaParser::Execute()
char errorBuf[4096] = {0};
int errorNum = 0;

tracy::LuaRemove(code.data());
LuaUtils::TracyRemoveAlsoExtras(code.data());
if ((errorNum = luaL_loadbuffer(L, code.c_str(), code.size(), codeLabel.c_str())) != 0) {
SNPRINTF(errorBuf, sizeof(errorBuf), "[loadbuf] error %d (\"%s\") in %s", errorNum, lua_tostring(L, -1), codeLabel.c_str());
LUA_CLOSE(&L);
Expand Down Expand Up @@ -643,7 +643,7 @@ int LuaParser::Include(lua_State* L)
lua_error(L);
}

tracy::LuaRemove(code.data());
LuaUtils::TracyRemoveAlsoExtras(code.data());
int error = luaL_loadbuffer(L, code.c_str(), code.size(), filename.c_str());
if (error != 0) {
char buf[1024];
Expand Down
90 changes: 90 additions & 0 deletions rts/Lua/LuaTracyExtra.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* This file is part of the Recoil engine (GPL v2 or later). */

#include "LuaTracyExtra.h"

#include "LuaInclude.h"
#include "LuaUtils.h"

#include "System/Misc/TracyDefs.h"
#include <common/TracyQueue.hpp>
p2004a marked this conversation as resolved.
Show resolved Hide resolved

#include <functional>
#include <set>
#include <string>

/* Tracy seems to want unique, unchanging strings to be passed to
* its API, so we need to immanentize the ephemeral Lua strings
* by storing them.
*
* NB: strings here are never really cleaned up, but the use case assumes
* that they live a long time and there's just a handful of them. */
static std::set <std::string, std::less<>> tracyLuaPlots;

static const std::string& GetImmanentPlotName(const char *plotName)
{
const auto plot = tracyLuaPlots.find(plotName);
if (plot != tracyLuaPlots.end())
return *plot;

return *tracyLuaPlots.emplace(plotName).first;
}

/*** Configure custom appearance for a Tracy plot for use in debugging or profiling
*
* @function tracy.LuaTracyPlotConfig
* @string plotName name of the plot to customize
* @string[opt="Number"] plotFormatType "Number"|"Percentage"|"Memory"
* @bool[opt=true] stepwise stepwise chart
* @bool[opt=false] fill whether to fill color
* @number[opt=0xFFFFFF] color uint32 number as BGR color
* @treturn nil
*/

static int LuaTracyPlotConfig(lua_State* L)
{
const auto plotName = luaL_checkstring(L, 1);
const auto plotFormatTypeString = luaL_optstring(L, 2, "");
const auto stepwise = luaL_optboolean(L, 3, true);
const auto fill = luaL_optboolean(L, 4, false);
const uint32_t color = luaL_optint(L, 5, 0xFFFFFF); // white

tracy::PlotFormatType plotFormatType;
switch (plotFormatTypeString[0]) {
case 'p': case 'P': plotFormatType = tracy::PlotFormatType::Percentage; break;
case 'm': case 'M': plotFormatType = tracy::PlotFormatType::Memory; break;
default: plotFormatType = tracy::PlotFormatType::Number; break;
}

TracyPlotConfig(GetImmanentPlotName(plotName).c_str(), plotFormatType, stepwise, fill, color);
return 0;
}


/*** Update a Tracy plot with a value
*
* @function tracy.LuaTracyPlot
* @string plotName which LuaPlot should be updated
* @number plotValue the number to show on the Tracy plot
* @treturn nil
*/
static int LuaTracyPlot(lua_State* L)
{
const auto plotName = luaL_checkstring(L, 1);
const auto plotValue = luaL_checkfloat (L, 2);

TracyPlot(GetImmanentPlotName(plotName).c_str(), plotValue);
return 0;
}

/******************************************************************************
* tracy extensions
* @module TracyExtra
* @see rts/Lua/LuaTracyExtra.cpp
******************************************************************************/

bool LuaTracyExtra::PushEntries(lua_State* L)
{
LuaPushNamedCFunc(L, "LuaTracyPlot" , LuaTracyPlot );
LuaPushNamedCFunc(L, "LuaTracyPlotConfig", LuaTracyPlotConfig);
return true;
}
9 changes: 9 additions & 0 deletions rts/Lua/LuaTracyExtra.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* This file is part of the Recoil engine (GPL v2 or later), see LICENSE.html */

#pragma once

struct lua_State;

namespace LuaTracyExtra {
bool PushEntries(lua_State* L);
};
47 changes: 47 additions & 0 deletions rts/Lua/LuaUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define SCOPED_TIMER(x)
#endif

#include <tracy/TracyLua.hpp>

static const int maxDepth = 16;

Expand Down Expand Up @@ -1821,3 +1822,49 @@ void LuaUtils::PushAttackerInfo(lua_State* L, const CUnit* const attacker)
lua_pushnil(L);
}
#endif


void LuaUtils::TracyRemoveAlsoExtras(char* script)
{
// tracy's built-in remover; does not handle our local TracyExtra functions
tracy::LuaRemove(script);

#ifndef TRACY_ENABLE
// Our extras are handled manually below, the same way Tracy does.
// Code is on BSD-3 licence, (c) 2017 Bartosz Taudul aka wolfpld

const auto FindEnd = [] (char *ptr) {
unsigned int cnt = 1;
while (cnt) {
if (*ptr == '(') ++ cnt;
else if (*ptr == ')') -- cnt;
++ ptr;
}
return ptr;
};

const auto Wipe = [&script, FindEnd] (size_t offset) {
const auto end = FindEnd(script + offset);
memset(script, ' ', end - script);
script = end;
};

while (*script) {
if (strncmp(script, "tracy.LuaTracyPlot", 18)) {
++ script;
continue;
}

/* The numbers are (sub)string lengths. Perhaps there could be
* system to magically generate optimal searches from a set of
* strings with long common prefixes, but for now it's manual.
* Keep upstreamability in mind though (that's why strcmp). */
if (!strncmp(script + 18, "Config(", 7))
Wipe(18 + 7);
else if (!strncmp(script + 18, "(", 1))
saurtron marked this conversation as resolved.
Show resolved Hide resolved
Wipe(18 + 1);
else
script += 18;
}
#endif
}
2 changes: 2 additions & 0 deletions rts/Lua/LuaUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ class LuaUtils {
static const TObj* IdToObject(int id, const char* func = nullptr);
template<typename TObj>
static const TObj* SolIdToObject(int id, const char* func = nullptr);

static void TracyRemoveAlsoExtras(char *script);
};


Expand Down
3 changes: 2 additions & 1 deletion rts/Lua/LuaVFS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ int LuaVFS::Include(lua_State* L, bool synced)
lua_error(L);
}

tracy::LuaRemove(fileData.data());
LuaUtils::TracyRemoveAlsoExtras(fileData.data());
if ((luaError = luaL_loadbuffer(L, fileData.c_str(), fileData.size(), fileName.c_str())) != 0) {
const auto buf = fmt::format("[LuaVFS::{}(synced={})][loadbuf] file={} error={} ({}) cenv={} vfsmode={}", __func__, synced, fileName, luaError, lua_tostring(L, -1), hasCustomEnv, mode);
lua_pushlstring(L, buf.c_str(), buf.size());
Expand Down Expand Up @@ -229,6 +229,7 @@ int LuaVFS::LoadFile(lua_State* L, bool synced)

string data;
if (LoadFileWithModes(filename, data, GetModes(L, 2, synced)) == 1) {
LuaUtils::TracyRemoveAlsoExtras(data.data());
lua_pushsstring(L, data);
return 1;
}
Expand Down