Heart/src/public/async.cpp

130 lines
3.4 KiB
C++
Raw Normal View History

2021-01-27 21:59:31 +03:00
/*
2024-12-30 22:44:47 +01:00
* Copyright (C) 2018-2025 QuasarApp.
2021-01-27 21:59:31 +03:00
* Distributed under the lgplv3 software license, see the accompanying
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
2021-03-23 23:02:28 +03:00
#include "abstractnode.h"
2020-11-29 23:31:55 +03:00
#include "async.h"
#include <QCoreApplication>
#include <QDateTime>
2020-12-06 20:12:34 +03:00
#include <QThread>
2020-12-16 23:02:59 +03:00
#include <QDebug>
2021-03-23 19:20:29 +03:00
#include <quasarapp.h>
2021-11-01 13:39:01 +03:00
#include <thread>
#include <chrono>
2022-01-20 17:12:59 +03:00
#include <qaglobalutils.h>
2020-11-29 23:31:55 +03:00
// Private implementation of waitFor functions.
#define waitPrivate(CONDITION, TIMEOUT) \
auto curmsec = QDateTime::currentMSecsSinceEpoch() + TIMEOUT; \
while (curmsec > QDateTime::currentMSecsSinceEpoch() && !CONDITION) { \
QCoreApplication::processEvents(); \
} \
QCoreApplication::processEvents(); \
return CONDITION; \
2021-11-01 13:39:01 +03:00
#define freazePrivate(CONDITION, TIMEOUT) \
auto curmsec = QDateTime::currentMSecsSinceEpoch() + TIMEOUT; \
while (curmsec > QDateTime::currentMSecsSinceEpoch() && !CONDITION) { \
std::this_thread::sleep_for(std::chrono::microseconds(1)); \
} \
return CONDITION; \
2020-11-29 23:31:55 +03:00
namespace QH {
2021-03-23 19:20:29 +03:00
Async::Async(QThread *thread, QObject *ptr):
2020-11-29 23:31:55 +03:00
QObject(ptr) {
2021-03-23 19:20:29 +03:00
threadAnalize(thread);
moveToThread(thread);
}
Async::~Async() {
2020-11-29 23:31:55 +03:00
}
2020-12-06 20:12:34 +03:00
void Async::asyncHandler(Job job,
2021-03-23 19:20:29 +03:00
bool *endOfWork,
bool *resultOfWork) const {
2020-11-29 23:31:55 +03:00
bool result = job();
2020-12-17 17:31:26 +03:00
if (endOfWork && resultOfWork)
2020-11-29 23:31:55 +03:00
*resultOfWork = result;
if (endOfWork) {
*endOfWork = true;
}
2021-03-23 19:20:29 +03:00
}
2020-12-06 20:12:34 +03:00
2021-03-23 19:20:29 +03:00
void Async::threadAnalize(QThread *thread) {
2021-03-24 10:47:03 +03:00
QThread * mainThread = AbstractNode::mainThreadID();
2021-03-23 23:02:28 +03:00
2021-03-24 10:45:13 +03:00
debug_assert((mainThread != thread) && thread, "You try create async object into main thread");
2020-11-29 23:31:55 +03:00
}
2021-11-01 13:39:01 +03:00
bool Async::waitFor(bool *condition, int timeout, bool freaze) const {
2020-11-29 23:31:55 +03:00
if (!condition)
return false;
2021-11-01 13:39:01 +03:00
if (freaze) {
freazePrivate(*condition, timeout)
} else {
waitPrivate(*condition, timeout)
}
2020-11-29 23:31:55 +03:00
}
2021-11-01 13:39:01 +03:00
bool Async::asyncLauncher(const Async::Job &job, bool await, bool freaze) const {
2021-03-24 10:39:04 +03:00
2020-12-06 20:12:34 +03:00
if (QThread::currentThread() == thread()) {
return job();
}
2021-03-24 10:39:04 +03:00
if (!thread()->isRunning()) {
2025-01-03 17:39:38 +01:00
qCritical() << "The work threand of the async object is not running";
2021-03-24 10:39:04 +03:00
return false;
}
2020-12-17 17:31:26 +03:00
if (!await) {
2021-02-19 18:59:00 +03:00
return QMetaObject::invokeMethod(const_cast<Async*>(this),
2021-01-13 17:31:44 +03:00
"asyncHandler",
Qt::QueuedConnection,
Q_ARG(QH::Async::Job, job));
2020-12-17 17:31:26 +03:00
}
2020-12-06 20:12:34 +03:00
bool workOfEnd = false, workResult = false;
2021-02-19 18:59:00 +03:00
bool invockeResult = QMetaObject::invokeMethod(const_cast<Async*>(this),
2020-12-06 20:12:34 +03:00
"asyncHandler",
Qt::QueuedConnection,
Q_ARG(QH::Async::Job, job),
2021-03-02 19:33:11 +03:00
Q_ARG(bool*, &workOfEnd),
Q_ARG(bool*, &workResult));
2020-12-06 20:12:34 +03:00
if (!invockeResult)
return false;
2021-11-01 13:39:01 +03:00
if (!waitFor(&workOfEnd, WAIT_TIME, freaze)) {
2020-12-06 20:12:34 +03:00
return false;
}
return workResult;
}
2021-11-01 13:39:01 +03:00
bool Async::waitFor(const std::function<bool ()> &condition, int timeout, bool freaze) const {
if (freaze) {
freazePrivate(condition(), timeout)
} else {
waitPrivate(condition(), timeout)
}
2020-11-29 23:31:55 +03:00
}
}