Lua: Add LocalSocket

Change-Id: I6601914176667100ad9007fa5e54f6d6c3f445a0
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
Marcus Tillmanns
2024-07-16 14:34:51 +02:00
parent 3dfd1dd1a9
commit 0e75f3f4f3
5 changed files with 160 additions and 0 deletions

View File

@@ -15,6 +15,7 @@ add_qtc_plugin(Lua
bindings/inheritance.h
bindings/install.cpp
bindings/json.cpp
bindings/localsocket.cpp
bindings/messagemanager.cpp
bindings/qtcprocess.cpp
bindings/settings.cpp
@@ -35,6 +36,7 @@ add_qtc_plugin(Lua
meta/gui.lua
meta/json.lua
meta/install.lua
meta/localsocket.lua
meta/lsp.lua
meta/messagemanager.lua
meta/process.lua

View File

@@ -0,0 +1,112 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "../luaengine.h"
#include <QLocalSocket>
#include <QTimer>
namespace Lua::Internal {
class LocalSocket : public QLocalSocket
{
public:
using QLocalSocket::QLocalSocket;
};
void addLocalSocketModule()
{
LuaEngine::registerProvider("LocalSocket", [](sol::state_view lua) -> sol::object {
sol::table async = lua.script("return require('async')", "_localsocket_").get<sol::table>();
sol::function wrap = async["wrap"];
sol::table result = lua.create_table();
sol::usertype<LocalSocket> socketType
= result.new_usertype<LocalSocket>("LocalSocket", sol::no_constructor);
result["create"] = [lua](const QString &name) {
auto socket = std::make_unique<LocalSocket>();
socket->setServerName(name);
return socket;
};
socketType["isConnected"] = [](LocalSocket *socket) {
return socket->state() == QLocalSocket::ConnectedState;
};
socketType["connectToServer_cb"] = [](LocalSocket *socket, sol::function cb) {
if (socket->state() != QLocalSocket::UnconnectedState)
throw sol::error("socket is not in UnconnectedState");
auto connection = new QMetaObject::Connection;
auto connectionError = new QMetaObject::Connection;
*connection = QObject::connect(
socket, &QLocalSocket::connected, socket, [connectionError, connection, cb]() {
qDebug() << "CONNECTED";
auto res = LuaEngine::void_safe_call(cb, true);
QTC_CHECK_EXPECTED(res);
QObject::disconnect(*connection);
delete connection;
QObject::disconnect(*connectionError);
delete connectionError;
});
*connectionError = QObject::connect(
socket,
&QLocalSocket::errorOccurred,
socket,
[socket, connection, connectionError, cb]() {
qDebug() << "CONNECT ERROR";
auto res = LuaEngine::void_safe_call(cb, false, socket->errorString());
QTC_CHECK_EXPECTED(res);
QObject::disconnect(*connection);
delete connection;
QObject::disconnect(*connectionError);
delete connectionError;
});
socket->connectToServer();
};
socketType["connectToServer"]
= wrap(socketType["connectToServer_cb"].get<sol::function>()).get<sol::function>();
socketType["write"] = [](LocalSocket *socket, const std::string &data) {
if (socket->state() != QLocalSocket::ConnectedState)
throw sol::error("socket is not in ConnectedState");
return socket->write(data.c_str(), data.size());
};
socketType["read_cb"] = [](LocalSocket *socket, sol::function cb) {
if (socket->state() != QLocalSocket::ConnectedState)
throw sol::error("socket is not in ConnectedState");
if (socket->bytesAvailable() > 0) {
QTimer::singleShot(0, [cb, socket]() {
LuaEngine::void_safe_call(cb, socket->readAll().toStdString());
});
return;
}
auto connection = new QMetaObject::Connection;
*connection = QObject::connect(
socket, &QLocalSocket::readyRead, socket, [connection, cb, socket]() {
auto res = LuaEngine::void_safe_call(cb, socket->readAll().toStdString());
QTC_CHECK_EXPECTED(res);
QObject::disconnect(*connection);
delete connection;
});
};
socketType["read"] = wrap(socketType["read_cb"].get<sol::function>()).get<sol::function>();
socketType["close"] = [](LocalSocket *socket) { socket->close(); };
return result;
});
}
} // namespace Lua::Internal

View File

@@ -41,6 +41,7 @@ QtcPlugin {
"inheritance.h",
"install.cpp",
"json.cpp"
"localsocket.cpp",
"messagemanager.cpp",
"qtcprocess.cpp",
"settings.cpp",
@@ -71,6 +72,7 @@ QtcPlugin {
"gui.lua",
"install.lua",
"json.lua",
"localsocket.lua",
"lsp.lua",
"messagemanager.lua",
"process.lua",

View File

@@ -41,6 +41,7 @@ void addGuiModule();
void addHookModule();
void addInstallModule();
void addJsonModule();
void addLocalSocketModule();
void addMessageManagerModule();
void addProcessModule();
void addQtModule();
@@ -256,6 +257,7 @@ public:
addHookModule();
addInstallModule();
addJsonModule();
addLocalSocketModule();
addMessageManagerModule();
addProcessModule();
addQtModule();

View File

@@ -0,0 +1,42 @@
---@meta LocalSocket
---@class LocalSocket
LocalSocket = {}
---Creates a new Socket to the given socketFileName
---@param socketFileName string The name of the socket file.
---@return LocalSocket localSocket The created socket.
function LocalSocket.create(socketFileName) end
---Returns true if the socket is connected.
---@return boolean isConnected True if the socket is connected.
function LocalSocket:isConnected() end
---@async
---Connects the socket to the server.
---@return boolean success True if the connection was successful.
---@return string errorString The error string if the connection failed.
function LocalSocket:connectToServer() end
---Connects the socket to the server
---@param callback function The callback function. The callback function should take two arguments: success (boolean) and errorString (string).
function LocalSocket:connectToServer_cb(callback) end
---Sends the data to the server.
---@param data string The data to send.
---@return integer bytesWritten The number of bytes written.
function LocalSocket:write(data) end
---@async
---Reads the data from the server. Waits until data is available.
---@return string data The data read from the server.
function LocalSocket:read() end
---Reads the data from the server. Calls "callback" once data is available.
---@param callback function The callback function. The callback function should take one argument: data (string).
function LocalSocket:read_cb(callback) end
---Closes the socket.
function LocalSocket:close() end
return LocalSocket