diff --git a/src/controllers/plugins/LuaUtilities.cpp b/src/controllers/plugins/LuaUtilities.cpp index e8e31b6fd..58f648f0a 100644 --- a/src/controllers/plugins/LuaUtilities.cpp +++ b/src/controllers/plugins/LuaUtilities.cpp @@ -1,11 +1,7 @@ #ifdef CHATTERINO_HAVE_PLUGINS # include "controllers/plugins/LuaUtilities.hpp" -# include "common/Channel.hpp" # include "common/QLogging.hpp" -# include "controllers/commands/CommandContext.hpp" -# include "controllers/plugins/api/ChannelRef.hpp" -# include "controllers/plugins/LuaAPI.hpp" # include # include @@ -77,9 +73,6 @@ QString humanErrorText(lua_State *L, int errCode) case LUA_ERRFILE: errName = "(file error)"; break; - case ERROR_BAD_PEEK: - errName = "(unable to convert value to c++)"; - break; default: errName = "(unknown error type)"; } @@ -91,18 +84,6 @@ QString humanErrorText(lua_State *L, int errCode) return errName; } -StackIdx pushEmptyArray(lua_State *L, int countArray) -{ - lua_createtable(L, countArray, 0); - return lua_gettop(L); -} - -StackIdx pushEmptyTable(lua_State *L, int countProperties) -{ - lua_createtable(L, 0, countProperties); - return lua_gettop(L); -} - StackIdx push(lua_State *L, const QString &str) { return lua::push(L, str.toStdString()); @@ -114,68 +95,6 @@ StackIdx push(lua_State *L, const std::string &str) return lua_gettop(L); } -StackIdx push(lua_State *L, const bool &b) -{ - lua_pushboolean(L, int(b)); - return lua_gettop(L); -} - -StackIdx push(lua_State *L, const int &b) -{ - lua_pushinteger(L, b); - return lua_gettop(L); -} - -StackIdx push(lua_State *L, const api::CompletionEvent &ev) -{ - auto idx = pushEmptyTable(L, 4); -# define PUSH(field) \ - lua::push(L, ev.field); \ - lua_setfield(L, idx, #field) - PUSH(query); - PUSH(full_text_content); - PUSH(cursor_position); - PUSH(is_first_word); -# undef PUSH - return idx; -} - -bool peek(lua_State *L, int *out, StackIdx idx) -{ - StackGuard guard(L); - if (lua_isnumber(L, idx) == 0) - { - return false; - } - - *out = lua_tointeger(L, idx); - return true; -} - -bool peek(lua_State *L, bool *out, StackIdx idx) -{ - StackGuard guard(L); - if (!lua_isboolean(L, idx)) - { - return false; - } - - *out = bool(lua_toboolean(L, idx)); - return true; -} - -bool peek(lua_State *L, double *out, StackIdx idx) -{ - StackGuard guard(L); - int ok{0}; - auto v = lua_tonumberx(L, idx, &ok); - if (ok != 0) - { - *out = v; - } - return ok != 0; -} - bool peek(lua_State *L, QString *out, StackIdx idx) { StackGuard guard(L); @@ -193,40 +112,6 @@ bool peek(lua_State *L, QString *out, StackIdx idx) return true; } -bool peek(lua_State *L, QByteArray *out, StackIdx idx) -{ - StackGuard guard(L); - size_t len{0}; - const char *str = lua_tolstring(L, idx, &len); - if (str == nullptr) - { - return false; - } - if (len >= INT_MAX) - { - assert(false && "string longer than INT_MAX, shit's fucked, yo"); - } - *out = QByteArray(str, int(len)); - return true; -} - -bool peek(lua_State *L, std::string *out, StackIdx idx) -{ - StackGuard guard(L); - size_t len{0}; - const char *str = lua_tolstring(L, idx, &len); - if (str == nullptr) - { - return false; - } - if (len >= INT_MAX) - { - assert(false && "string longer than INT_MAX, shit's fucked, yo"); - } - *out = std::string(str, len); - return true; -} - QString toString(lua_State *L, StackIdx idx) { size_t len{}; diff --git a/src/controllers/plugins/LuaUtilities.hpp b/src/controllers/plugins/LuaUtilities.hpp index 574f1caff..a1e6036c4 100644 --- a/src/controllers/plugins/LuaUtilities.hpp +++ b/src/controllers/plugins/LuaUtilities.hpp @@ -2,34 +2,19 @@ #ifdef CHATTERINO_HAVE_PLUGINS -# include "common/QLogging.hpp" - # include # include # include # include # include -# include # include # include # include -# include -# include struct lua_State; -class QJsonObject; -namespace chatterino { -struct CommandContext; -} // namespace chatterino namespace chatterino::lua { -namespace api { - struct CompletionEvent; -} // namespace api - -constexpr int ERROR_BAD_PEEK = LUA_OK - 1; - /** * @brief Dumps the Lua stack into qCDebug(chatterinoLua) * @@ -50,31 +35,11 @@ QString humanErrorText(lua_State *L, int errCode); */ using StackIdx = int; -/** - * @brief Creates a table with countArray array properties on the Lua stack - * @return stack index of the newly created table - */ -StackIdx pushEmptyArray(lua_State *L, int countArray); - -/** - * @brief Creates a table with countProperties named properties on the Lua stack - * @return stack index of the newly created table - */ -StackIdx pushEmptyTable(lua_State *L, int countProperties); - StackIdx push(lua_State *L, const QString &str); StackIdx push(lua_State *L, const std::string &str); -StackIdx push(lua_State *L, const bool &b); -StackIdx push(lua_State *L, const int &b); -StackIdx push(lua_State *L, const api::CompletionEvent &ev); // returns OK? -bool peek(lua_State *L, int *out, StackIdx idx = -1); -bool peek(lua_State *L, bool *out, StackIdx idx = -1); -bool peek(lua_State *L, double *out, StackIdx idx = -1); bool peek(lua_State *L, QString *out, StackIdx idx = -1); -bool peek(lua_State *L, QByteArray *out, StackIdx idx = -1); -bool peek(lua_State *L, std::string *out, StackIdx idx = -1); /** * @brief Converts Lua object at stack index idx to a string. @@ -138,195 +103,6 @@ public: } }; -/// TEMPLATES - -template -StackIdx push(lua_State *L, std::optional val) -{ - if (val.has_value()) - { - return lua::push(L, *val); - } - lua_pushnil(L); - return lua_gettop(L); -} - -template -bool peek(lua_State *L, std::optional *out, StackIdx idx = -1) -{ - if (lua_isnil(L, idx)) - { - *out = std::nullopt; - return true; - } - - *out = T(); - return peek(L, out->operator->(), idx); -} - -template -bool peek(lua_State *L, std::vector *vec, StackIdx idx = -1) -{ - StackGuard guard(L); - - if (!lua_istable(L, idx)) - { - lua::stackDump(L, "!table"); - qCDebug(chatterinoLua) - << "value is not a table, type is" << lua_type(L, idx); - return false; - } - auto len = lua_rawlen(L, idx); - if (len == 0) - { - qCDebug(chatterinoLua) << "value has 0 length"; - return true; - } - if (len > 1'000'000) - { - qCDebug(chatterinoLua) << "value is too long"; - return false; - } - // count like lua - for (int i = 1; i <= len; i++) - { - lua_geti(L, idx, i); - std::optional obj; - if (!lua::peek(L, &obj)) - { - //lua_seti(L, LUA_REGISTRYINDEX, 1); // lazy - qCDebug(chatterinoLua) - << "Failed to convert lua object into c++: at array index " << i - << ":"; - stackDump(L, "bad conversion into string"); - return false; - } - lua_pop(L, 1); - vec->push_back(obj.value()); - } - return true; -} - -/** - * @brief Converts object at stack index idx to enum given by template parameter T - */ -template , bool>::type = true> -bool peek(lua_State *L, T *out, StackIdx idx = -1) -{ - std::string tmp; - if (!lua::peek(L, &tmp, idx)) - { - return false; - } - std::optional opt = magic_enum::enum_cast(tmp); - if (opt.has_value()) - { - *out = opt.value(); - return true; - } - - return false; -} - -/** - * @brief Converts a vector to Lua and pushes it onto the stack. - * - * Needs StackIdx push(lua_State*, T); to work. - * - * @return Stack index of newly created table. - */ -template -StackIdx push(lua_State *L, std::vector vec) -{ - auto out = pushEmptyArray(L, vec.size()); - int i = 1; - for (const auto &el : vec) - { - push(L, el); - lua_seti(L, out, i); - i += 1; - } - return out; -} - -/** - * @brief Converts a QList to Lua and pushes it onto the stack. - * - * Needs StackIdx push(lua_State*, T); to work. - * - * @return Stack index of newly created table. - */ -template -StackIdx push(lua_State *L, QList vec) -{ - auto out = pushEmptyArray(L, vec.size()); - int i = 1; - for (const auto &el : vec) - { - push(L, el); - lua_seti(L, out, i); - i += 1; - } - return out; -} - -/** - * @brief Converts an enum given by T to Lua (into a string) and pushes it onto the stack. - * - * @return Stack index of newly created string. - */ -template , bool> = true> -StackIdx push(lua_State *L, T inp) -{ - std::string_view name = magic_enum::enum_name(inp); - return lua::push(L, std::string(name)); -} - -/** - * @brief Converts a Lua object into c++ and removes it from the stack. - * If peek fails, the object is still removed from the stack. - * - * Relies on bool peek(lua_State*, T*, StackIdx) existing. - */ -template -bool pop(lua_State *L, T *out, StackIdx idx = -1) -{ - StackGuard guard(L, -1); - auto ok = peek(L, out, idx); - if (idx < 0) - { - idx = lua_gettop(L) + idx + 1; - } - lua_remove(L, idx); - return ok; -} - -/** - * @brief Creates a table mapping enum names to unique values. - * - * Values in this table may change. - * - * @returns stack index of newly created table - * @deprecated - */ -template -StackIdx pushEnumTable(lua_State *L) -{ - // std::array - auto values = magic_enum::enum_values(); - StackIdx out = lua::pushEmptyTable(L, values.size()); - for (const T v : values) - { - std::string_view name = magic_enum::enum_name(v); - std::string str(name); - - lua::push(L, str); - lua_setfield(L, out, str.c_str()); - } - return out; -} - /** * @brief Creates a table mapping enum names to unique values. * @@ -350,58 +126,6 @@ sol::table createEnumTable(sol::state_view &lua) return out; } -// Represents a Lua function on the stack -template -class CallbackFunction -{ - StackIdx stackIdx_; - lua_State *L; - -public: - CallbackFunction(lua_State *L, StackIdx stackIdx) - : stackIdx_(stackIdx) - , L(L) - { - } - - // this type owns the stackidx, it must not be trivially copiable - CallbackFunction operator=(CallbackFunction &) = delete; - CallbackFunction(CallbackFunction &) = delete; - - // Permit only move - CallbackFunction &operator=(CallbackFunction &&) = default; - CallbackFunction(CallbackFunction &&) = default; - - ~CallbackFunction() - { - lua_remove(L, this->stackIdx_); - } - - std::variant operator()(Args... arguments) - { - lua_pushvalue(this->L, this->stackIdx_); - ( // apparently this calls lua::push() for every Arg - [this, &arguments] { - lua::push(this->L, arguments); - }(), - ...); - - int res = lua_pcall(L, sizeof...(Args), 1, 0); - if (res != LUA_OK) - { - qCDebug(chatterinoLua) << "error is: " << res; - return {res}; - } - - ReturnType val; - if (!lua::pop(L, &val)) - { - return {ERROR_BAD_PEEK}; - } - return {val}; - } -}; - } // namespace chatterino::lua #endif