Skip to content

Commit c3822c7

Browse files
committed
refactor: abstract connection/transport; and clearly separate qt remote obj and qt local into separate implementations
1 parent 95f763b commit c3822c7

13 files changed

+635
-319
lines changed

cpp/CMakeLists.txt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ set(SDK_SOURCES
2727
token_manager.h
2828
logos_mode.h
2929
plugin_registry.h
30+
logos_transport.h
31+
logos_transport_factory.cpp
32+
logos_transport_factory.h
33+
implementations/qt_local/local_transport.cpp
34+
implementations/qt_local/local_transport.h
35+
implementations/qt_remote/remote_transport.cpp
36+
implementations/qt_remote/remote_transport.h
3037
)
3138

3239
# Create the SDK library as STATIC instead of SHARED
@@ -38,6 +45,8 @@ target_link_libraries(logos_sdk PUBLIC Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSIO
3845
# Include directories
3946
target_include_directories(logos_sdk PUBLIC
4047
${CMAKE_CURRENT_SOURCE_DIR}
48+
${CMAKE_CURRENT_SOURCE_DIR}/implementations/qt_local
49+
${CMAKE_CURRENT_SOURCE_DIR}/implementations/qt_remote
4150
)
4251

4352
# Set output directories for static library
@@ -63,5 +72,17 @@ install(FILES
6372
token_manager.h
6473
logos_mode.h
6574
plugin_registry.h
75+
logos_transport.h
76+
logos_transport_factory.h
6677
DESTINATION include
67-
)
78+
)
79+
80+
install(FILES
81+
implementations/qt_local/local_transport.h
82+
DESTINATION include/implementations/qt_local
83+
)
84+
85+
install(FILES
86+
implementations/qt_remote/remote_transport.h
87+
DESTINATION include/implementations/qt_remote
88+
)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#include "local_transport.h"
2+
#include "../../plugin_registry.h"
3+
#include "../../module_proxy.h"
4+
#include <QDebug>
5+
6+
// --- LocalTransportHost ---
7+
8+
bool LocalTransportHost::publishObject(const QString& name, QObject* object)
9+
{
10+
PluginRegistry::registerPlugin(object, name);
11+
qDebug() << "LocalTransportHost: Published object:" << name;
12+
return true;
13+
}
14+
15+
void LocalTransportHost::unpublishObject(const QString& name)
16+
{
17+
if (!name.isEmpty()) {
18+
PluginRegistry::unregisterPlugin(name);
19+
qDebug() << "LocalTransportHost: Unpublished object:" << name;
20+
}
21+
}
22+
23+
// --- LocalTransportConnection ---
24+
25+
bool LocalTransportConnection::connectToHost()
26+
{
27+
qDebug() << "LocalTransportConnection: Local mode - no connection needed";
28+
return true;
29+
}
30+
31+
bool LocalTransportConnection::isConnected() const
32+
{
33+
return true;
34+
}
35+
36+
bool LocalTransportConnection::reconnect()
37+
{
38+
return true;
39+
}
40+
41+
QObject* LocalTransportConnection::requestObject(const QString& objectName, int /*timeoutMs*/)
42+
{
43+
QObject* plugin = PluginRegistry::getPlugin<QObject>(objectName);
44+
if (!plugin) {
45+
qWarning() << "LocalTransportConnection: Plugin not found in registry:" << objectName;
46+
return nullptr;
47+
}
48+
qDebug() << "LocalTransportConnection: Found plugin:" << objectName;
49+
return plugin;
50+
}
51+
52+
void LocalTransportConnection::releaseObject(QObject* /*object*/)
53+
{
54+
// Local mode: we don't own the object, so nothing to do
55+
}
56+
57+
QVariant LocalTransportConnection::callRemoteMethod(QObject* object, const QString& authToken,
58+
const QString& methodName, const QVariantList& args,
59+
int /*timeoutMs*/)
60+
{
61+
if (!object) {
62+
qWarning() << "LocalTransportConnection: Cannot call method on null object";
63+
return QVariant();
64+
}
65+
66+
ModuleProxy* proxy = qobject_cast<ModuleProxy*>(object);
67+
if (!proxy) {
68+
qWarning() << "LocalTransportConnection: Object is not a ModuleProxy";
69+
return QVariant();
70+
}
71+
72+
return proxy->callRemoteMethod(authToken, methodName, args);
73+
}
74+
75+
bool LocalTransportConnection::callInformModuleToken(QObject* object, const QString& authToken,
76+
const QString& moduleName, const QString& token,
77+
int /*timeoutMs*/)
78+
{
79+
if (!object) {
80+
qWarning() << "LocalTransportConnection: Cannot call informModuleToken on null object";
81+
return false;
82+
}
83+
84+
ModuleProxy* proxy = qobject_cast<ModuleProxy*>(object);
85+
if (!proxy) {
86+
qWarning() << "LocalTransportConnection: Object is not a ModuleProxy";
87+
return false;
88+
}
89+
90+
return proxy->informModuleToken(authToken, moduleName, token);
91+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#ifndef LOCAL_TRANSPORT_H
2+
#define LOCAL_TRANSPORT_H
3+
4+
#include "../../logos_transport.h"
5+
6+
class LocalTransportHost : public LogosTransportHost {
7+
public:
8+
bool publishObject(const QString& name, QObject* object) override;
9+
void unpublishObject(const QString& name) override;
10+
};
11+
12+
class LocalTransportConnection : public LogosTransportConnection {
13+
public:
14+
bool connectToHost() override;
15+
bool isConnected() const override;
16+
bool reconnect() override;
17+
QObject* requestObject(const QString& objectName, int timeoutMs) override;
18+
void releaseObject(QObject* object) override;
19+
QVariant callRemoteMethod(QObject* object, const QString& authToken,
20+
const QString& methodName, const QVariantList& args,
21+
int timeoutMs) override;
22+
bool callInformModuleToken(QObject* object, const QString& authToken,
23+
const QString& moduleName, const QString& token,
24+
int timeoutMs) override;
25+
};
26+
27+
#endif // LOCAL_TRANSPORT_H
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
#include "remote_transport.h"
2+
#include <QRemoteObjectRegistryHost>
3+
#include <QRemoteObjectNode>
4+
#include <QRemoteObjectReplica>
5+
#include <QRemoteObjectPendingCall>
6+
#include <QDebug>
7+
#include <QUrl>
8+
#include <QMetaObject>
9+
#include <QTime>
10+
11+
// --- RemoteTransportHost ---
12+
13+
RemoteTransportHost::RemoteTransportHost(const QString& registryUrl)
14+
: m_registryHost(nullptr)
15+
, m_registryUrl(registryUrl)
16+
{
17+
}
18+
19+
RemoteTransportHost::~RemoteTransportHost()
20+
{
21+
delete m_registryHost;
22+
}
23+
24+
bool RemoteTransportHost::publishObject(const QString& name, QObject* object)
25+
{
26+
if (!m_registryHost) {
27+
m_registryHost = new QRemoteObjectRegistryHost(QUrl(m_registryUrl));
28+
if (!m_registryHost) {
29+
qCritical() << "RemoteTransportHost: Failed to create registry host";
30+
return false;
31+
}
32+
qDebug() << "RemoteTransportHost: Created registry host with URL:" << m_registryUrl;
33+
}
34+
35+
bool success = m_registryHost->enableRemoting(object, name);
36+
if (success) {
37+
qDebug() << "RemoteTransportHost: Published object:" << name;
38+
} else {
39+
qCritical() << "RemoteTransportHost: Failed to publish object:" << name;
40+
}
41+
return success;
42+
}
43+
44+
void RemoteTransportHost::unpublishObject(const QString& /*name*/)
45+
{
46+
// Qt Remote Objects doesn't require explicit unregistration;
47+
// the host cleanup handles it on destruction.
48+
}
49+
50+
// --- RemoteTransportConnection ---
51+
52+
RemoteTransportConnection::RemoteTransportConnection(const QString& registryUrl)
53+
: m_node(new QRemoteObjectNode())
54+
, m_registryUrl(registryUrl)
55+
, m_connected(false)
56+
{
57+
}
58+
59+
RemoteTransportConnection::~RemoteTransportConnection()
60+
{
61+
delete m_node;
62+
}
63+
64+
bool RemoteTransportConnection::connectToHost()
65+
{
66+
return connectToRegistry();
67+
}
68+
69+
bool RemoteTransportConnection::isConnected() const
70+
{
71+
return m_connected;
72+
}
73+
74+
bool RemoteTransportConnection::reconnect()
75+
{
76+
qDebug() << "RemoteTransportConnection: Attempting to reconnect to registry:" << m_registryUrl;
77+
78+
if (m_connected) {
79+
delete m_node;
80+
m_node = new QRemoteObjectNode();
81+
m_connected = false;
82+
}
83+
84+
return connectToRegistry();
85+
}
86+
87+
bool RemoteTransportConnection::connectToRegistry()
88+
{
89+
if (!m_node) {
90+
qWarning() << "RemoteTransportConnection: Remote object node is null";
91+
return false;
92+
}
93+
94+
if (m_registryUrl.isEmpty()) {
95+
qWarning() << "RemoteTransportConnection: Registry URL is empty";
96+
return false;
97+
}
98+
99+
qDebug() << "RemoteTransportConnection: Connecting to registry:" << m_registryUrl
100+
<< "at" << QTime::currentTime().toString("hh:mm:ss.zzz");
101+
102+
QUrl url(m_registryUrl);
103+
bool success = m_node->connectToNode(url);
104+
105+
if (success) {
106+
m_connected = true;
107+
qDebug() << "RemoteTransportConnection: Successfully connected to registry:" << m_registryUrl;
108+
} else {
109+
m_connected = false;
110+
qWarning() << "RemoteTransportConnection: Failed to connect to registry:" << m_registryUrl;
111+
}
112+
qDebug() << "RemoteTransportConnection: Connected to registry at"
113+
<< QTime::currentTime().toString("hh:mm:ss.zzz");
114+
115+
return m_connected;
116+
}
117+
118+
QObject* RemoteTransportConnection::requestObject(const QString& objectName, int timeoutMs)
119+
{
120+
if (!m_connected) {
121+
qWarning() << "RemoteTransportConnection: Not connected. Cannot request object:" << objectName;
122+
return nullptr;
123+
}
124+
125+
qDebug() << "RemoteTransportConnection: Requesting object:" << objectName
126+
<< "at" << QTime::currentTime().toString("hh:mm:ss.zzz");
127+
128+
QRemoteObjectReplica* replica = m_node->acquireDynamic(objectName);
129+
if (!replica) {
130+
qWarning() << "RemoteTransportConnection: Failed to acquire replica for:" << objectName;
131+
return nullptr;
132+
}
133+
134+
if (!replica->waitForSource(timeoutMs)) {
135+
qWarning() << "RemoteTransportConnection: Timeout waiting for replica:" << objectName;
136+
delete replica;
137+
return nullptr;
138+
}
139+
140+
qDebug() << "RemoteTransportConnection: Acquired replica for:" << objectName
141+
<< "at" << QTime::currentTime().toString("hh:mm:ss.zzz");
142+
return replica;
143+
}
144+
145+
void RemoteTransportConnection::releaseObject(QObject* object)
146+
{
147+
delete object;
148+
}
149+
150+
QVariant RemoteTransportConnection::callRemoteMethod(QObject* object, const QString& authToken,
151+
const QString& methodName, const QVariantList& args,
152+
int timeoutMs)
153+
{
154+
if (!object) {
155+
qWarning() << "RemoteTransportConnection: Cannot call method on null object";
156+
return QVariant();
157+
}
158+
159+
QRemoteObjectPendingCall pendingCall;
160+
bool success = QMetaObject::invokeMethod(
161+
object,
162+
"callRemoteMethod",
163+
Qt::DirectConnection,
164+
Q_RETURN_ARG(QRemoteObjectPendingCall, pendingCall),
165+
Q_ARG(QString, authToken),
166+
Q_ARG(QString, methodName),
167+
Q_ARG(QVariantList, args)
168+
);
169+
170+
if (!success) {
171+
qWarning() << "RemoteTransportConnection: Failed to invoke callRemoteMethod on replica";
172+
return QVariant();
173+
}
174+
175+
pendingCall.waitForFinished(timeoutMs);
176+
177+
if (!pendingCall.isFinished() || pendingCall.error() != QRemoteObjectPendingCall::NoError) {
178+
qWarning() << "RemoteTransportConnection: callRemoteMethod failed or timed out:" << pendingCall.error();
179+
return QVariant();
180+
}
181+
182+
return pendingCall.returnValue();
183+
}
184+
185+
bool RemoteTransportConnection::callInformModuleToken(QObject* object, const QString& authToken,
186+
const QString& moduleName, const QString& token,
187+
int timeoutMs)
188+
{
189+
if (!object) {
190+
qWarning() << "RemoteTransportConnection: Cannot call informModuleToken on null object";
191+
return false;
192+
}
193+
194+
QRemoteObjectPendingCall pendingCall;
195+
bool success = QMetaObject::invokeMethod(
196+
object,
197+
"informModuleToken",
198+
Qt::DirectConnection,
199+
Q_RETURN_ARG(QRemoteObjectPendingCall, pendingCall),
200+
Q_ARG(QString, authToken),
201+
Q_ARG(QString, moduleName),
202+
Q_ARG(QString, token)
203+
);
204+
205+
if (!success) {
206+
qWarning() << "RemoteTransportConnection: Failed to invoke informModuleToken on replica";
207+
return false;
208+
}
209+
210+
pendingCall.waitForFinished(timeoutMs);
211+
212+
if (!pendingCall.isFinished() || pendingCall.error() != QRemoteObjectPendingCall::NoError) {
213+
qWarning() << "RemoteTransportConnection: informModuleToken failed or timed out:" << pendingCall.error();
214+
return false;
215+
}
216+
217+
return pendingCall.returnValue().toBool();
218+
}

0 commit comments

Comments
 (0)