diff --git a/bindings/lua/CMakeLists.txt b/bindings/lua/CMakeLists.txt index 79bfdc6eb..7e06c036c 100644 --- a/bindings/lua/CMakeLists.txt +++ b/bindings/lua/CMakeLists.txt @@ -13,6 +13,7 @@ set(LUA_BINDINGS_SOURCE "src/cubos.cpp" "src/plugin.cpp" "src/systems.cpp" + "src/logging.cpp" ) # ------------------------ Configure lua bindings target ------------------------- diff --git a/bindings/lua/samples/hello_world/scripts/hello.lua b/bindings/lua/samples/hello_world/scripts/hello.lua index f1a18139c..bc483feb4 100644 --- a/bindings/lua/samples/hello_world/scripts/hello.lua +++ b/bindings/lua/samples/hello_world/scripts/hello.lua @@ -1 +1,5 @@ print("Hello world!") + +cubos.info("hello world", 123, 123.3) +cubos.warn("this is a warning", {}, function() cubos.info("ok") end) +cubos.error("this is an error") diff --git a/bindings/lua/src/cubos.cpp b/bindings/lua/src/cubos.cpp index 9fd3d10ac..4eb70f61f 100644 --- a/bindings/lua/src/cubos.cpp +++ b/bindings/lua/src/cubos.cpp @@ -7,6 +7,7 @@ #include "cubos.hpp" #include "systems.hpp" +#include "logging.hpp" using cubos::engine::Cubos; @@ -25,6 +26,11 @@ void cubos::bindings::lua::injectCubos(lua_State* state, Cubos* cubos) lua_newtable(state); pushFunction(state, "startupSystem", startupSystem); pushFunction(state, "system", system); + + pushFunction(state, "info", logInfo); + pushFunction(state, "warn", logWarn); + pushFunction(state, "error", logError); + lua_setglobal(state, "cubos"); } diff --git a/bindings/lua/src/logging.cpp b/bindings/lua/src/logging.cpp new file mode 100644 index 000000000..228c33637 --- /dev/null +++ b/bindings/lua/src/logging.cpp @@ -0,0 +1,105 @@ +#include "systems.hpp" + +#include +#include + +#include + +using namespace cubos::core::tel; + +static std::string formatArgs(lua_State *state) +{ + std::string str; + int top = lua_gettop(state); + + for (int i = 1; i <= top; i++) + { + int type = lua_type(state, i); + + switch (type) + { + case LUA_TSTRING: + str.append(lua_tostring(state, i)); + break; + case LUA_TNUMBER: { + lua_Number n = lua_tonumber(state, i); + + if (std::floor(n) == n) + { + str.append(std::to_string(static_cast(n))); + } + else + { + str.append(std::to_string(n)); + } + break; + } + case LUA_TBOOLEAN: + str.append(lua_toboolean(state, i) ? "true" : "false"); + break; + case LUA_TNIL: + str.append("nil"); + break; + case LUA_TTABLE: + str.append(""); + break; + case LUA_TFUNCTION: + str.append(""); + break; + case LUA_TUSERDATA: + str.append(""); + break; + case LUA_TLIGHTUSERDATA: + str.append(""); + break; + case LUA_TTHREAD: + str.append(""); + break; + } + + if (i != top) + str.append(" "); + } + + return str; +} + +static void log(lua_State* state, Level logLevel) +{ + std::string formattedArgs = formatArgs(state); + Logger::Location location; + lua_Debug debugInfo; + + if (lua_getstack(state, 1, &debugInfo)) + { + if (lua_getinfo(state, "nSl", &debugInfo)) + { + location.function = debugInfo.name ? debugInfo.name : "undefined"; + location.file = debugInfo.short_src; + location.line = debugInfo.currentline; + + Logger::write(logLevel, location, formattedArgs); + } + } +} + +namespace cubos::bindings::lua +{ + int logInfo(lua_State* state) + { + log(state, Level::Info); + return 0; + }; + + int logWarn(lua_State* state) + { + log(state, Level::Warn); + return 0; + }; + + int logError(lua_State* state) + { + log(state, Level::Error); + return 0; + }; +} // namespace cubos::bindings::lua diff --git a/bindings/lua/src/logging.hpp b/bindings/lua/src/logging.hpp new file mode 100644 index 000000000..cb6cc1547 --- /dev/null +++ b/bindings/lua/src/logging.hpp @@ -0,0 +1,29 @@ +/// @dir +/// @brief @ref lua-bindings-plugin plugin directory. + +/// @file +/// @brief Logging lua api. +/// @ingroup lua-bindings-plugin +#pragma once + +#include + +#include + +namespace cubos::bindings::lua +{ + /// @brief Lua api function to log information. + /// @param state The current lua state. + /// @ingroup lua-bindings-plugin + int logInfo(lua_State* state); + + /// @brief Lua api function to log a warning. + /// @param state The current lua state. + /// @ingroup lua-bindings-plugin + int logWarn(lua_State* state); + + /// @brief Lua api function log an error. + /// @param state The current lua state. + /// @ingroup lua-bindings-plugin + int logError(lua_State* state); +} // namespace cubos::bindings::lua \ No newline at end of file