From f2c16f916a4bcc4c78ae6b8d0ea9a58bb9eb76bc Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 21 May 2018 19:31:19 +0200 Subject: [PATCH] Lua/LuaState: Add error handling methods --- ChangeLog.md | 2 ++ include/Nazara/Lua/LuaCoroutine.hpp | 2 +- include/Nazara/Lua/LuaState.hpp | 14 +++++++---- src/Nazara/Lua/LuaCoroutine.cpp | 2 +- src/Nazara/Lua/LuaState.cpp | 39 ++++++++++++++++++++--------- 5 files changed, 40 insertions(+), 19 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 28800ec0e..7cd448e12 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -101,6 +101,8 @@ Nazara Engine: - Mesh class now has a OnMeshInvalidateAABB signal, triggered when a mesh invalidates its AABB, which is also submesh updates its AABB - Model now invalidate properly their bounding volume when their mesh AABB is updated - Added operator&/|/^ taking an enumeration value and a Flags object using the same enumeration type. +- Added LuaState::CallWithHandler methods, allowing to setup a error handler function +- Added LuaState::Traceback method Nazara Development Kit: - Added ImageWidget (#139) diff --git a/include/Nazara/Lua/LuaCoroutine.hpp b/include/Nazara/Lua/LuaCoroutine.hpp index cdda83b3a..753aa8a4f 100644 --- a/include/Nazara/Lua/LuaCoroutine.hpp +++ b/include/Nazara/Lua/LuaCoroutine.hpp @@ -31,7 +31,7 @@ namespace Nz private: LuaCoroutine(lua_State* internalState, int refIndex); - bool Run(int argCount, int resultCount) override; + bool Run(int argCount, int resultCount, int errHandler) override; int m_ref; }; diff --git a/include/Nazara/Lua/LuaState.hpp b/include/Nazara/Lua/LuaState.hpp index 5774933a4..67640925a 100644 --- a/include/Nazara/Lua/LuaState.hpp +++ b/include/Nazara/Lua/LuaState.hpp @@ -43,6 +43,8 @@ namespace Nz bool Call(unsigned int argCount); bool Call(unsigned int argCount, unsigned int resultCount); + bool CallWithHandler(unsigned int argCount, int errorHandler); + bool CallWithHandler(unsigned int argCount, unsigned int resultCount, int errorHandler); template T Check(int* index) const; template T Check(int* index, T defValue) const; @@ -84,10 +86,10 @@ namespace Nz void Error(const char* message) const; void Error(const String& message) const; - bool Execute(const String& code); - bool ExecuteFromFile(const String& filePath); - bool ExecuteFromMemory(const void* data, std::size_t size); - bool ExecuteFromStream(Stream& stream); + bool Execute(const String& code, int errorHandler = 0); + bool ExecuteFromFile(const String& filePath, int errorHandler = 0); + bool ExecuteFromMemory(const void* data, std::size_t size, int errorHandler = 0); + bool ExecuteFromStream(Stream& stream, int errorHandler = 0); int GetAbsIndex(int index) const; LuaType GetField(const char* fieldName, int tableIndex = -1) const; @@ -178,6 +180,8 @@ namespace Nz void* ToUserdata(int index, const char* tname) const; void* ToUserdata(int index, const String& tname) const; + void Traceback(const char* message = nullptr, int level = 0); + LuaState& operator=(const LuaState&) = default; LuaState& operator=(LuaState&& instance) = default; @@ -190,7 +194,7 @@ namespace Nz template std::enable_if_t::value, T> CheckBounds(int index, long long value) const; template std::enable_if_t::value, T> CheckBounds(int index, long long value) const; - virtual bool Run(int argCount, int resultCount); + virtual bool Run(int argCount, int resultCount, int errHandler); static int ProxyFunc(lua_State* internalState); diff --git a/src/Nazara/Lua/LuaCoroutine.cpp b/src/Nazara/Lua/LuaCoroutine.cpp index bccf8d7fc..ad3f40736 100644 --- a/src/Nazara/Lua/LuaCoroutine.cpp +++ b/src/Nazara/Lua/LuaCoroutine.cpp @@ -47,7 +47,7 @@ namespace Nz } } - bool LuaCoroutine::Run(int argCount, int /*resultCount*/) + bool LuaCoroutine::Run(int argCount, int /*resultCount*/, int /*errHandler*/) { return Resume(argCount) != Ternary_False; } diff --git a/src/Nazara/Lua/LuaState.cpp b/src/Nazara/Lua/LuaState.cpp index e9b18eaef..2e4dd78ea 100644 --- a/src/Nazara/Lua/LuaState.cpp +++ b/src/Nazara/Lua/LuaState.cpp @@ -144,12 +144,22 @@ namespace Nz bool LuaState::Call(unsigned int argCount) { - return Run(argCount, LUA_MULTRET); + return Run(argCount, LUA_MULTRET, 0); } bool LuaState::Call(unsigned int argCount, unsigned int resultCount) { - return Run(argCount, resultCount); + return Run(argCount, resultCount, 0); + } + + bool LuaState::CallWithHandler(int errorHandler, unsigned int argCount) + { + return Run(argCount, LUA_MULTRET, errorHandler); + } + + bool LuaState::CallWithHandler(int errorHandler, unsigned int argCount, unsigned int resultCount) + { + return Run(argCount, resultCount, errorHandler); } void LuaState::CheckAny(int index) const @@ -350,7 +360,7 @@ namespace Nz luaL_error(m_state, message.GetConstBuffer()); } - bool LuaState::Execute(const String& code) + bool LuaState::Execute(const String& code, int errorHandler) { if (code.IsEmpty()) return true; @@ -358,29 +368,29 @@ namespace Nz if (!Load(code)) return false; - return Call(0); + return CallWithHandler(errorHandler, 0); } - bool LuaState::ExecuteFromFile(const String& filePath) + bool LuaState::ExecuteFromFile(const String& filePath, int errorHandler) { if (!LoadFromFile(filePath)) return false; - return Call(0); + return CallWithHandler(errorHandler, 0); } - bool LuaState::ExecuteFromMemory(const void* data, std::size_t size) + bool LuaState::ExecuteFromMemory(const void* data, std::size_t size, int errorHandler) { MemoryView stream(data, size); - return ExecuteFromStream(stream); + return ExecuteFromStream(stream, errorHandler); } - bool LuaState::ExecuteFromStream(Stream& stream) + bool LuaState::ExecuteFromStream(Stream& stream, int errorHandler) { if (!LoadFromStream(stream)) return false; - return Call(0); + return CallWithHandler(errorHandler, 0); } int LuaState::GetAbsIndex(int index) const @@ -809,14 +819,19 @@ namespace Nz return luaL_testudata(m_state, index, tname.GetConstBuffer()); } - bool LuaState::Run(int argCount, int resultCount) + void LuaState::Traceback(const char* message, int level) + { + luaL_traceback(m_state, m_state, message, level); + } + + bool LuaState::Run(int argCount, int resultCount, int errHandler) { LuaInstance& instance = GetInstance(m_state); if (instance.m_level++ == 0) instance.m_clock.Restart(); - int status = lua_pcall(m_state, argCount, resultCount, 0); + int status = lua_pcall(m_state, argCount, resultCount, errHandler); instance.m_level--;