From fe2ececd23df0d462a4f1afe3ec75649804eab84 Mon Sep 17 00:00:00 2001 From: harrand Date: Sun, 6 Aug 2023 17:12:36 +0100 Subject: [PATCH] [lua] add ability to read variables. note that this is not properly tested and might not work --- src/tz/lua/state.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++- src/tz/lua/state.hpp | 7 ++++ 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/src/tz/lua/state.cpp b/src/tz/lua/state.cpp index 4b2a2d6d24..e646c4f6d6 100644 --- a/src/tz/lua/state.cpp +++ b/src/tz/lua/state.cpp @@ -50,7 +50,7 @@ namespace tz::lua bool state::assign_bool(const char* varname, bool b) const { - std::string cmd = std::string(varname) + " = " + std::to_string(b); + std::string cmd = std::string(varname) + " = " + (b ? "true" : "false"); return this->execute(cmd.c_str(), false); } @@ -95,6 +95,97 @@ namespace tz::lua return this->execute(cmd.c_str(), false); } + std::vector impl_string_split(const std::string& str, const std::string& delim) + { + std::vector result; + std::size_t start = 0; + + for(std::size_t found = str.find(delim); found != std::string::npos; found = str.find(delim, start)) + { + result.emplace_back(str.begin() + start, str.begin() + found); + start = found + delim.size(); + } + if (start != str.size()) + result.emplace_back(str.begin() + start, str.end()); + return result; + } + + // leaves 1 extra on the stack. + int impl_lua_get_var(std::string varname, lua_State* s, int& stack_sz) + { + auto bits = impl_string_split(varname, "."); + tz::assert(bits.size()); + int type = lua_getglobal(s, bits.front().c_str()); + bits.erase(bits.begin()); + stack_sz++; + for(const std::string& bit : bits) + { + type = lua_getfield(s, -1, bit.c_str()); + stack_sz++; + if(type == LUA_TNIL) + { + break; + } + } + return type; + } + + std::optional state::get_bool(const char* varname) const + { + std::optional ret = std::nullopt; + int stack_usage = 0; + auto* s = static_cast(this->lstate); + if(impl_lua_get_var(varname, s, stack_usage) == LUA_TBOOLEAN) + { + ret = lua_toboolean(s, -1); + } + lua_pop(s, stack_usage); + return ret; + } + + std::optional state::get_float(const char* varname) const + { + auto ret = this->get_double(varname); + if(ret.has_value()) + { + return static_cast(ret.value()); + } + return std::nullopt; + } + + std::optional state::get_double(const char* varname) const + { + std::optional ret = std::nullopt; + int stack_usage = 0; + auto* s = static_cast(this->lstate); + if(impl_lua_get_var(varname, s, stack_usage) == LUA_TNUMBER) + { + ret = lua_tonumber(s, -1); + } + lua_pop(s, stack_usage); + return ret; + } + + std::optional state::get_int(const char* varname) const + { + auto ret = this->get_double(varname); + if(ret.has_value()) + { + return static_cast(ret.value()); + } + return std::nullopt; + } + + std::optional state::get_uint(const char* varname) const + { + auto ret = this->get_int(varname); + if(ret.has_value()) + { + return static_cast(ret.value()); + } + return std::nullopt; + } + std::string state::collect_stack() const { if(!this->impl_check_stack(3)) diff --git a/src/tz/lua/state.hpp b/src/tz/lua/state.hpp index 0b8621de45..a047e18e35 100644 --- a/src/tz/lua/state.hpp +++ b/src/tz/lua/state.hpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace tz::lua { @@ -55,6 +56,12 @@ namespace tz::lua } bool assign_func(const char* varname, void* func_ptr) const; bool assign_string(const char* varname, std::string str) const; + + std::optional get_bool(const char* varname) const; + std::optional get_float(const char* varname) const; + std::optional get_double(const char* varname) const; + std::optional get_int(const char* varname) const; + std::optional get_uint(const char* varname) const; std::string collect_stack() const; private: bool impl_check_stack(std::size_t sz) const;