Skip to content

Commit

Permalink
Add tracy.LuaTracyPlot and tracy.LuaTracyPlotConfig (#1651)
Browse files Browse the repository at this point in the history
Co-authored-by: Beherith <mysterme@gmail.com>
  • Loading branch information
sprunk and Beherith authored Dec 23, 2024
1 parent 29edeb1 commit 6760620
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 4 deletions.
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>

#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))
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

0 comments on commit 6760620

Please sign in to comment.