mirror of
https://github.com/logos-co/logos-cpp-sdk.git
synced 2026-08-31 09:41:06 +00:00
Finish Abstraction & Refactor (Ongoing) - part 1 (#25)
* refactor: abstract connection/transport; and clearly separate qt remote obj and qt local into separate implementations * abstract qt remote registry * add mock implementation; these serves to further test the abstraction but also useful for testing modules later * use LogosObject instead of QObject * abstract provider side * updates to use new api * re-add async api back --------- Co-authored-by: Logos Workspace <logos@workspace.local>
This commit is contained in:
co-authored by
Logos Workspace
parent
4b66dac015
commit
4197ee1830
+66
-63
@@ -1,32 +1,31 @@
|
||||
#include "logos_api_provider.h"
|
||||
#include "logos_object.h"
|
||||
#include "logos_provider_object.h"
|
||||
#include "qt_provider_object.h"
|
||||
#include "module_proxy.h"
|
||||
#include "logos_api.h"
|
||||
#include "logos_mode.h"
|
||||
#include "logos_instance.h"
|
||||
#include "plugin_registry.h"
|
||||
#include <QRemoteObjectRegistryHost>
|
||||
#include "logos_transport.h"
|
||||
#include "logos_transport_factory.h"
|
||||
#include <QDebug>
|
||||
#include <QUrl>
|
||||
#include <QMetaObject>
|
||||
#include <QString>
|
||||
|
||||
LogosAPIProvider::LogosAPIProvider(const QString& module_name, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_registryHost(nullptr)
|
||||
, m_registryUrl(LogosInstance::id(module_name))
|
||||
, m_moduleProxy(nullptr)
|
||||
, m_qtProviderObject(nullptr)
|
||||
{
|
||||
m_transport = LogosTransportFactory::createHost(m_registryUrl);
|
||||
}
|
||||
|
||||
LogosAPIProvider::~LogosAPIProvider()
|
||||
{
|
||||
if (LogosModeConfig::isLocal() && !m_registeredObjectName.isEmpty()) {
|
||||
PluginRegistry::unregisterPlugin(m_registeredObjectName);
|
||||
if (!m_registeredObjectName.isEmpty()) {
|
||||
m_transport->unpublishObject(m_registeredObjectName);
|
||||
}
|
||||
// QRemoteObjectRegistryHost will be deleted automatically as it's a child object
|
||||
// ModuleProxy will be deleted automatically as it's a child object
|
||||
}
|
||||
|
||||
// QObject* path: auto-detects LogosProviderPlugin; falls back to QtProviderObject wrapper
|
||||
bool LogosAPIProvider::registerObject(const QString& name, QObject* object)
|
||||
{
|
||||
if (!object) {
|
||||
@@ -39,57 +38,66 @@ bool LogosAPIProvider::registerObject(const QString& name, QObject* object)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if a ModuleProxy was already created - only allow one registration
|
||||
if (m_moduleProxy) {
|
||||
qCritical() << "LogosAPIProvider: Object already registered. Only one registration per provider is allowed";
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "LogosAPIProvider: Creating ModuleProxy for" << name << "wrapping the provided object";
|
||||
|
||||
// Before wrapping with ModuleProxy, call initLogos if the method exists
|
||||
// Check if the object has an initLogos method and call it with the parent (LogosAPI instance)
|
||||
int methodIndex = object->metaObject()->indexOfMethod("initLogos(LogosAPI*)");
|
||||
if (methodIndex != -1) {
|
||||
qDebug() << "LogosAPIProvider: Calling initLogos on object before wrapping";
|
||||
bool methodSuccess = QMetaObject::invokeMethod(object, "initLogos",
|
||||
Qt::DirectConnection,
|
||||
Q_ARG(LogosAPI*, qobject_cast<LogosAPI*>(parent())));
|
||||
if (methodSuccess) {
|
||||
qDebug() << "LogosAPIProvider: Successfully called initLogos on object";
|
||||
} else {
|
||||
qWarning() << "LogosAPIProvider: Failed to call initLogos on object";
|
||||
// Check if this plugin implements LogosProviderPlugin (new API)
|
||||
LogosProviderPlugin* providerPlugin = qobject_cast<LogosProviderPlugin*>(object);
|
||||
if (providerPlugin) {
|
||||
qDebug() << "[LogosProviderObject] LogosAPIProvider: detected LogosProviderPlugin for" << name;
|
||||
LogosProviderObject* provider = providerPlugin->createProviderObject();
|
||||
if (provider) {
|
||||
return registerObject(name, provider);
|
||||
}
|
||||
} else {
|
||||
qDebug() << "LogosAPIProvider: Object does not have initLogos method, skipping";
|
||||
qWarning() << "LogosAPIProvider: createProviderObject() returned null for" << name;
|
||||
}
|
||||
|
||||
m_moduleProxy = new ModuleProxy(object, this);
|
||||
object = m_moduleProxy;
|
||||
// Legacy path: wrap QObject in QtProviderObject adapter
|
||||
qDebug() << "[LogosProviderObject] LogosAPIProvider: wrapping QObject in QtProviderObject for" << name;
|
||||
|
||||
bool success = false;
|
||||
m_qtProviderObject = new QtProviderObject(object, this);
|
||||
m_qtProviderObject->init(qobject_cast<LogosAPI*>(parent()));
|
||||
|
||||
if (LogosModeConfig::isLocal()) {
|
||||
PluginRegistry::registerPlugin(object, name);
|
||||
return publishProvider(name, m_qtProviderObject);
|
||||
}
|
||||
|
||||
// New path: LogosProviderObject* -> ModuleProxy -> transport
|
||||
bool LogosAPIProvider::registerObject(const QString& name, LogosProviderObject* provider)
|
||||
{
|
||||
if (!provider) {
|
||||
qWarning() << "LogosAPIProvider: Cannot register null provider";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name.isEmpty()) {
|
||||
qWarning() << "LogosAPIProvider: Cannot register provider with empty name";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_moduleProxy) {
|
||||
qCritical() << "LogosAPIProvider: Object already registered. Only one registration per provider is allowed";
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "[LogosProviderObject] LogosAPIProvider: registering LogosProviderObject directly for" << name;
|
||||
|
||||
provider->init(qobject_cast<LogosAPI*>(parent()));
|
||||
|
||||
return publishProvider(name, provider);
|
||||
}
|
||||
|
||||
bool LogosAPIProvider::publishProvider(const QString& name, LogosProviderObject* provider)
|
||||
{
|
||||
m_moduleProxy = new ModuleProxy(provider, this);
|
||||
|
||||
bool success = m_transport->publishObject(name, m_moduleProxy);
|
||||
if (success) {
|
||||
m_registeredObjectName = name;
|
||||
success = true;
|
||||
qDebug() << "LogosAPIProvider: Successfully registered object with name:" << name;
|
||||
qDebug() << "[LogosProviderObject] LogosAPIProvider: successfully published" << name;
|
||||
} else {
|
||||
if (!m_registryHost) {
|
||||
m_registryHost = new QRemoteObjectRegistryHost(QUrl(m_registryUrl));
|
||||
if (!m_registryHost) {
|
||||
qCritical() << "LogosAPIProvider: Failed to create registry host";
|
||||
return false;
|
||||
}
|
||||
qDebug() << "LogosAPIProvider: Created registry host with URL:" << m_registryUrl;
|
||||
}
|
||||
|
||||
success = m_registryHost->enableRemoting(object, name);
|
||||
if (success) {
|
||||
qDebug() << "LogosAPIProvider: Successfully registered object with name:" << name;
|
||||
} else {
|
||||
qCritical() << "LogosAPIProvider: Failed to register object with name:" << name;
|
||||
}
|
||||
qCritical() << "LogosAPIProvider: Failed to publish" << name;
|
||||
}
|
||||
|
||||
return success;
|
||||
@@ -107,27 +115,22 @@ bool LogosAPIProvider::saveToken(const QString& from_module_name, const QString&
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "LogosAPIProvider: Delegating saveToken call to module proxy for module:" << from_module_name;
|
||||
qDebug() << "LogosAPIProvider: Delegating saveToken to module proxy for:" << from_module_name;
|
||||
return m_moduleProxy->saveToken(from_module_name, token);
|
||||
}
|
||||
|
||||
void LogosAPIProvider::onEventResponse(QObject* replica, const QString& eventName, const QVariantList& data)
|
||||
void LogosAPIProvider::onEventResponse(LogosObject* object, const QString& eventName, const QVariantList& data)
|
||||
{
|
||||
// qDebug() << "LogosAPIProvider: Received event:" << eventName << "with data:" << data;
|
||||
qDebug() << "LogosAPIProvider: Received event:" << eventName;
|
||||
qDebug() << "[LogosObject] LogosAPIProvider::onEventResponse" << eventName << "-> LogosObject::emitEvent";
|
||||
|
||||
if (eventName.isEmpty()) {
|
||||
qWarning() << "LogosAPIProvider: Event name cannot be empty";
|
||||
return;
|
||||
}
|
||||
if (!object) {
|
||||
qWarning() << "LogosAPIProvider: Cannot emit event on null object";
|
||||
return;
|
||||
}
|
||||
|
||||
// qDebug() << "LogosAPIProvider: Emitting event:" << eventName << "with data:" << data;
|
||||
qDebug() << "LogosAPIProvider: Emitting event:" << eventName;
|
||||
|
||||
// emit the eventResponse signal of replica
|
||||
QMetaObject::invokeMethod(replica, "eventResponse", Qt::QueuedConnection, Q_ARG(QString, eventName), Q_ARG(QVariantList, data));
|
||||
// QMetaObject::invokeMethod(replica, "eventResponse_another", Qt::QueuedConnection, Q_ARG(QString, eventName), Q_ARG(QVariantList, data));
|
||||
// TODO: try queued connection instead
|
||||
// QMetaObject::invokeMethod(replica, "eventResponse_another", Qt::DirectConnection, Q_ARG(QString, eventName), Q_ARG(QVariantList, data));
|
||||
object->emitEvent(eventName, data);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user