1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
// 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 setupLocalSocketModule()
{
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");
QObject::connect(socket, &QLocalSocket::connected, socket, [socket, cb] {
qDebug() << "CONNECTED";
auto res = void_safe_call(cb, true);
QTC_CHECK_RESULT(res);
QObject::disconnect(socket, &QLocalSocket::errorOccurred, socket, nullptr);
}, Qt::SingleShotConnection);
QObject::connect(socket, &QLocalSocket::errorOccurred, socket, [socket, cb] {
qDebug() << "CONNECT ERROR";
auto res = void_safe_call(cb, false, socket->errorString());
QTC_CHECK_RESULT(res);
QObject::disconnect(socket, &QLocalSocket::connected, socket, nullptr);
}, Qt::SingleShotConnection);
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]() {
void_safe_call(cb, socket->readAll().toStdString());
});
return;
}
QObject::connect(socket, &QLocalSocket::readyRead, socket, [socket, cb] {
auto res = void_safe_call(cb, socket->readAll().toStdString());
QTC_CHECK_RESULT(res);
}, Qt::SingleShotConnection);
};
socketType["read"] = wrap(socketType["read_cb"].get<sol::function>()).get<sol::function>();
socketType["close"] = [](LocalSocket *socket) { socket->close(); };
return result;
});
}
} // namespace Lua::Internal
|