From 64b94f9661bde4bcd34c3ba3f605fdc504c404f7 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Mon, 16 Oct 2023 00:41:41 +0100 Subject: [PATCH] lua: add log{Verbose,Debug,Warn,Error} --- Source/utils/lua.cpp | 78 ++++++++++++++++++++++++++-- Source/utils/sdl2_to_1_2_backports.h | 1 + 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/Source/utils/lua.cpp b/Source/utils/lua.cpp index 043fca442..0b2605c88 100644 --- a/Source/utils/lua.cpp +++ b/Source/utils/lua.cpp @@ -3,6 +3,8 @@ #include #include +#include +#include #include #include @@ -67,10 +69,72 @@ void RunScript(std::string_view path) CheckResult(luaState->safe_script(luaScriptStr)); } -void LuaPanic(sol::optional maybe_msg) +void LuaPanic(sol::optional message) { LogError("Lua is in a panic state and will now abort() the application:\n", - maybe_msg.value_or("unknown error")); + message.value_or("unknown error")); +} + +void LuaLogMessage(LogPriority priority, std::string_view fmt, sol::variadic_args args) +{ + std::string formatted; + FMT_TRY + { + fmt::dynamic_format_arg_store store; + for (const sol::stack_proxy arg : args) { + switch (arg.get_type()) { + case sol::type::boolean: + store.push_back(arg.as()); + break; + case sol::type::number: + if (lua_isinteger(arg.lua_state(), arg.stack_index())) { + store.push_back(lua_tointeger(arg.lua_state(), arg.stack_index())); + } else { + store.push_back(lua_tonumber(arg.lua_state(), arg.stack_index())); + } + break; + case sol::type::string: + store.push_back(arg.as()); + break; + default: + store.push_back(sol::utility::to_string(sol::stack_object(arg))); + break; + } + } + formatted = fmt::vformat(fmt, store); + } + FMT_CATCH(const fmt::format_error &e) + { +#if FMT_EXCEPTIONS + // e.what() is undefined if exceptions are disabled, so we wrap the whole block + // with an `FMT_EXCEPTIONS` check. + std::string error = StrCat("Format error, fmt: ", fmt, " error: ", e.what()); + SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "%s", error.c_str()); + return; +#endif + } + SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, static_cast(priority), "%s", formatted.c_str()); +} + +void LuaLog(std::string_view fmt, sol::variadic_args args) +{ + LuaLogMessage(LogPriority::Info, fmt, std::move(args)); +} +void LuaLogVerbose(std::string_view fmt, sol::variadic_args args) +{ + LuaLogMessage(LogPriority::Verbose, fmt, std::move(args)); +} +void LuaLogDebug(std::string_view fmt, sol::variadic_args args) +{ + LuaLogMessage(LogPriority::Debug, fmt, std::move(args)); +} +void LuaLogWarn(std::string_view fmt, sol::variadic_args args) +{ + LuaLogMessage(LogPriority::Warn, fmt, std::move(args)); +} +void LuaLogError(std::string_view fmt, sol::variadic_args args) +{ + LuaLogMessage(LogPriority::Error, fmt, std::move(args)); } } // namespace @@ -110,10 +174,14 @@ void LuaInitialize() // Registering devilutionx object table lua.create_named_table( "devilutionx", - "message", [](std::string_view text) { EventPlrMsg(text, UiFlags::ColorRed); } + "message", [](std::string_view text) { EventPlrMsg(text, UiFlags::ColorRed); }, // TODO: Re-enable once https://github.com/bebbo/amiga-gcc/issues/363 is fixed. // "drawString", [](std::string_view text, int x, int y) { DrawString(GlobalBackBuffer(), text, { x, y }); } - ); + "log", LuaLog, + "logVerbose", LuaLogVerbose, + "logDebug", LuaLogDebug, + "logWarn", LuaLogWarn, + "logError", LuaLogError); RunScript("lua/init.lua"); RunScript("lua/user.lua"); @@ -150,7 +218,7 @@ tl::expected RunLua(std::string_view code) return tl::make_unexpected("Unknown Lua error"); } - return sol::utility::to_string(sol::object(result)); + return sol::utility::to_string(sol::stack_object(result)); } } // namespace devilution diff --git a/Source/utils/sdl2_to_1_2_backports.h b/Source/utils/sdl2_to_1_2_backports.h index 93a5ac949..a62ab88ae 100644 --- a/Source/utils/sdl2_to_1_2_backports.h +++ b/Source/utils/sdl2_to_1_2_backports.h @@ -89,6 +89,7 @@ void SDL_LogInfo(int category, const char *fmt, ...) DVL_PRINTF_ATTRIBUTE(2, 3); void SDL_LogWarn(int category, const char *fmt, ...) DVL_PRINTF_ATTRIBUTE(2, 3); void SDL_LogError(int category, const char *fmt, ...) DVL_PRINTF_ATTRIBUTE(2, 3); void SDL_LogCritical(int category, const char *fmt, ...) DVL_PRINTF_ATTRIBUTE(2, 3); +void SDL_LogMessage(int category, SDL_LogPriority priority, const char *fmt, ...) DVL_PRINTF_ATTRIBUTE(3, 4); void SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list ap) DVL_PRINTF_ATTRIBUTE(3, 0); void SDL_LogSetAllPriority(SDL_LogPriority priority);