From 944e447886a1b503e6b43c2e1f56fdd1aa55f848 Mon Sep 17 00:00:00 2001 From: Mm2PL Date: Thu, 3 Oct 2024 16:24:42 +0200 Subject: [PATCH] Add things for sol migration Co-authored-by: Nerixyz --- src/CMakeLists.txt | 10 ++- src/PrecompiledHeader.hpp | 4 + src/controllers/plugins/SolTypes.cpp | 58 ++++++++++++++ src/controllers/plugins/SolTypes.hpp | 111 +++++++++++++++++++++++++++ 4 files changed, 179 insertions(+), 4 deletions(-) create mode 100644 src/controllers/plugins/SolTypes.cpp create mode 100644 src/controllers/plugins/SolTypes.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1d40a43a3..57b9c4060 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -235,14 +235,16 @@ set(SOURCE_FILES controllers/plugins/api/HTTPResponse.hpp controllers/plugins/LuaAPI.cpp controllers/plugins/LuaAPI.hpp - controllers/plugins/PluginPermission.cpp - controllers/plugins/PluginPermission.hpp + controllers/plugins/LuaUtilities.cpp + controllers/plugins/LuaUtilities.hpp controllers/plugins/Plugin.cpp controllers/plugins/Plugin.hpp controllers/plugins/PluginController.hpp controllers/plugins/PluginController.cpp - controllers/plugins/LuaUtilities.cpp - controllers/plugins/LuaUtilities.hpp + controllers/plugins/PluginPermission.cpp + controllers/plugins/PluginPermission.hpp + controllers/plugins/SolTypes.cpp + controllers/plugins/SolTypes.hpp controllers/sound/ISoundController.hpp controllers/sound/MiniaudioBackend.cpp diff --git a/src/PrecompiledHeader.hpp b/src/PrecompiledHeader.hpp index d7c289bca..a12265950 100644 --- a/src/PrecompiledHeader.hpp +++ b/src/PrecompiledHeader.hpp @@ -129,6 +129,10 @@ # include # include +# ifdef CHATTERINO_HAVE_PLUGINS +# include +# endif + # ifndef UNUSED # define UNUSED(x) (void)(x) # endif diff --git a/src/controllers/plugins/SolTypes.cpp b/src/controllers/plugins/SolTypes.cpp new file mode 100644 index 000000000..00ce5788b --- /dev/null +++ b/src/controllers/plugins/SolTypes.cpp @@ -0,0 +1,58 @@ +#ifdef CHATTERINO_HAVE_PLUGINS +# include "controllers/plugins/SolTypes.hpp" + +// NOLINTBEGIN(readability-named-parameter) +// QString +bool sol_lua_check(sol::types, lua_State *L, int index, + std::function handler, + sol::stack::record &tracking) +{ + return sol::stack::check(L, index, handler, tracking); +} + +QString sol_lua_get(sol::types, lua_State *L, int index, + sol::stack::record &tracking) +{ + auto str = sol::stack::get(L, index, tracking); + return QString::fromUtf8(str.data(), static_cast(str.length())); +} + +int sol_lua_push(sol::types, lua_State *L, const QString &value) +{ + return sol::stack::push(L, value.toUtf8().data()); +} + +// QStringList +bool sol_lua_check(sol::types, lua_State *L, int index, + std::function handler, + sol::stack::record &tracking) +{ + return sol::stack::check(L, index, handler, tracking); +} + +QStringList sol_lua_get(sol::types, lua_State *L, int index, + sol::stack::record &tracking) +{ + sol::table table = sol::stack::get(L, index, tracking); + QStringList result; + result.reserve(static_cast(table.size())); + for (size_t i = 1; i < table.size() + 1; i++) + { + result.append(table.get(i)); + } + return result; +} + +int sol_lua_push(sol::types, lua_State *L, + const QStringList &value) +{ + sol::table table = sol::table::create(L, static_cast(value.size())); + for (const QString &str : value) + { + table.add(str); + } + return sol::stack::push(L, table); +} +// NOLINTEND(readability-named-parameter) + +#endif diff --git a/src/controllers/plugins/SolTypes.hpp b/src/controllers/plugins/SolTypes.hpp new file mode 100644 index 000000000..397e46daa --- /dev/null +++ b/src/controllers/plugins/SolTypes.hpp @@ -0,0 +1,111 @@ +#pragma once +#ifdef CHATTERINO_HAVE_PLUGINS + +# include "util/QMagicEnum.hpp" +# include "util/TypeName.hpp" + +# include +# include +# include +# include +# include + +namespace chatterino::detail { + +// NOLINTBEGIN(readability-identifier-naming) +template +constexpr bool IsOptional = false; +template +constexpr bool IsOptional> = true; +// NOLINTEND(readability-identifier-naming) + +} // namespace chatterino::detail + +namespace chatterino::lua { + +/// @brief Attempts to call @a function with @a args +/// +/// @a T is expected to be returned. +/// If `void` is specified, the returned values +/// are ignored. +/// `std::optional` signifies zero or one returned values. +template +inline nonstd::expected_lite::expected tryCall( + const sol::protected_function &function, Args &&...args) +{ + sol::protected_function_result result = + function(std::forward(args)...); + if (!result.valid()) + { + sol::error err = result; + return nonstd::expected_lite::make_unexpected( + QString::fromUtf8(err.what())); + } + + if constexpr (std::is_same_v) + { + return {}; + } + if constexpr (detail::IsOptional) + { + if (result.return_count() == 0) + { + return {}; + } + } + + if (result.return_count() > 1) + { + return nonstd::expected_lite::make_unexpected( + u"Expected one value to be returned but " % + QString::number(result.return_count()) % u" values were returned"); + } + + try + { + // XXX: this has weird failure modes, + // std::optional means this is fallible, but we want nil|LuaFor + if constexpr (detail::IsOptional) + { + return result.get(); + } + else + { + auto ret = result.get>(); + + if (!ret) + { + auto t = type_name(); + return nonstd::expected_lite::make_unexpected( + u"Expected " % QLatin1String(t.data(), t.size()) % + u" to be returned but " % + qmagicenum::enumName(result.get_type()) % u" was returned"); + } + return *ret; + } + } + catch (std::runtime_error &e) + { + return nonstd::expected_lite::make_unexpected( + QString::fromUtf8(e.what())); + } + // non other exceptions we let it explode +} + +} // namespace chatterino::lua + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +# define SOL_STACK_FUNCTIONS(TYPE) \ + bool sol_lua_check(sol::types, lua_State *L, int index, \ + std::function handler, \ + sol::stack::record &tracking); \ + TYPE sol_lua_get(sol::types, lua_State *L, int index, \ + sol::stack::record &tracking); \ + int sol_lua_push(sol::types, lua_State *L, const TYPE &value); + +SOL_STACK_FUNCTIONS(QString) +SOL_STACK_FUNCTIONS(QStringList) + +# undef SOL_STACK_FUNCTIONS + +#endif