Files
logos-cpp-sdk/cpp/logos_api_consumer.cpp

162 lines
6.2 KiB
C++
Raw Permalink Normal View History

2025-09-30 14:56:47 -04:00
#include "logos_api_consumer.h"
#include "logos_object.h"
2025-09-30 14:56:47 -04:00
#include "module_proxy.h"
#include "logos_api_client.h"
#include "token_manager.h"
#include "logos_mode.h"
2026-03-17 01:43:39 +11:00
#include "logos_instance.h"
#include "logos_transport.h"
#include "logos_transport_factory.h"
2025-09-30 14:56:47 -04:00
#include <QDebug>
#include <QUrl>
#include <QMetaObject>
#include <QTimer>
2025-09-30 14:56:47 -04:00
#include <QTime>
2026-04-08 18:27:21 -03:00
#include <QPointer>
2025-09-30 14:56:47 -04:00
LogosAPIConsumer::LogosAPIConsumer(const QString& module_to_talk_to, const QString& origin_module, TokenManager* token_manager, QObject *parent)
: QObject(parent)
2026-03-17 01:43:39 +11:00
, m_registryUrl(LogosInstance::id(module_to_talk_to))
2025-09-30 14:56:47 -04:00
, m_token_manager(token_manager)
{
m_transport = LogosTransportFactory::createConnection(m_registryUrl);
m_transport->connectToHost();
2025-09-30 14:56:47 -04:00
}
LogosAPIConsumer::~LogosAPIConsumer()
{
}
LogosObject* LogosAPIConsumer::requestObject(const QString& objectName, Timeout timeout)
2025-09-30 14:56:47 -04:00
{
qDebug() << "LogosAPIConsumer: Requesting object:" << objectName << "at" << QTime::currentTime().toString("hh:mm:ss.zzz");
if (objectName.isEmpty()) {
qWarning() << "LogosAPIConsumer: Object name cannot be empty";
return nullptr;
}
if (!m_transport->isConnected()) {
qWarning() << "LogosAPIConsumer: Not connected to registry. Cannot request object:" << objectName;
return nullptr;
}
LogosObject* object = m_transport->requestObject(objectName, timeout.ms);
if (object) {
qDebug() << "[LogosObject] LogosAPIConsumer: acquired LogosObject for:" << objectName << "(id:" << object->id() << ")";
2025-09-30 14:56:47 -04:00
}
return object;
2025-09-30 14:56:47 -04:00
}
bool LogosAPIConsumer::isConnected() const
{
return m_transport->isConnected();
2025-09-30 14:56:47 -04:00
}
QString LogosAPIConsumer::registryUrl() const
{
return m_registryUrl;
}
bool LogosAPIConsumer::reconnect()
{
qDebug() << "LogosAPIConsumer: Attempting to reconnect to registry:" << m_registryUrl;
return m_transport->reconnect();
2025-09-30 14:56:47 -04:00
}
QVariant LogosAPIConsumer::invokeRemoteMethod(const QString& authToken, const QString& objectName, const QString& methodName,
const QVariantList& args, Timeout timeout)
2025-09-30 14:56:47 -04:00
{
qDebug() << "LogosAPIConsumer: Calling invokeRemoteMethod:" << objectName << methodName << "args_count:" << args.size() << "timeout:" << timeout.ms;
2025-09-30 14:56:47 -04:00
LogosObject* plugin = m_transport->requestObject(objectName, timeout.ms);
if (!plugin) {
qWarning() << "LogosAPIConsumer: Failed to acquire plugin/replica for object:" << objectName;
2025-09-30 14:56:47 -04:00
return QVariant();
}
qDebug() << "[LogosObject] LogosAPIConsumer: calling via LogosObject::callMethod" << methodName;
QVariant result = plugin->callMethod(authToken, methodName, args, timeout.ms);
plugin->release();
return result;
2025-09-30 14:56:47 -04:00
}
void LogosAPIConsumer::invokeRemoteMethodAsync(const QString& authToken, const QString& objectName, const QString& methodName,
const QVariantList& args,
AsyncResultCallback callback,
Timeout timeout)
{
if (!callback) {
qWarning() << "LogosAPIConsumer: invokeRemoteMethodAsync called with null callback";
return;
}
LogosObject* plugin = m_transport->requestObject(objectName, timeout.ms);
if (!plugin) {
qWarning() << "LogosAPIConsumer: Failed to acquire plugin/replica for object:" << objectName;
QTimer::singleShot(0, this, [callback]() { callback(QVariant()); });
return;
}
2026-04-08 18:00:46 -03:00
qDebug() << "[LogosObject] LogosAPIConsumer: async calling via LogosObject::callMethodAsync" << methodName;
2026-04-08 18:27:21 -03:00
// QPointer guards against use-after-free: if the consumer is destroyed
// before the transport callback fires, the callback is silently dropped.
// No re-queuing needed -- the transport already delivers on a deferred
// event-loop iteration (QTimer / QueuedConnection).
QPointer<LogosAPIConsumer> self(this);
2026-04-08 18:00:46 -03:00
plugin->callMethodAsync(authToken, methodName, args, timeout.ms,
2026-04-08 18:27:21 -03:00
[plugin, callback, self](QVariant result) {
2026-04-08 18:00:46 -03:00
plugin->release();
2026-04-08 18:27:21 -03:00
if (!self) return;
2026-04-08 18:00:46 -03:00
callback(result);
});
}
void LogosAPIConsumer::onEvent(LogosObject* originObject, const QString& eventName, std::function<void(const QString&, const QVariantList&)> callback)
{
qDebug() << "[LogosObject] LogosAPIConsumer::onEvent registering for:" << eventName << "on LogosObject id:" << originObject;
if (!originObject) {
qWarning() << "LogosAPIConsumer: Cannot register event on null object";
return;
}
originObject->onEvent(eventName, std::move(callback));
qDebug() << "[LogosObject] LogosAPIConsumer: event callback registered for:" << eventName;
2025-09-30 14:56:47 -04:00
}
bool LogosAPIConsumer::informModuleToken(const QString& authToken, const QString& moduleName, const QString& token)
{
qDebug() << "LogosAPIConsumer: Informing module token for module:" << moduleName << "with token:" << token;
LogosObject* plugin = m_transport->requestObject("capability_module", 20000);
if (!plugin) {
qWarning() << "LogosAPIConsumer: Failed to acquire plugin/replica for object: capability_module";
return false;
}
qDebug() << "[LogosObject] LogosAPIConsumer: calling LogosObject::informModuleToken for" << moduleName;
bool result = plugin->informModuleToken(authToken, moduleName, token, 20000);
2025-09-30 14:56:47 -04:00
qDebug() << "LogosAPIConsumer: informModuleToken completed with result:" << result;
plugin->release();
return result;
2025-09-30 14:56:47 -04:00
}
bool LogosAPIConsumer::informModuleToken_module(const QString& authToken, const QString& originModule, const QString& moduleName, const QString& token)
{
qDebug() << "LogosAPIConsumer: Informing module token for module:" << moduleName << "with token:" << token;
LogosObject* plugin = m_transport->requestObject(originModule, 20000);
if (!plugin) {
qWarning() << "LogosAPIConsumer: Failed to acquire plugin/replica for object:" << originModule;
2025-09-30 14:56:47 -04:00
return false;
}
qDebug() << "[LogosObject] LogosAPIConsumer: calling LogosObject::informModuleToken for" << moduleName << "on" << originModule;
bool result = plugin->informModuleToken(authToken, moduleName, token, 20000);
2025-09-30 14:56:47 -04:00
qDebug() << "LogosAPIConsumer: informModuleToken completed with result:" << result;
plugin->release();
return result;
2025-09-30 14:56:47 -04:00
}