Skip to content

Commit

Permalink
Switch DEBUG to flags and initialize DEBUG from config["debug"]
Browse files Browse the repository at this point in the history
"fps": show FPS in console,
"errors": show more info for errors,
default to none
  • Loading branch information
black-sliver committed May 9, 2024
1 parent ac8c490 commit 046bd47
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 11 deletions.
7 changes: 6 additions & 1 deletion doc/PACKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,12 @@ a table representing an enum with the following constants: \

### other globals

* `DEBUG` set to true to get more error or debug output
* `DEBUG` set to true or an array of strings to get more error or debug output
* `false` or `nil`: disable everything
* `true`: enable everything
* `{'fps'}`: enable FPS output in console
* `{'errors'}`: enable more detailed error reporting
* `{'fps', 'errors', ...}`: enable multiple
* `require` function, see [ScriptHost:LoadScript](#global-scripthost)


Expand Down
36 changes: 28 additions & 8 deletions src/core/tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,36 @@ static const char* timeout_error_message = "Execution aborted. Limit reached.";

int Tracker::luaErrorHandler(lua_State *L)
{
// skip trace for certain errors unless running in debug mode (DEBUG == true)
// skip trace for certain errors unless running in debug mode (DEBUG == true or "errors" in DEBUG)
if (lua_isstring(L, -1) && strstr(lua_tostring(L, -1), timeout_error_message)) {
lua_getglobal(L, "DEBUG");
lua_pushboolean(L, true);
if (!lua_compare(L, -1, -2, LUA_OPEQ)) {
// return original error
lua_pop(L, 2);
return 1;
bool skip_trace;
int t = lua_getglobal(L, "DEBUG");
if (t == LUA_TNIL) {
skip_trace = true;
} else if (t == LUA_TTABLE) {
lua_pushnil(L);
skip_trace = true;
while (lua_next(L, -2) != 0) {
if (strcmp(lua_tostring(L, -1), "errors") == 0) {
skip_trace = false;
lua_pop(L, 2); // key, value
break;
}
lua_pop(L, 1); // value
}
} else if (t == LUA_TBOOLEAN) {
lua_pushboolean(L, false);
if (lua_compare(L, -1, -2, LUA_OPEQ))
skip_trace = true;
else
skip_trace = false;
lua_pop(L, 1); // true
} else {
skip_trace = false;
}
lua_pop(L, 2);
lua_pop(L, 1); // DEBUG
if (skip_trace)
return 1; // original error
}
// generate and print trace, then return original error
luaL_traceback(L, L, NULL, 1);
Expand Down
110 changes: 108 additions & 2 deletions src/poptracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,81 @@ enum HotkeyID {
HOTKEY_SHOW_HELP,
};

static char _globalStoreKey = 'k';
static const uintptr_t globalStoreIndex = (uintptr_t)&_globalStoreKey;
static char _globalPopKey = 'k';
static const uintptr_t globalPopIndex = (uintptr_t)&_globalPopKey;

int PopTracker::global_index(lua_State *L)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, (lua_Integer)globalStoreIndex);
lua_pushvalue(L, -2);
lua_rawget(L, -2);
return 1;
}

int PopTracker::global_newindex(lua_State *L)
{
bool toStore = false;
if (lua_isstring(L, -2)) {
// filter out special keys
const char* key = lua_tostring(L, -2);
if (strcmp(key, "DEBUG") == 0) {
lua_rawgeti(L, LUA_REGISTRYINDEX, (lua_Integer)globalPopIndex);
PopTracker* pop = static_cast<PopTracker*>(lua_touserdata(L, -1));
lua_pop(L, 1); // pop
if (!pop) {
luaL_error(L, "Lua state not initialized correctly!");
} else if (lua_isboolean(L, -1) || lua_isnil(L, -1)) {
if (lua_toboolean(L, -1)) {
for (const char* flag: PopTracker::ALL_DEBUG_FLAGS)
pop->_debugFlags.insert(flag);
} else {
pop->_debugFlags.clear();
}
} else if (lua_istable(L, -1)) {
pop->_debugFlags.clear();
lua_pushnil(L);
while (lua_next(L, -2) != 0) {
pop->_debugFlags.insert(lua_tostring(L, -1));
lua_pop(L, 1); // value
}
} else if (lua_isstring(L, -1)) {
pop->_debugFlags.clear();
pop->_debugFlags.insert(lua_tostring(L, -1));
} else {
luaL_error(L, "Invalid assignment to global DEBUG");
}
toStore = true;
}
}
if (toStore) {
// store into separate store so we receive updates
lua_rawgeti(L, LUA_REGISTRYINDEX, (lua_Integer)globalStoreIndex);
lua_insert(L, -3);
lua_rawset(L, -3);
} else {
// store into global object for speed optimization
lua_rawset(L, -3);
}
return 0;
}

void PopTracker::global_wrap(lua_State *L, PopTracker* self)
{
lua_pushglobaltable(L);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, global_index);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, global_newindex);
lua_setfield(L,-2, "__newindex");
lua_setmetatable(L, -2);
lua_pop(L,1);
lua_newtable(L);
lua_rawseti(L, LUA_REGISTRYINDEX, (lua_Integer)globalStoreIndex);
lua_pushlightuserdata(L, self);
lua_rawseti(L, LUA_REGISTRYINDEX, (lua_Integer)globalPopIndex);
}

