mirror of
https://github.com/logos-co/logos-cpp-sdk.git
synced 2026-08-31 09:41:06 +00:00
remove proxy api (moved to logos-module-client)
This commit is contained in:
@@ -51,12 +51,6 @@ set(SDK_SOURCES
|
||||
implementations/mock/mock_transport.h
|
||||
implementations/mock/mock_registry.h
|
||||
implementations/mock/logos_mock.h
|
||||
logos_json_utils.cpp
|
||||
logos_json_utils.h
|
||||
logos_core_client.cpp
|
||||
logos_core_client.h
|
||||
logos_sdk_c.cpp
|
||||
logos_sdk_c.h
|
||||
)
|
||||
|
||||
# Create the SDK library as STATIC instead of SHARED
|
||||
@@ -104,9 +98,6 @@ install(FILES
|
||||
logos_transport_factory.h
|
||||
logos_registry.h
|
||||
logos_registry_factory.h
|
||||
logos_json_utils.h
|
||||
logos_core_client.h
|
||||
logos_sdk_c.h
|
||||
DESTINATION include
|
||||
)
|
||||
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
#include "logos_core_client.h"
|
||||
#include "logos_api.h"
|
||||
#include "logos_api_client.h"
|
||||
#include "logos_object.h"
|
||||
#include "logos_json_utils.h"
|
||||
#include <QDebug>
|
||||
|
||||
LogosCoreClient::LogosCoreClient(QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_api(new LogosAPI("core", this))
|
||||
{
|
||||
}
|
||||
|
||||
LogosCoreClient::~LogosCoreClient()
|
||||
{
|
||||
}
|
||||
|
||||
LogosAPIClient* LogosCoreClient::clientFor(const QString& pluginName)
|
||||
{
|
||||
return m_api->getClient(pluginName);
|
||||
}
|
||||
|
||||
void LogosCoreClient::callMethodAsync(const QString& pluginName,
|
||||
const QString& methodName,
|
||||
const QString& paramsJson,
|
||||
AsyncCallback callback)
|
||||
{
|
||||
if (!callback) return;
|
||||
|
||||
bool ok = false;
|
||||
QString errorMessage;
|
||||
QVariantList args = LogosJsonUtils::parseMethodParams(paramsJson, &ok, &errorMessage);
|
||||
|
||||
if (!ok) {
|
||||
callback(false, errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
LogosAPIClient* client = m_api->getClient(pluginName);
|
||||
if (!client) {
|
||||
callback(false, QString("Failed to get client for plugin: %1").arg(pluginName));
|
||||
return;
|
||||
}
|
||||
|
||||
client->invokeRemoteMethodAsync(
|
||||
pluginName, methodName, args,
|
||||
[callback, pluginName, methodName](QVariant result) {
|
||||
if (result.isValid()) {
|
||||
QString resultStr;
|
||||
if (result.canConvert<QString>()) {
|
||||
resultStr = result.toString();
|
||||
} else {
|
||||
resultStr = QString("Result of type: %1").arg(result.typeName());
|
||||
}
|
||||
callback(true, QString("Method call successful. Result: %1").arg(resultStr));
|
||||
} else {
|
||||
callback(false, QStringLiteral("Method call returned invalid result"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void LogosCoreClient::subscribeEvent(const QString& pluginName,
|
||||
const QString& eventName,
|
||||
AsyncCallback callback)
|
||||
{
|
||||
if (!callback) return;
|
||||
|
||||
LogosAPIClient* client = m_api->getClient(pluginName);
|
||||
if (!client) {
|
||||
qWarning() << "LogosCoreClient: Failed to get client for event subscription:" << pluginName;
|
||||
return;
|
||||
}
|
||||
|
||||
LogosObject* obj = client->requestObject(pluginName);
|
||||
if (!obj) {
|
||||
qWarning() << "LogosCoreClient: Failed to get object for event subscription:" << pluginName;
|
||||
return;
|
||||
}
|
||||
|
||||
client->onEvent(obj, eventName,
|
||||
[callback](const QString& evName, const QVariantList& evData) {
|
||||
QString json = LogosJsonUtils::formatEventJson(evName, evData);
|
||||
callback(true, json);
|
||||
});
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
#ifndef LOGOS_CORE_CLIENT_H
|
||||
#define LOGOS_CORE_CLIENT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
#include <QVariantList>
|
||||
#include <QHash>
|
||||
#include <functional>
|
||||
|
||||
class LogosAPI;
|
||||
class LogosAPIClient;
|
||||
class LogosObject;
|
||||
|
||||
/**
|
||||
* @brief LogosCoreClient provides a high-level async interface for calling
|
||||
* plugin methods and subscribing to events from the "core" (host) perspective.
|
||||
*
|
||||
* Unlike creating ephemeral LogosAPI instances per call, this class maintains
|
||||
* a single persistent LogosAPI("core") and reuses cached client connections.
|
||||
*
|
||||
* It uses LogosAPIClient::invokeRemoteMethodAsync for connection-aware calls,
|
||||
* eliminating manual QTimer-based connection delays.
|
||||
*/
|
||||
class LogosCoreClient : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using AsyncCallback = std::function<void(bool success, const QString& message)>;
|
||||
|
||||
explicit LogosCoreClient(QObject* parent = nullptr);
|
||||
~LogosCoreClient();
|
||||
|
||||
/**
|
||||
* Call a plugin method asynchronously, with parameters provided as a JSON
|
||||
* string in the [{name,value,type},...] format used by FFI consumers.
|
||||
* The callback receives (success, resultMessage).
|
||||
*/
|
||||
void callMethodAsync(const QString& pluginName,
|
||||
const QString& methodName,
|
||||
const QString& paramsJson,
|
||||
AsyncCallback callback);
|
||||
|
||||
/**
|
||||
* Subscribe to an event from a plugin. The callback fires each time
|
||||
* the event is emitted, with a JSON-formatted message.
|
||||
*/
|
||||
void subscribeEvent(const QString& pluginName,
|
||||
const QString& eventName,
|
||||
AsyncCallback callback);
|
||||
|
||||
/**
|
||||
* Get (or lazily create) a LogosAPIClient for the named plugin.
|
||||
*/
|
||||
LogosAPIClient* clientFor(const QString& pluginName);
|
||||
|
||||
private:
|
||||
LogosAPI* m_api;
|
||||
};
|
||||
|
||||
#endif // LOGOS_CORE_CLIENT_H
|
||||
@@ -1,115 +0,0 @@
|
||||
#include "logos_json_utils.h"
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QDebug>
|
||||
|
||||
namespace LogosJsonUtils {
|
||||
|
||||
QVariant jsonParamToVariant(const QJsonObject& param)
|
||||
{
|
||||
QString name = param.value("name").toString();
|
||||
QString value = param.value("value").toString();
|
||||
QString type = param.value("type").toString();
|
||||
|
||||
qDebug() << "LogosJsonUtils: Converting param:" << name << "value:" << value << "type:" << type;
|
||||
|
||||
if (type == "string" || type == "QString") {
|
||||
return QVariant(value);
|
||||
} else if (type == "int" || type == "integer") {
|
||||
bool ok;
|
||||
int intValue = value.toInt(&ok);
|
||||
return ok ? QVariant(intValue) : QVariant();
|
||||
} else if (type == "bool" || type == "boolean") {
|
||||
if (value.toLower() == "true" || value == "1") {
|
||||
return QVariant(true);
|
||||
} else if (value.toLower() == "false" || value == "0") {
|
||||
return QVariant(false);
|
||||
}
|
||||
return QVariant();
|
||||
} else if (type == "double" || type == "float") {
|
||||
bool ok;
|
||||
double doubleValue = value.toDouble(&ok);
|
||||
return ok ? QVariant(doubleValue) : QVariant();
|
||||
} else {
|
||||
qWarning() << "LogosJsonUtils: Unknown parameter type:" << type << "- treating as string";
|
||||
return QVariant(value);
|
||||
}
|
||||
}
|
||||
|
||||
QVariantList parseMethodParams(const QString& json, bool* ok, QString* errorMessage)
|
||||
{
|
||||
QVariantList args;
|
||||
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(json.toUtf8(), &parseError);
|
||||
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
if (ok) *ok = false;
|
||||
if (errorMessage) *errorMessage = QString("JSON parse error: %1").arg(parseError.errorString());
|
||||
return args;
|
||||
}
|
||||
|
||||
QJsonArray paramsArray = jsonDoc.array();
|
||||
|
||||
for (const QJsonValue& paramValue : paramsArray) {
|
||||
if (paramValue.isObject()) {
|
||||
QJsonObject paramObj = paramValue.toObject();
|
||||
QVariant variant = jsonParamToVariant(paramObj);
|
||||
if (variant.isValid()) {
|
||||
args.append(variant);
|
||||
} else {
|
||||
if (ok) *ok = false;
|
||||
if (errorMessage) *errorMessage = QString("Invalid parameter: %1").arg(paramObj.value("name").toString());
|
||||
return QVariantList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) *ok = true;
|
||||
return args;
|
||||
}
|
||||
|
||||
QString variantToJsonString(const QVariant& value)
|
||||
{
|
||||
if (!value.isValid())
|
||||
return QStringLiteral("null");
|
||||
|
||||
switch (value.userType()) {
|
||||
case QMetaType::Bool:
|
||||
return value.toBool() ? QStringLiteral("true") : QStringLiteral("false");
|
||||
case QMetaType::Int:
|
||||
case QMetaType::LongLong:
|
||||
return QString::number(value.toLongLong());
|
||||
case QMetaType::Double:
|
||||
case QMetaType::Float:
|
||||
return QString::number(value.toDouble());
|
||||
case QMetaType::QString:
|
||||
return value.toString();
|
||||
case QMetaType::QVariantMap: {
|
||||
QJsonDocument doc(QJsonObject::fromVariantMap(value.toMap()));
|
||||
return QString::fromUtf8(doc.toJson(QJsonDocument::Compact));
|
||||
}
|
||||
case QMetaType::QVariantList: {
|
||||
QJsonDocument doc(QJsonArray::fromVariantList(value.toList()));
|
||||
return QString::fromUtf8(doc.toJson(QJsonDocument::Compact));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
QString formatEventJson(const QString& eventName, const QVariantList& data)
|
||||
{
|
||||
QString result = QString("{\"event\":\"%1\",\"data\":[").arg(eventName);
|
||||
for (int i = 0; i < data.size(); ++i) {
|
||||
if (i > 0) result += ",";
|
||||
result += QString("\"%1\"").arg(data[i].toString());
|
||||
}
|
||||
result += "]}";
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace LogosJsonUtils
|
||||
@@ -1,44 +0,0 @@
|
||||
#ifndef LOGOS_JSON_UTILS_H
|
||||
#define LOGOS_JSON_UTILS_H
|
||||
|
||||
#include <QVariant>
|
||||
#include <QVariantList>
|
||||
#include <QString>
|
||||
#include <QJsonObject>
|
||||
|
||||
namespace LogosJsonUtils {
|
||||
|
||||
/**
|
||||
* Convert a single JSON parameter object {name, value, type} to a QVariant.
|
||||
* Supports types: string, QString, int, integer, bool, boolean, double, float.
|
||||
* Unknown types are treated as strings.
|
||||
* Returns invalid QVariant for unparseable values (e.g. "abc" as int).
|
||||
*/
|
||||
QVariant jsonParamToVariant(const QJsonObject& param);
|
||||
|
||||
/**
|
||||
* Parse a JSON string containing an array of {name, value, type} objects
|
||||
* into a QVariantList. This is the format used by FFI consumers (e.g. logos-js-sdk).
|
||||
*
|
||||
* On success, sets ok=true and returns the converted arguments.
|
||||
* On failure (JSON parse error or invalid parameter), sets ok=false and
|
||||
* fills errorMessage with a description.
|
||||
*/
|
||||
QVariantList parseMethodParams(const QString& json, bool* ok = nullptr, QString* errorMessage = nullptr);
|
||||
|
||||
/**
|
||||
* Convert a QVariant result into a JSON-formatted string suitable for
|
||||
* returning through the C callback API.
|
||||
*/
|
||||
QString variantToJsonString(const QVariant& value);
|
||||
|
||||
/**
|
||||
* Format event data (event name + QVariantList payload) as a JSON string
|
||||
* matching the format expected by FFI consumers:
|
||||
* {"event":"<name>","data":["<val1>","<val2>",...]}
|
||||
*/
|
||||
QString formatEventJson(const QString& eventName, const QVariantList& data);
|
||||
|
||||
}
|
||||
|
||||
#endif // LOGOS_JSON_UTILS_H
|
||||
@@ -1,62 +0,0 @@
|
||||
#include "logos_sdk_c.h"
|
||||
#include "logos_core_client.h"
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
|
||||
static LogosCoreClient* s_coreClient = nullptr;
|
||||
|
||||
static LogosCoreClient* ensureClient()
|
||||
{
|
||||
if (!s_coreClient)
|
||||
s_coreClient = new LogosCoreClient();
|
||||
return s_coreClient;
|
||||
}
|
||||
|
||||
void logos_sdk_call_method_async(
|
||||
const char* plugin_name,
|
||||
const char* method_name,
|
||||
const char* params_json,
|
||||
LogosSdkCallback callback,
|
||||
void* user_data)
|
||||
{
|
||||
if (!callback) return;
|
||||
|
||||
if (!plugin_name || !method_name) {
|
||||
callback(0, "Plugin name or method name is null", user_data);
|
||||
return;
|
||||
}
|
||||
|
||||
QString pluginStr = QString::fromUtf8(plugin_name);
|
||||
QString methodStr = QString::fromUtf8(method_name);
|
||||
QString paramsStr = params_json ? QString::fromUtf8(params_json) : QStringLiteral("[]");
|
||||
|
||||
ensureClient()->callMethodAsync(pluginStr, methodStr, paramsStr,
|
||||
[callback, user_data](bool success, const QString& message) {
|
||||
QByteArray msgBytes = message.toUtf8();
|
||||
callback(success ? 1 : 0, msgBytes.constData(), user_data);
|
||||
});
|
||||
}
|
||||
|
||||
void logos_sdk_register_event(
|
||||
const char* plugin_name,
|
||||
const char* event_name,
|
||||
LogosSdkCallback callback,
|
||||
void* user_data)
|
||||
{
|
||||
if (!plugin_name || !event_name || !callback) return;
|
||||
|
||||
QString pluginStr = QString::fromUtf8(plugin_name);
|
||||
QString eventStr = QString::fromUtf8(event_name);
|
||||
|
||||
ensureClient()->subscribeEvent(pluginStr, eventStr,
|
||||
[callback, user_data](bool success, const QString& message) {
|
||||
QByteArray msgBytes = message.toUtf8();
|
||||
callback(success ? 1 : 0, msgBytes.constData(), user_data);
|
||||
});
|
||||
}
|
||||
|
||||
void logos_sdk_shutdown()
|
||||
{
|
||||
delete s_coreClient;
|
||||
s_coreClient = nullptr;
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
#ifndef LOGOS_SDK_C_H
|
||||
#define LOGOS_SDK_C_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* C callback type matching the AsyncCallback in logos_core.h:
|
||||
* void(int result, const char* message, void* user_data)
|
||||
*/
|
||||
typedef void (*LogosSdkCallback)(int result, const char* message, void* user_data);
|
||||
|
||||
/**
|
||||
* Call a plugin method asynchronously.
|
||||
*
|
||||
* @param plugin_name Target plugin name
|
||||
* @param method_name Method to call
|
||||
* @param params_json JSON array of [{name,value,type},...] parameters (may be NULL for "[]")
|
||||
* @param callback Receives (1=success/0=failure, message, user_data) on completion
|
||||
* @param user_data Opaque pointer passed through to callback
|
||||
*/
|
||||
void logos_sdk_call_method_async(
|
||||
const char* plugin_name,
|
||||
const char* method_name,
|
||||
const char* params_json,
|
||||
LogosSdkCallback callback,
|
||||
void* user_data
|
||||
);
|
||||
|
||||
/**
|
||||
* Register an event listener for a specific event from a plugin.
|
||||
*
|
||||
* @param plugin_name Plugin that emits the event
|
||||
* @param event_name Event name to listen for
|
||||
* @param callback Receives (1, json_event_data, user_data) each time event fires
|
||||
* @param user_data Opaque pointer passed through to callback
|
||||
*/
|
||||
void logos_sdk_register_event(
|
||||
const char* plugin_name,
|
||||
const char* event_name,
|
||||
LogosSdkCallback callback,
|
||||
void* user_data
|
||||
);
|
||||
|
||||
/**
|
||||
* Shut down the SDK's internal core client, releasing connections.
|
||||
* Safe to call multiple times. After this, async calls will lazily re-create
|
||||
* the client on next use.
|
||||
*/
|
||||
void logos_sdk_shutdown(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LOGOS_SDK_C_H
|
||||
Reference in New Issue
Block a user