Add more push/peek/pop functions to LuaUtilities

This commit is contained in:
Mm2PL 2023-01-30 22:21:09 +01:00
parent 602b9a738c
commit 082420b94a
No known key found for this signature in database
GPG key ID: 94AC9B80EFA15ED9
3 changed files with 74 additions and 15 deletions

View file

@ -2,8 +2,12 @@
#include "common/Channel.hpp" #include "common/Channel.hpp"
#include "controllers/commands/CommandContext.hpp" #include "controllers/commands/CommandContext.hpp"
#include "lauxlib.h"
#include "lua.h" #include "lua.h"
#include <climits>
#include <cstdlib>
namespace chatterino::lua { namespace chatterino::lua {
int pushEmptyArray(lua_State *L, int countArray) int pushEmptyArray(lua_State *L, int countArray)
{ {
@ -35,4 +39,36 @@ int push(lua_State *L, const CommandContext &ctx)
return outIdx; return outIdx;
} }
int push(lua_State *L, const bool &b)
{
lua_pushboolean(L, int(b));
return lua_gettop(L);
}
bool peek(lua_State *L, double *out, int idx)
{
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, int idx)
{
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 = QString::fromUtf8(str, int(len));
return true;
}
} // namespace chatterino::lua } // namespace chatterino::lua

View file

@ -17,6 +17,11 @@ int pushEmptyTable(lua_State *L, int countProperties);
int push(lua_State *L, const CommandContext &ctx); int push(lua_State *L, const CommandContext &ctx);
int push(lua_State *L, const QString &str); int push(lua_State *L, const QString &str);
int push(lua_State *L, const bool &b);
// returns OK?
bool peek(lua_State *L, double *out, int idx = -1);
bool peek(lua_State *L, QString *out, int idx = -1);
/// TEMPLATES /// TEMPLATES
@ -48,4 +53,15 @@ int push(lua_State *L, QList<T> vec)
return out; return out;
} }
template <typename T>
bool pop(lua_State *L, T *out, int idx = -1)
{
auto ok = peek(L, out, idx);
if (ok)
{
lua_pop(L, 1);
}
return ok;
}
} // namespace chatterino::lua } // namespace chatterino::lua

View file

@ -143,9 +143,6 @@ QString PluginController::tryExecPluginCommand(const QString &commandName,
return ""; return "";
} }
constexpr int C_FALSE = 0;
constexpr int C_TRUE = 1;
extern "C" { extern "C" {
int luaC2SystemMsg(lua_State *L) int luaC2SystemMsg(lua_State *L)
@ -154,22 +151,25 @@ int luaC2SystemMsg(lua_State *L)
{ {
qCDebug(chatterinoLua) << "system_msg: need 2 args"; qCDebug(chatterinoLua) << "system_msg: need 2 args";
luaL_error(L, "need exactly 2 arguments"); // NOLINT luaL_error(L, "need exactly 2 arguments"); // NOLINT
lua_pushboolean(L, C_FALSE); lua::push(L, false);
return 1; return 1;
} }
const char *channel = luaL_optstring(L, 1, NULL); //const char *channel = luaL_optstring(L, 1, NULL);
const char *text = luaL_optstring(L, 2, NULL); QString channel;
lua_pop(L, 2); QString text;
lua::pop(L, &text);
lua::pop(L, &channel);
//const char *text = luaL_optstring(L, 2, NULL);
const auto chn = getApp()->twitch->getChannelOrEmpty(channel); const auto chn = getApp()->twitch->getChannelOrEmpty(channel);
if (chn->isEmpty()) if (chn->isEmpty())
{ {
qCDebug(chatterinoLua) << "system_msg: no channel" << channel; qCDebug(chatterinoLua) << "system_msg: no channel" << channel;
lua_pushboolean(L, C_FALSE); lua::push(L, false);
return 1; return 1;
} }
qCDebug(chatterinoLua) << "system_msg: OK!"; qCDebug(chatterinoLua) << "system_msg: OK!";
chn->addMessage(makeSystemMessage(text)); chn->addMessage(makeSystemMessage(text));
lua_pushboolean(L, C_TRUE); lua::push(L, true);
return 1; return 1;
} }
@ -182,7 +182,13 @@ int luaC2RegisterCommand(lua_State *L)
return 0; return 0;
} }
const char *name = luaL_optstring(L, 1, NULL); QString name;
if (!lua::peek(L, &name, 1))
{
// NOLINTNEXTLINE
luaL_error(L, "cannot get string (1st arg of register_command)");
return 0;
}
if (lua_isnoneornil(L, 2)) if (lua_isnoneornil(L, 2))
{ {
// NOLINTNEXTLINE // NOLINTNEXTLINE
@ -202,22 +208,23 @@ int luaC2RegisterCommand(lua_State *L)
} }
int luaC2SendMsg(lua_State *L) int luaC2SendMsg(lua_State *L)
{ {
const char *channel = luaL_optstring(L, 1, NULL); QString text;
const char *text = luaL_optstring(L, 2, NULL); QString channel;
lua_pop(L, 2); lua::pop(L, &text);
lua::pop(L, &channel);
const auto chn = getApp()->twitch->getChannelOrEmpty(channel); const auto chn = getApp()->twitch->getChannelOrEmpty(channel);
if (chn->isEmpty()) if (chn->isEmpty())
{ {
qCDebug(chatterinoLua) << "send_msg: no channel" << channel; qCDebug(chatterinoLua) << "send_msg: no channel" << channel;
lua_pushboolean(L, C_FALSE); lua::push(L, false);
return 1; return 1;
} }
QString message = text; QString message = text;
message = message.replace('\n', ' '); message = message.replace('\n', ' ');
QString outText = getApp()->commands->execCommand(message, chn, false); QString outText = getApp()->commands->execCommand(message, chn, false);
chn->sendMessage(outText); chn->sendMessage(outText);
lua_pushboolean(L, C_TRUE); lua::push(L, true);
return 1; return 1;
} }