Skip to content

Commit

Permalink
refactor(plugins): use sol3 for commands and channels
Browse files Browse the repository at this point in the history
  • Loading branch information
Nerixyz committed Sep 3, 2024
1 parent aae1288 commit 45b7c0a
Show file tree
Hide file tree
Showing 29 changed files with 576 additions and 644 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,6 @@
[submodule "lib/expected-lite"]
path = lib/expected-lite
url = https://github.com/martinmoene/expected-lite
[submodule "lib/sol2"]
path = lib/sol2
url = https://github.com/ThePhD/sol2.git
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ endif()
if (CHATTERINO_PLUGINS)
set(LUA_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/lib/lua/src")
add_subdirectory(lib/lua)

find_package(sol2 REQUIRED)
endif()

if (BUILD_WITH_CRASHPAD)
Expand Down
20 changes: 20 additions & 0 deletions cmake/FindSol2.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
include(FindPackageHandleStandardArgs)

find_path(Sol2_INCLUDE_DIR sol/sol.hpp HINTS ${CMAKE_SOURCE_DIR}/lib/sol2/include)

find_package_handle_standard_args(Sol2 DEFAULT_MSG Sol2_INCLUDE_DIR)

if (Sol2_FOUND)
add_library(Sol2 INTERFACE IMPORTED)
set_target_properties(Sol2 PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Sol2_INCLUDE_DIR}"
)
target_compile_definitions(Sol2 INTERFACE
SOL_ALL_SAFETIES_ON=1
SOL_USING_CXX_LUA=1
)
target_link_libraries(Sol2 INTERFACE lua)
add_library(sol2::sol2 ALIAS Sol2)
endif ()

mark_as_advanced(Sol2_INCLUDE_DIR)
43 changes: 19 additions & 24 deletions docs/plugin-meta.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,29 @@ c2.EventType = {}
-- Begin src/common/Channel.hpp

---@alias c2.ChannelType integer
---@type { None: c2.ChannelType, Direct: c2.ChannelType, Twitch: c2.ChannelType, TwitchWhispers: c2.ChannelType, TwitchWatching: c2.ChannelType, TwitchMentions: c2.ChannelType, TwitchLive: c2.ChannelType, TwitchAutomod: c2.ChannelType, TwitchEnd: c2.ChannelType, Irc: c2.ChannelType, Misc: c2.ChannelType }
---@type { None: c2.ChannelType, Direct: c2.ChannelType, Twitch: c2.ChannelType, TwitchWhispers: c2.ChannelType, TwitchWatching: c2.ChannelType, TwitchMentions: c2.ChannelType, TwitchLive: c2.ChannelType, TwitchAutomod: c2.ChannelType, TwitchEnd: c2.ChannelType, Misc: c2.ChannelType }
c2.ChannelType = {}

-- End src/common/Channel.hpp

-- Begin src/controllers/plugins/api/ChannelRef.hpp

---@alias c2.Platform integer
--- This enum describes a platform for the purpose of searching for a channel.
--- Currently only Twitch is supported because identifying IRC channels is tricky.
---@type { Twitch: c2.Platform }
c2.Platform = {}
-- Begin src/providers/twitch/TwitchChannel.hpp

---@class StreamStatus
---@field live boolean
---@field viewer_count number
---@field title string Stream title or last stream title
---@field game_name string
---@field game_id string
---@field uptime number Seconds since the stream started.

---@class RoomModes
---@field subscriber_only boolean
---@field unique_chat boolean You might know this as r9kbeta or robot9000.
---@field emotes_only boolean Whether or not text is allowed in messages. Note that "emotes" here only means Twitch emotes, not Unicode emoji, nor 3rd party text-based emotes

-- End src/providers/twitch/TwitchChannel.hpp

