277 lines
6.3 KiB
C++
Executable File
277 lines
6.3 KiB
C++
Executable File
|
|
|
|
|
|
#include "request_helper.h"
|
|
|
|
#ifdef REQUEST_HELPER_WITH_GUI
|
|
#include <LtsWidgets/lts_global_wait_dialog.h>
|
|
#include <LtsWidgets/lts_message_dialog.h>
|
|
#include <QWidget>
|
|
#endif
|
|
|
|
|
|
#include <QEventLoop>
|
|
#include <QTimer>
|
|
#include <memory>
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
|
|
#define DEBUG
|
|
|
|
|
|
namespace LtsUtils
|
|
{
|
|
bool RequestHelper::s_debug = false;
|
|
|
|
RequestHelper::RequestHelper(QObject *parent, bool quiet,
|
|
|
|
const std::function<void (void)> &success,
|
|
const std::function<void (void)> &failure)
|
|
: QObject(parent)
|
|
, m_failed(false)
|
|
, m_repliedId(-1)
|
|
, m_quiet(quiet)
|
|
, m_blockingCall(true)
|
|
, m_successFn(success)
|
|
, m_failureFn(failure)
|
|
{
|
|
connect(this, &RequestHelper::signalSuccess, this, m_successFn, Qt::QueuedConnection);
|
|
connect(this, &RequestHelper::signalFailed, this, m_failureFn, Qt::QueuedConnection);
|
|
|
|
if (s_debug)
|
|
{
|
|
QTimer *t = new QTimer(this);
|
|
t->setInterval(2000);
|
|
t->setSingleShot(true);
|
|
connect(this, &RequestHelper::signalNextRequest, t, static_cast<void (QTimer::*)(void)>(&QTimer::start));
|
|
connect(t, &QTimer::timeout, this, &RequestHelper::slotNextRequest, Qt::QueuedConnection);
|
|
}
|
|
else
|
|
{
|
|
connect(this, &RequestHelper::signalNextRequest,
|
|
this, &RequestHelper::slotNextRequest,
|
|
Qt::QueuedConnection
|
|
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
void RequestHelper::addRequest(const std::function<int64_t()> &requestFunction,
|
|
const std::function<void(const Core::FunctionReply &baseReply)> &baseReplyHandler)
|
|
{
|
|
m_requestFunctions.append(RequestFunctionContainer(requestFunction, baseReplyHandler));
|
|
}
|
|
|
|
bool RequestHelper::requestReply(const Core::FunctionReply &baseReply)
|
|
{
|
|
const Core::FunctionReplyObject fro(baseReply.id(),
|
|
baseReply.errorString(),
|
|
baseReply.errorParams());
|
|
return _requestReply(fro, &baseReply);
|
|
}
|
|
|
|
bool RequestHelper::requestReply(const Core::FunctionReplyObject &replyObject)
|
|
{
|
|
return _requestReply(replyObject, nullptr);
|
|
}
|
|
|
|
|
|
bool RequestHelper::_requestReply(const Core::FunctionReplyObject &fro, const Core::FunctionReply *baseReply)
|
|
{
|
|
m_errorString = fro.translated();
|
|
|
|
#ifdef REQUEST_HELPER_WITH_GUI
|
|
if (fro.error())
|
|
{
|
|
|
|
if (!m_quiet)
|
|
{
|
|
if (m_blockingCall)
|
|
{
|
|
LtsWidgets::LtsMessageDialog::showMessage(qobject_cast<QWidget *>(parent()),
|
|
m_errorString,
|
|
tr("Request failed"));
|
|
}
|
|
else
|
|
{
|
|
new LtsWidgets::LtsMessageDialogNew(qobject_cast<QWidget *>(parent()),
|
|
m_errorString,
|
|
tr("Request failed"));
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
m_repliedId = fro.id();
|
|
|
|
if (m_singleRequestCustomFunctionReply != nullptr)
|
|
{
|
|
if (baseReply)
|
|
m_singleRequestCustomFunctionReply(*baseReply);
|
|
else
|
|
m_singleRequestCustomFunctionReply(Core::FunctionReply(fro.id(), fro.str(), fro.args(), fro.additionalInfo()));
|
|
}
|
|
|
|
if (fro.error())
|
|
{
|
|
failure();
|
|
return false;
|
|
}
|
|
|
|
emit signalNextRequest();
|
|
return true;
|
|
}
|
|
|
|
|
|
bool RequestHelper::startSingleRequest(const std::function<int64_t()> &requestFunction,
|
|
const std::function<void(const Core::FunctionReply &baseReply)> &baseReplyHandler)
|
|
{
|
|
addRequest(requestFunction, baseReplyHandler);
|
|
return startRequests();
|
|
}
|
|
|
|
|
|
void RequestHelper::failure()
|
|
{
|
|
m_failed = true;
|
|
emit signalFailed();
|
|
done();
|
|
}
|
|
|
|
|
|
void RequestHelper::done()
|
|
{
|
|
#ifdef REQUEST_HELPER_WITH_GUI
|
|
if (!m_quiet)
|
|
LtsWidgets::LtsGlobalWaitDialog::getInstance()->done();
|
|
#endif
|
|
|
|
m_requestFunctions.clear();
|
|
m_singleRequestCustomFunctionReply = nullptr;
|
|
|
|
if (m_blockingCall)
|
|
emit signalQuitLoop();
|
|
|
|
m_blockingCall = true;
|
|
|
|
if (!m_blockingCall)
|
|
deleteLater();
|
|
}
|
|
|
|
|
|
void RequestHelper::slotNextRequest()
|
|
{
|
|
if (m_requestFunctions.isEmpty())
|
|
{
|
|
if (!m_blockingCall)
|
|
emit signalSuccess();
|
|
|
|
done();
|
|
|
|
return;
|
|
}
|
|
|
|
const RequestFunctionContainer rfc = m_requestFunctions.takeFirst();
|
|
m_singleRequestCustomFunctionReply = rfc.second;
|
|
|
|
int64_t result = rfc.first();
|
|
|
|
if (result == 0)
|
|
{
|
|
#ifdef REQUEST_HELPER_WITH_GUI
|
|
if (!m_quiet)
|
|
{
|
|
if (m_blockingCall)
|
|
{
|
|
LtsWidgets::LtsMessageDialog::showMessage(qobject_cast<QWidget *>(parent()),
|
|
tr("Request failed"));
|
|
}
|
|
else
|
|
{
|
|
connect(new LtsWidgets::LtsMessageDialogNew(qobject_cast<QWidget *>(parent()),
|
|
tr("Request failed")), &LtsWidgets::LtsMessageDialogNew::destroyed,
|
|
this, [this]()
|
|
{
|
|
failure();
|
|
});
|
|
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
failure();
|
|
}
|
|
}
|
|
|
|
|
|
void RequestHelper::startSingleBackgroundRequest(const std::function<int64_t()> &requestFunction,
|
|
const std::function<void (const Core::FunctionReply &)> &baseReplyHandler)
|
|
{
|
|
m_blockingCall = false;
|
|
startSingleRequest(requestFunction, baseReplyHandler);
|
|
}
|
|
|
|
|
|
void RequestHelper::startBackgroundRequests()
|
|
{
|
|
m_blockingCall = false;
|
|
startRequests();
|
|
}
|
|
|
|
|
|
void RequestHelper::setCustomWaitMessage(const QString &customWaitMessage)
|
|
{
|
|
m_customWaitMessage = (customWaitMessage + QStringLiteral(" ..."));
|
|
}
|
|
|
|
|
|
bool RequestHelper::startRequests()
|
|
{
|
|
if (m_requestFunctions.isEmpty())
|
|
{
|
|
#ifdef LTS_DEBUG
|
|
qWarning("RequestHelper: started request helper without requests!");
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
m_failed = false;
|
|
|
|
#ifdef REQUEST_HELPER_WITH_GUI
|
|
if (!m_quiet)
|
|
LtsWidgets::LtsGlobalWaitDialog::getInstance()->wait(m_customWaitMessage);
|
|
m_customWaitMessage.clear();
|
|
#endif
|
|
|
|
m_errorString.clear();
|
|
m_repliedId = -1;
|
|
|
|
if (s_debug)
|
|
{
|
|
QTimer *t = new QTimer(this);
|
|
t->setInterval(2000);
|
|
connect(t, &QTimer::timeout, this, &RequestHelper::slotNextRequest, Qt::QueuedConnection);
|
|
connect(t, &QTimer::timeout, t, &QTimer::deleteLater);
|
|
t->start();
|
|
}
|
|
else
|
|
{
|
|
slotNextRequest();
|
|
|
|
if (m_blockingCall)
|
|
{
|
|
QEventLoop loop;
|
|
connect(this, &RequestHelper::signalQuitLoop,
|
|
&loop, &QEventLoop::quit,
|
|
Qt::QueuedConnection);
|
|
loop.exec();
|
|
}
|
|
}
|
|
|
|
|
|
return (!m_failed);
|
|
}
|
|
|
|
}
|