Files
logos-liblogos/app/call_executor.cpp
T
Iuri Matias 351149408a support --call arg to call module methods in the cmd line
support --call arg to call module methods in the cmd line

cleanup

cleanup
2026-01-28 15:17:26 -05:00

178 lines
4.8 KiB
C++

#include "call_executor.h"
#include "logos_core.h"
#include <QFile>
#include <QTextStream>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QEventLoop>
#include <QTimer>
#include <QDebug>
#include <iostream>
struct CallResult {
bool completed = false;
bool success = false;
QString message;
};
static void methodCallCallback(int result, const char* message, void* user_data) {
CallResult* callResult = static_cast<CallResult*>(user_data);
callResult->completed = true;
callResult->success = (result == 1);
callResult->message = message ? QString::fromUtf8(message) : QString();
}
QString CallExecutor::resolveParam(const QString& param) {
if (param.startsWith('@')) {
QString filePath = param.mid(1);
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning() << "Failed to open file:" << filePath;
return QString();
}
QTextStream in(&file);
QString content = in.readAll();
file.close();
return content;
}
return param;
}
QJsonValue CallExecutor::convertParam(const QString& param) {
if (param.toLower() == "true") {
return QJsonValue(true);
}
if (param.toLower() == "false") {
return QJsonValue(false);
}
bool ok;
int intVal = param.toInt(&ok);
if (ok) {
return QJsonValue(intVal);
}
double doubleVal = param.toDouble(&ok);
if (ok) {
return QJsonValue(doubleVal);
}
return QJsonValue(param);
}
QString CallExecutor::buildParamsJson(const QStringList& params) {
QJsonArray paramsArray;
for (int i = 0; i < params.size(); ++i) {
QString rawParam = params[i];
QString resolvedParam = resolveParam(rawParam);
if (rawParam.startsWith('@') && resolvedParam.isEmpty()) {
qWarning() << "Failed to resolve file parameter:" << rawParam;
return QString();
}
QJsonObject paramObj;
paramObj["name"] = QString("arg%1").arg(i);
paramObj["value"] = resolvedParam;
QJsonValue converted = convertParam(resolvedParam);
if (converted.isBool()) {
paramObj["type"] = "bool";
paramObj["value"] = resolvedParam;
} else if (converted.isDouble()) {
bool ok;
resolvedParam.toInt(&ok);
if (ok) {
paramObj["type"] = "int";
} else {
paramObj["type"] = "double";
}
paramObj["value"] = resolvedParam;
} else {
paramObj["type"] = "QString";
paramObj["value"] = resolvedParam;
}
paramsArray.append(paramObj);
}
QJsonDocument doc(paramsArray);
return QString::fromUtf8(doc.toJson(QJsonDocument::Compact));
}
bool CallExecutor::executeCall(const ModuleCall& call) {
qDebug() << "Executing call:" << call.moduleName << "." << call.methodName
<< "with" << call.params.size() << "params";
QString paramsJson = buildParamsJson(call.params);
if (call.params.size() > 0 && paramsJson.isEmpty()) {
std::cerr << "Error: Failed to build parameters for "
<< call.moduleName.toStdString() << "."
<< call.methodName.toStdString() << std::endl;
return false;
}
CallResult result;
logos_core_call_plugin_method_async(
call.moduleName.toUtf8().constData(),
call.methodName.toUtf8().constData(),
paramsJson.isEmpty() ? "[]" : paramsJson.toUtf8().constData(),
methodCallCallback,
&result
);
QEventLoop loop;
QTimer timeoutTimer;
timeoutTimer.setSingleShot(true);
timeoutTimer.setInterval(30000);
QTimer pollTimer;
pollTimer.setInterval(100);
QObject::connect(&timeoutTimer, &QTimer::timeout, &loop, &QEventLoop::quit);
QObject::connect(&pollTimer, &QTimer::timeout, [&]() {
if (result.completed) {
loop.quit();
}
});
timeoutTimer.start();
pollTimer.start();
loop.exec();
pollTimer.stop();
timeoutTimer.stop();
if (!result.completed) {
std::cerr << "Error: Timeout waiting for "
<< call.moduleName.toStdString() << "."
<< call.methodName.toStdString() << std::endl;
return false;
}
if (!result.success) {
std::cerr << "Error: " << result.message.toStdString() << std::endl;
return false;
}
std::cout << result.message.toStdString() << std::endl;
return true;
}
int CallExecutor::executeCalls(const QList<ModuleCall>& calls) {
for (const ModuleCall& call : calls) {
if (!executeCall(call)) {
return 1;
}
}
return 0;
}