---@class c2.Channel
c2.Channel = {}
Expand Down Expand Up @@ -72,7 +83,7 @@ function c2.Channel:get_display_name() end
--- Note that this does not execute client-commands.
---
---@param message string
---@param execute_commands boolean Should commands be run on the text?
---@param execute_commands? boolean Should commands be run on the text?
function c2.Channel:send_message(message, execute_commands) end

--- Adds a system message client-side
Expand Down Expand Up @@ -131,31 +142,15 @@ function c2.Channel:__tostring() end
--- - /automod
---
---@param name string Which channel are you looking for?
---@param platform c2.Platform Where to search for the channel?
---@return c2.Channel?
function c2.Channel.by_name(name, platform) end
function c2.Channel.by_name(name) end

--- Finds a channel by the Twitch user ID of its owner.
---
---@param id string ID of the owner of the channel.
---@return c2.Channel?
function c2.Channel.by_twitch_id(id) end

---@class RoomModes
---@field unique_chat boolean You might know this as r9kbeta or robot9000.
---@field subscriber_only boolean
---@field emotes_only boolean Whether or not text is allowed in messages. Note that "emotes" here only means Twitch emotes, not Unicode emoji, nor 3rd party text-based emotes
---@field follower_only number? Time in minutes you need to follow to chat or nil.
---@field slow_mode number? Time in seconds you need to wait before sending messages or nil.

---@class StreamStatus
---@field live boolean
---@field viewer_count number
---@field uptime number Seconds since the stream started.
---@field title string Stream title or last stream title
---@field game_name string
---@field game_id string

-- End src/controllers/plugins/api/ChannelRef.hpp