PopTracker::PopTracker(int argc, char** argv, bool cli, const json& args)
{
Expand Down Expand Up @@ -172,6 +247,21 @@ PopTracker::PopTracker(int argc, char** argv, bool cli, const json& args)
} else if (!_config["override_rule_exec_limit"].is_null())
_config["override_rule_exec_limit"] = nullptr; // clear invalid value

auto debugIt = _config.find("debug");
if (debugIt == _config.end()) {
_config["debug"] = nullptr;
} else if (debugIt.value().is_boolean()) {
if (debugIt.value().get<bool>()) {
for (const char* flag: ALL_DEBUG_FLAGS)
_defaultDebugFlags.insert(flag);
}
} else if (debugIt.value().is_array()) {
try {
_defaultDebugFlags = debugIt.value().get<std::set<std::string>>();
} catch (...) {}
}
_debugFlags = _defaultDebugFlags;

saveConfig();

_ui = nullptr; // UI init moved to start()
Expand Down Expand Up @@ -740,7 +830,8 @@ bool PopTracker::frame()
td = std::chrono::duration_cast<std::chrono::milliseconds>(now - _fpsTimer).count();
if (td >= 5000) {
unsigned f = _frames*1000; f/=td;
printf("FPS:%4u (max %2dms)\n", f, _maxFrameTime);
if (_debugFlags.count("fps") || _maxFrameTime > 1000)
printf("FPS:%4u (max %2dms)\n", f, _maxFrameTime);
_frames = 0;
_fpsTimer = now;
_maxFrameTime = 0;
Expand Down Expand Up @@ -940,6 +1031,8 @@ void PopTracker::unloadTracker()
_scriptHost = nullptr;
_pack = nullptr;
_archipelago = nullptr;

_debugFlags = _defaultDebugFlags;
}

bool PopTracker::loadTracker(const std::string& pack, const std::string& variant, bool loadAutosave)
Expand Down Expand Up @@ -1029,7 +1122,12 @@ bool PopTracker::loadTracker(const std::string& pack, const std::string& variant
lua_pushstring(_L, "Pack");
lua_pushlightuserdata(_L, _pack);
lua_settable(_L, LUA_REGISTRYINDEX);


// store native debug flags set in registry
lua_pushstring(_L, "DebugFlags");
lua_pushlightuserdata(_L, &_debugFlags);
lua_settable(_L, LUA_REGISTRYINDEX);

printf("Creating Script Host...\n");
_scriptHost = new ScriptHost(_pack, _L, _tracker);
printf("Registering in Lua...\n");
Expand Down Expand Up @@ -1095,6 +1193,14 @@ bool PopTracker::loadTracker(const std::string& pack, const std::string& variant
{"Cleared", AccessibilityLevel::CLEARED},
}).Lua_SetGlobal(_L, "AccessibilityLevel");

printf("Hooking Lua globals...\n");
global_wrap(_L, this);
if (_debugFlags.empty())
lua_pushnil(_L);
else
json_to_lua(_L, _debugFlags);
lua_setglobal(_L, "DEBUG");

printf("Updating UI\n");
_win->setTracker(_tracker);
if (auto at = _scriptHost->getAutoTracker()) {
Expand Down
8 changes: 8 additions & 0 deletions src/poptracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class PopTracker final : public App {
std::string _exportDir;
std::string _homePackDir;
std::string _appPackDir;
std::set<std::string> _debugFlags;
std::set<std::string> _defaultDebugFlags;

unsigned _frames = 0;
unsigned _maxFrameTime = 0;
Expand Down Expand Up @@ -75,13 +77,19 @@ class PopTracker final : public App {

bool saveConfig();

static int global_index(lua_State* L);
static int global_newindex(lua_State* L);
static void global_wrap(lua_State* L, PopTracker* self);

public:
PopTracker(int argc, char** argv, bool cli=false, const json& args=nullptr);
virtual ~PopTracker();

bool ListPacks(PackManager::confirmation_callback confirm = nullptr, bool installable = true);
bool InstallPack(const std::string& uid, PackManager::confirmation_callback confirm = nullptr);

static constexpr std::initializer_list<const char*> ALL_DEBUG_FLAGS = {"errors", "fps"};

static constexpr const char APPNAME[] = "PopTracker";
static constexpr const char VERSION_STRING[] = APP_VERSION_STRING;
static const Version VERSION;
Expand Down

0 comments on commit 046bd47

Please sign in to comment.