Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(luals-meta): generate globals in c2 and echo @lua commands #5385

Merged
merged 6 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- Dev: Make printing of strings in tests easier. (#5379)
- Dev: Refactor and document `Scrollbar`. (#5334, #5393)
- Dev: Reduced the amount of scale events. (#5404, #5406)
- Dev: All Lua globals now show in the `c2` global in the LuaLS metadata. (#5385)

## 2.5.1

Expand Down
58 changes: 29 additions & 29 deletions docs/plugin-meta.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ c2.EventType = {}

---@class CommandContext
---@field words string[] The words typed when executing the command. For example `/foo bar baz` will result in `{"/foo", "bar", "baz"}`.
---@field channel Channel The channel the command was executed in.
---@field channel c2.Channel The channel the command was executed in.

---@class CompletionList
---@field values string[] The completions
Expand All @@ -30,98 +30,98 @@ c2.EventType = {}

-- Begin src/common/Channel.hpp

---@alias ChannelType integer
---@type { None: ChannelType, Direct: ChannelType, Twitch: ChannelType, TwitchWhispers: ChannelType, TwitchWatching: ChannelType, TwitchMentions: ChannelType, TwitchLive: ChannelType, TwitchAutomod: ChannelType, TwitchEnd: ChannelType, Irc: ChannelType, Misc: ChannelType }
ChannelType = {}
---@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 }
c2.ChannelType = {}

-- End src/common/Channel.hpp

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

---@alias Platform integer
---@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: Platform }
Platform = {}
---@type { Twitch: c2.Platform }
c2.Platform = {}

---@class Channel
Channel = {}
---@class c2.Channel
c2.Channel = {}

--- Returns true if the channel this object points to is valid.
--- If the object expired, returns false
--- If given a non-Channel object, it errors.
---
---@return boolean success
function Channel:is_valid() end
function c2.Channel:is_valid() end

--- Gets the channel's name. This is the lowercase login name.
---
---@return string name
function Channel:get_name() end
function c2.Channel:get_name() end

--- Gets the channel's type
---
---@return ChannelType
function Channel:get_type() end
---@return c2.ChannelType
function c2.Channel:get_type() end

--- Get the channel owner's display name. This may contain non-lowercase ascii characters.
---
---@return string name
function Channel:get_display_name() end
function c2.Channel:get_display_name() end

--- Sends a message to the target channel.
--- Note that this does not execute client-commands.
---
---@param message string
---@param execute_commands boolean Should commands be run on the text?
function Channel:send_message(message, execute_commands) end
function c2.Channel:send_message(message, execute_commands) end

--- Adds a system message client-side
---
---@param message string
function Channel:add_system_message(message) end
function c2.Channel:add_system_message(message) end

--- Returns true for twitch channels.
--- Compares the channel Type. Note that enum values aren't guaranteed, just
--- that they are equal to the exposed enum.
---
---@return boolean
function Channel:is_twitch_channel() end
function c2.Channel:is_twitch_channel() end

--- Returns a copy of the channel mode settings (subscriber only, r9k etc.)
---
---@return RoomModes
function Channel:get_room_modes() end
function c2.Channel:get_room_modes() end

--- Returns a copy of the stream status.
---
---@return StreamStatus
function Channel:get_stream_status() end
function c2.Channel:get_stream_status() end

--- Returns the Twitch user ID of the owner of the channel.
---
---@return string
function Channel:get_twitch_id() end
function c2.Channel:get_twitch_id() end

--- Returns true if the channel is a Twitch channel and the user owns it
---
---@return boolean
function Channel:is_broadcaster() end
function c2.Channel:is_broadcaster() end

--- Returns true if the channel is a Twitch channel and the user is a moderator in the channel
--- Returns false for broadcaster.
---
---@return boolean
function Channel:is_mod() end
function c2.Channel:is_mod() end

--- Returns true if the channel is a Twitch channel and the user is a VIP in the channel
--- Returns false for broadcaster.
---
---@return boolean
function Channel:is_vip() end
function c2.Channel:is_vip() end

---@return string
function Channel:__tostring() end
function c2.Channel:__tostring() end

--- Finds a channel by name.
--- Misc channels are marked as Twitch:
Expand All @@ -132,15 +132,15 @@ function Channel:__tostring() end
--- - /automod
---
---@param name string Which channel are you looking for?
---@param platform Platform Where to search for the channel?
---@return Channel?
function Channel.by_name(name, platform) end
---@param platform c2.Platform Where to search for the channel?
---@return c2.Channel?
function c2.Channel.by_name(name, platform) end

--- Finds a channel by the Twitch user ID of its owner.
---
---@param id string ID of the owner of the channel.
---@return Channel?
function Channel.by_twitch_id(id) end
---@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.
Expand Down
43 changes: 24 additions & 19 deletions scripts/make_luals_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,13 @@ def next_doc_comment(self) -> Optional[list[str]]:
def read_class_body(self) -> list[list[str]]:
"""The reader must be at the first line of the class/struct body. All comments inside the class are returned."""
items = []
nesting = -1 # for the opening brace
while (line := self.peek_line()) is not None:
if line.startswith("};"):
if line.startswith("};") and nesting == 0:
self.next_line()
break
if not is_comment_start(line):
nesting += line.count("{") - line.count("}")
self.next_line()
continue
doc = self.next_doc_comment()
Expand Down Expand Up @@ -231,21 +233,6 @@ def read_file(path: Path, out: TextIOWrapper):
else:
header = doc_comment

# include block
if header[0].startswith("@includefile "):
for comment in header:
if not comment.startswith("@includefile "):
panic(
path,
reader.line_no(),
f"Invalid include block - got line '{comment}'",
)
filename = comment.split(" ", 1)[1]
out.write(f"-- Begin src/{filename}\n\n")
read_file(repo_root / "src" / filename, out)
out.write(f"-- End src/{filename}\n\n")
continue

# enum
if header[0].startswith("@exposeenum "):
if len(header) > 1:
Expand All @@ -270,7 +257,7 @@ def read_file(path: Path, out: TextIOWrapper):
continue

# class
if header[0].startswith("@lua@class "):
elif header[0].startswith("@lua@class "):
name = header[0].split(" ", 1)[1]
classname = name.split(":")[0].strip()
printmsg(path, reader.line_no(), f"class {classname}")
Expand Down Expand Up @@ -311,11 +298,29 @@ def read_file(path: Path, out: TextIOWrapper):
for func in funcs:
write_func(path, reader.line_no(), func, out)
continue

# global function
if header[-1].startswith("@exposed "):
elif header[-1].startswith("@exposed "):
write_func(path, reader.line_no(), doc_comment, out)
continue
else:
for comment in header:
inline_command(path, reader.line_no(), comment, out)


def inline_command(path: Path, line: int, comment: str, out: TextIOWrapper):
if comment.startswith("@includefile "):
filename = comment.split(" ", 1)[1]
out.write(f"-- Begin src/{filename}\n\n")
read_file(repo_root / "src" / filename, out)
out.write(f"-- End src/{filename}\n\n")
elif comment.startswith("@lua@class"):
panic(
path,
line,
"Unexpected @lua@class command. @lua@class must be placed at the start of the comment block!",
)
elif comment.startswith("@lua@"):
out.write(f'---{comment.replace("@lua", "", 1)}\n')


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion src/common/Channel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class Channel : public std::enable_shared_from_this<Channel>
public:
// This is for Lua. See scripts/make_luals_meta.py
/**
* @exposeenum ChannelType
* @exposeenum c2.ChannelType
*/
enum class Type {
None,
Expand Down
2 changes: 1 addition & 1 deletion src/controllers/plugins/LuaAPI.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ enum class EventType {
/**
* @lua@class CommandContext
* @lua@field words string[] The words typed when executing the command. For example `/foo bar baz` will result in `{"/foo", "bar", "baz"}`.
* @lua@field channel Channel The channel the command was executed in.
* @lua@field channel c2.Channel The channel the command was executed in.
*/

/**
Expand Down
Loading
Loading