diff options
author | Dominick Allen <djallen@librehumanitas.org> | 2024-09-30 00:36:19 -0500 |
---|---|---|
committer | Dominick Allen <djallen@librehumanitas.org> | 2024-09-30 00:36:19 -0500 |
commit | 6f2b61b676a16482fdac70a58a8e875c4d68e713 (patch) | |
tree | e2f8b2376847b5b13b278572c0fae8a6bc4d0e82 /src/luacxx.cpp | |
parent | dacd752bbf46f2afb08b4b8d730ba3619528dda4 (diff) |
Add configuration handling.
Diffstat (limited to 'src/luacxx.cpp')
-rw-r--r-- | src/luacxx.cpp | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/src/luacxx.cpp b/src/luacxx.cpp new file mode 100644 index 0000000..926e30f --- /dev/null +++ b/src/luacxx.cpp @@ -0,0 +1,142 @@ +#include "luacxx.hpp" + +extern "C" { +#include <lauxlib.h> +#include <lualib.h> +} + +namespace getsuyomi { + +using fud::FudStatus; + +LuaContext::LuaContext() +{ + m_state = luaL_newstate(); + if (m_state != nullptr) { + luaL_openlibs(m_state); + } +} + +LuaContext::~LuaContext() +{ + if (m_state != nullptr) { + lua_close(m_state); + m_state = nullptr; + } +} + +LuaContext::LuaContext(LuaContext&& rhs) : m_state{rhs.m_state} +{ + rhs.m_state = nullptr; +} + +LuaContext& LuaContext::operator=(LuaContext&& rhs) +{ + m_state = rhs.m_state; + rhs.m_state = nullptr; + return *this; +} + +FudStatus LuaContext::loadFile(const char* filename) +{ + if (!valid()) + { + return FudStatus::ObjectInvalid; + } + if (luaL_loadfile(m_state, filename) || lua_pcall(m_state, 0, 0, 0)) { + return FudStatus::Failure; + } + return FudStatus::Success; +} + +LuaResult<int64_t> LuaContext::getGlobalInteger(const char* name) +{ + if (m_state == nullptr) { + return LuaResult<int64_t>::error(FudStatus::ObjectInvalid); + } + + int isNumber{}; + int64_t result{}; + + auto luaType = lua_getglobal(m_state, name); + // discard luaType since isNumber will check if variable is integral + static_cast<void>(luaType); + + result = lua_tointegerx(m_state, -1, &isNumber); + + lua_pop(m_state, 1); + + if (!static_cast<bool>(isNumber)) { + return LuaResult<int64_t>::error(FudStatus::Failure); + } + return LuaResult<int64_t>::okay(result); +} + +LuaResult<const char*> LuaContext::getGlobalString(const char* name) +{ + if (m_state == nullptr) { + return LuaResult<const char*>::error(FudStatus::ObjectInvalid); + } + + size_t length; + const char* result{nullptr}; + + auto luaType = lua_getglobal(m_state, name); + static_cast<void>(luaType); + + result = lua_tolstring(m_state, -1, &length); + + lua_pop(m_state, 1); + + if (result == nullptr) { + return LuaResult<const char*>::error(FudStatus::Failure); + } + return LuaResult<const char*>::okay(result); +} + +LuaResult<std::vector<std::string>> LuaContext::getGlobalStringArray(const char* name) +{ + using RetType = LuaResult<std::vector<std::string>>; + if (m_state == nullptr) { + return RetType::error(FudStatus::ObjectInvalid); + } + + auto luaType = lua_getglobal(m_state, name); + static_cast<void>(luaType); + + if (!lua_istable(m_state, -1)) { + lua_pop(m_state, 1); + return RetType::error(FudStatus::Failure); + } + + int64_t length; + int isNumber{}; + lua_len(m_state, -1); + length = lua_tointegerx(m_state, -1, &isNumber); + lua_pop(m_state, 1); + + if (!static_cast<bool>(isNumber) || length < 0) { + lua_pop(m_state, 1); + return RetType::error(FudStatus::Failure); + } + + std::vector<std::string> output{}; + output.reserve(static_cast<size_t>(length)); + for (int64_t index = 1; index <= length; ++index) { + const char* result{nullptr}; + lua_pushinteger(m_state, index); + static_cast<void>(lua_gettable(m_state, -2)); + result = lua_tolstring(m_state, -1, nullptr); + + if (result == nullptr) { + lua_pop(m_state, 1); + return RetType::error(FudStatus::Failure); + } + output.emplace_back(result); + } + + lua_pop(m_state, 1); + return RetType::okay(output); +} + +} // namespace getsuyomi |