diff options
Diffstat (limited to 'source/LuaState.cpp')
-rw-r--r-- | source/LuaState.cpp | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/source/LuaState.cpp b/source/LuaState.cpp new file mode 100644 index 000000000..da86a4b20 --- /dev/null +++ b/source/LuaState.cpp @@ -0,0 +1,218 @@ + +// LuaState.cpp + +// Implements the cLuaState class representing the wrapper over lua_State *, provides associated helper functions + +#include "Globals.h" +#include "LuaState.h" + +extern "C" +{ + #include "lualib.h" +} + +#include "tolua++.h" +#include "Bindings.h" +#include "ManualBindings.h" + +// fwd: SQLite/lsqlite3.c +extern "C" +{ + LUALIB_API int luaopen_lsqlite3(lua_State * L); +} + +// fwd: LuaExpat/lxplib.c: +extern "C" +{ + int luaopen_lxp(lua_State * L); +} + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cLuaState: + +cLuaState::cLuaState(const AString & a_SubsystemName) : + m_LuaState(NULL), + m_SubsystemName(a_SubsystemName) +{ +} + + + + + +cLuaState::~cLuaState() +{ + if (IsValid()) + { + Close(); + } +} + + + + + +void cLuaState::Create(void) +{ + if (m_LuaState != NULL) + { + LOGWARNING("%s: Trying to create an already-existing LuaState, ignoring.", __FUNCTION__); + return; + } + m_LuaState = lua_open(); + luaL_openlibs(m_LuaState); + tolua_AllToLua_open(m_LuaState); + ManualBindings::Bind(m_LuaState); + luaopen_lsqlite3(m_LuaState); + luaopen_lxp(m_LuaState); +} + + + + + +void cLuaState::Close(void) +{ + if (m_LuaState == NULL) + { + LOGWARNING("%s: Trying to close an invalid LuaState, ignoring.", __FUNCTION__); + return; + } + lua_close(m_LuaState); + m_LuaState = NULL; +} + + + + + +bool cLuaState::LoadFile(const AString & a_FileName) +{ + ASSERT(IsValid()); + + // Load the file: + int s = luaL_loadfile(m_LuaState, a_FileName.c_str()); + if (ReportErrors(s)) + { + LOGWARNING("Can't load %s because of an error in file %s", m_SubsystemName.c_str(), a_FileName.c_str()); + return false; + } + + // Execute the globals: + s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0); + if (ReportErrors(s)) + { + LOGWARNING("Error in %s in file %s", m_SubsystemName.c_str(), a_FileName.c_str()); + return false; + } + + return true; +} + + + + + +bool cLuaState::PushFunction(const char * a_FunctionName, bool a_ShouldLogFailure /* = true */) +{ + if (!IsValid()) + { + // This happens if cPlugin::Initialize() fails with an error + return false; + } + + lua_getglobal(m_LuaState, a_FunctionName); + if (!lua_isfunction(m_LuaState, -1)) + { + if (a_ShouldLogFailure) + { + LOGWARNING("Error in %s: Could not find function %s()", m_SubsystemName.c_str(), a_FunctionName); + } + lua_pop(m_LuaState, 1); + return false; + } + return true; +} + + + + + +bool cLuaState::PushFunctionFromRegistry(int a_FnRef) +{ + lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // same as lua_getref() + if (!lua_isfunction(m_LuaState, -1)) + { + lua_pop(m_LuaState, 1); + return false; + } + return true; +} + + + + + +void cLuaState::PushStringVector(const AStringVector & a_Vector) +{ + lua_createtable(m_LuaState, a_Vector.size(), 0); + int newTable = lua_gettop(m_LuaState); + int index = 1; + for (AStringVector::const_iterator itr = a_Vector.begin(), end = a_Vector.end(); itr != end; ++itr, ++index) + { + tolua_pushstring(m_LuaState, itr->c_str()); + lua_rawseti(m_LuaState, newTable, index); + } +} + + + + + +bool cLuaState::CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName) +{ + ASSERT(lua_isfunction(m_LuaState, -a_NumArgs - 1)); + + int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0); + if (ReportErrors(s)) + { + LOGWARNING("Error in %s calling function %s()", m_SubsystemName.c_str(), a_FunctionName); + return false; + } + return true; +} + + + + + +bool cLuaState::ReportErrors(int a_Status) +{ + return ReportErrors(m_LuaState, a_Status); +} + + + + + +bool cLuaState::ReportErrors(lua_State * a_LuaState, int a_Status) +{ + if (a_Status == 0) + { + // No error to report + return false; + } + + LOGWARNING("LUA: %d - %s", a_Status, lua_tostring(a_LuaState, -1)); + lua_pop(a_LuaState, 1); + return true; +} + + + + |