-- Begin src/controllers/plugins/api/HTTPResponse.hpp
Expand Down
15 changes: 3 additions & 12 deletions docs/wip-plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,15 +219,6 @@ c2.register_callback(
)
```

#### `Platform` enum

This table describes platforms that can be accessed. Chatterino supports IRC
however plugins do not yet have explicit access to get IRC channels objects.
The values behind the names may change, do not count on them. It has the
following keys:

- `Twitch`

#### `ChannelType` enum

This table describes channel types Chatterino supports. The values behind the
Expand Down Expand Up @@ -260,9 +251,9 @@ used on non-Twitch channels. Special channels while marked as
is an actual Twitch chatroom use `Channel:get_type()` instead of
`Channel:is_twitch_channel()`.

##### `Channel:by_name(name, platform)`
##### `Channel:by_name(name)`

Finds a channel given by `name` on `platform` (see [`Platform` enum](#Platform-enum)). Returns the channel or `nil` if not open.
Finds a channel given by `name`. Returns the channel or `nil` if not open.

Some miscellaneous channels are marked as if they are specifically Twitch channels:

Expand All @@ -275,7 +266,7 @@ Some miscellaneous channels are marked as if they are specifically Twitch channe
Example:

```lua
local pajladas = c2.Channel.by_name("pajlada", c2.Platform.Twitch)
local pajladas = c2.Channel.by_name("pajlada")
```

##### `Channel:by_twitch_id(id)`
Expand Down
84 changes: 43 additions & 41 deletions lib/lua/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,53 +1,55 @@
project(lua CXX)

#[====[
Updating this list:
remove all listed files
go to line below, ^y2j4j$@" and then reindent the file names
/LUA_SRC
:r!ls lib/lua/src | grep '\.c' | grep -Ev 'lua\.c|onelua\.c' | sed 's#^#src/#'
This list contains all .c files except lua.c and onelua.c
Use the following command from the repository root to get these file:
perl -e 'print s/^lib\/lua\///r . "\n" for grep { /\.c$/ && !/(lua|onelua)\.c$/ } glob "lib/lua/src/*.c"'
#]====]
set(LUA_SRC
"src/lapi.c"
"src/lauxlib.c"
"src/lbaselib.c"
"src/lcode.c"
"src/lcorolib.c"
"src/lctype.c"
"src/ldblib.c"
"src/ldebug.c"
"src/ldo.c"
"src/ldump.c"
"src/lfunc.c"
"src/lgc.c"
"src/linit.c"
"src/liolib.c"
"src/llex.c"
"src/lmathlib.c"
"src/lmem.c"
"src/loadlib.c"
"src/lobject.c"
"src/lopcodes.c"
"src/loslib.c"
"src/lparser.c"
"src/lstate.c"
"src/lstring.c"
"src/lstrlib.c"
"src/ltable.c"
"src/ltablib.c"
"src/ltests.c"
"src/ltm.c"
"src/lua.c"
"src/lundump.c"
"src/lutf8lib.c"
"src/lvm.c"
"src/lzio.c"
src/lapi.c
src/lauxlib.c
src/lbaselib.c
src/lcode.c
src/lcorolib.c
src/lctype.c
src/ldblib.c
src/ldebug.c
src/ldo.c
src/ldump.c
src/lfunc.c
src/lgc.c
src/linit.c
src/liolib.c
src/llex.c
src/lmathlib.c
src/lmem.c
src/loadlib.c
src/lobject.c
src/lopcodes.c
src/loslib.c
src/lparser.c
src/lstate.c
src/lstring.c
src/lstrlib.c
src/ltable.c
src/ltablib.c
src/ltests.c
src/ltm.c
src/lundump.c
src/lutf8lib.c
src/lvm.c
src/lzio.c
)

add_library(lua STATIC ${LUA_SRC})
target_include_directories(lua
PUBLIC
${LUA_INCLUDE_DIRS}
)
set_source_files_properties(${LUA_SRC} PROPERTIES LANGUAGE C)
set_target_properties(${liblua} PROPERTIES
LANGUAGE CXX
LINKER_LANGUAGE CXX
CXX_STANDARD 98
CXX_EXTENSIONS TRUE
)
set_source_files_properties(${LUA_SRC} PROPERTIES LANGUAGE CXX)
2 changes: 1 addition & 1 deletion lib/lua/src
Submodule src updated 70 files
+153 −161 lapi.c
+5 −14 lapi.h
+35 −107 lauxlib.c
+0 −2 lauxlib.h
+24 −31 lbaselib.c
+20 −21 lcode.c
+4 −1 lcode.h
+9 −0 ldblib.c
+80 −119 ldebug.c
+0 −1 ldebug.h
+14 −24 ldo.c
+13 −0 ldo.h
+32 −92 ldump.c
+4 −6 lfunc.c
+351 −336 lgc.c
+22 −69 lgc.h
+26 −23 linit.c
+5 −5 llex.c
+13 −16 llimits.h
+24 −31 lmathlib.c
+4 −4 lmem.c
+0 −2 lmem.h
+16 −7 loadlib.c
+2 −59 lobject.c
+14 −53 lobject.h
+4 −4 lopcodes.h
+33 −42 lparser.c
+67 −32 lstate.c
+17 −15 lstate.h
+14 −90 lstring.c
+5 −9 lstring.h
+6 −12 lstrlib.c
+114 −412 ltable.c
+13 −119 ltable.h
+29 −16 ltablib.c
+57 −147 ltests.c
+3 −4 ltests.h
+23 −28 ltm.c
+10 −10 ltm.h
+4 −16 lua.c
+24 −52 lua.h
+0 −9 luaconf.h
+13 −26 lualib.h
+56 −126 lundump.c
+3 −6 lundump.h
+164 −159 lvm.c
+24 −19 lvm.h
+8 −28 lzio.c
+0 −1 lzio.h
+1 −1 manual/2html
+271 −347 manual/manual.of
+1 −1 testes/all.lua
+22 −101 testes/api.lua
+1 −1 testes/attrib.lua
+15 −26 testes/calls.lua
+11 −8 testes/closure.lua
+8 −10 testes/coroutine.lua
+4 −4 testes/db.lua
+4 −7 testes/errors.lua
+0 −9 testes/events.lua
+6 −8 testes/files.lua
+54 −38 testes/gc.lua
+17 −27 testes/gengc.lua
+8 −2 testes/locals.lua
+25 −35 testes/main.lua
+6 −8 testes/nextvar.lua
+20 −36 testes/pm.lua
+5 −33 testes/sort.lua
+3 −26 testes/strings.lua
+0 −2 testes/utf8.lua
1 change: 1 addition & 0 deletions lib/sol2
Submodule sol2 added at 2b0d2f
4 changes: 2 additions & 2 deletions scripts/make_luals_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def write_func(path: Path, line: int, comments: list[str], out: TextIOWrapper):
if not comments[0].startswith("@"):
out.write(f"--- {comments[0]}\n---\n")
comments = comments[1:]
params = []
params: list[str] = []
for comment in comments[:-1]:
if not comment.startswith("@lua"):
panic(path, line, f"Invalid function specification - got '{comment}'")
Expand All @@ -209,7 +209,7 @@ def write_func(path: Path, line: int, comments: list[str], out: TextIOWrapper):
panic(path, line, f"Invalid function exposure - got '{comments[-1]}'")
name = comments[-1].split(" ", 1)[1]
printmsg(path, line, f"function {name}")
lua_params = ", ".join(params)
lua_params = ", ".join(p.removesuffix("?") for p in params)
out.write(f"function {name}({lua_params}) end\n\n")


Expand Down
12 changes: 7 additions & 5 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -774,7 +776,7 @@ target_link_libraries(${LIBRARY_PROJECT}
$<$<BOOL:${WIN32}>:Wtsapi32>
)
if (CHATTERINO_PLUGINS)
target_link_libraries(${LIBRARY_PROJECT} PUBLIC lua)
target_link_libraries(${LIBRARY_PROJECT} PUBLIC lua sol2::sol2)
endif()

if (BUILD_WITH_QTKEYCHAIN)
Expand Down
4 changes: 4 additions & 0 deletions src/PrecompiledHeader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@
# include <unordered_set>
# include <vector>

# ifdef CHATTERINO_HAVE_PLUGINS
# include <sol/sol.hpp>
# endif

# ifndef UNUSED
# define UNUSED(x) (void)(x)
# endif
Expand Down
36 changes: 0 additions & 36 deletions src/controllers/plugins/LuaAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@
# include "messages/MessageBuilder.hpp"
# include "providers/twitch/TwitchIrcServer.hpp"

extern "C" {
# include <lauxlib.h>
# include <lua.h>
# include <lualib.h>
}
# include <QFileInfo>
# include <QLoggingCategory>
# include <QTextCodec>
Expand Down Expand Up @@ -63,40 +61,6 @@ QDebug qdebugStreamForLogLevel(lua::api::LogLevel lvl)
// luaL_error is a c-style vararg function, this makes clang-tidy not dislike it so much
namespace chatterino::lua::api {

int c2_register_command(lua_State *L)
{
auto *pl = getApp()->getPlugins()->getPluginByStatePtr(L);
if (pl == nullptr)
{
luaL_error(L, "internal error: no plugin");
return 0;
}

QString name;
if (!lua::peek(L, &name, 1))
{
luaL_error(L, "cannot get command name (1st arg of register_command, "
"expected a string)");
return 0;
}
if (lua_isnoneornil(L, 2))
{
luaL_error(L, "missing argument for register_command: function "
"\"pointer\"");
return 0;
}

auto callbackSavedName = QString("c2commandcb-%1").arg(name);
lua_setfield(L, LUA_REGISTRYINDEX, callbackSavedName.toStdString().c_str());
auto ok = pl->registerCommand(name, callbackSavedName);

// delete both name and callback
lua_pop(L, 2);

lua::push(L, ok);
return 1;
}

int c2_register_callback(lua_State *L)
{
auto *pl = getApp()->getPlugins()->getPluginByStatePtr(L);
Expand Down
Loading

0 comments on commit 45b7c0a

Please sign in to comment.