4
1
mirror of https://github.com/QuasarApp/Heart.git synced 2025-05-11 17:09:41 +00:00

fixed async functions

This commit is contained in:
Andrei Yankovich 2020-12-06 20:12:34 +03:00
parent 11c22cc61a
commit 752c531cfe
4 changed files with 106 additions and 144 deletions
Heart

@ -2,6 +2,7 @@
#include <QCoreApplication>
#include <QDateTime>
#include <QThread>
// Private implementation of waitFor functions.
#define waitPrivate(CONDITION, TIMEOUT) \
@ -19,7 +20,7 @@ Async::Async(QObject *ptr):
}
void Async::asyncLauncher(Job job,
void Async::asyncHandler(Job job,
bool *resultOfWork,
bool *endOfWork) const {
@ -31,6 +32,8 @@ void Async::asyncLauncher(Job job,
if (endOfWork) {
*endOfWork = true;
}
}
bool Async::waitFor(bool *condition, int timeout) const {
@ -40,6 +43,35 @@ bool Async::waitFor(bool *condition, int timeout) const {
waitPrivate(*condition, timeout)
}
bool Async::asyncLauncher(const Async::Job &job, bool await) {
if (QThread::currentThread() == thread()) {
return job();
}
bool workOfEnd = false, workResult = false;
bool invockeResult = QMetaObject::invokeMethod(this,
"asyncHandler",
Qt::QueuedConnection,
Q_ARG(QH::Async::Job, job),
Q_ARG(bool *, &workResult),
Q_ARG(bool *, &workOfEnd));
if (!invockeResult)
return false;
if (!await) {
return true;
}
if (!waitFor(&workOfEnd)) {
return false;
}
return workResult;
}
bool Async::waitFor(const std::function<bool ()> &condition, int timeout) const {
waitPrivate(condition(), timeout)
}

@ -43,10 +43,18 @@ protected:
*/
bool waitFor(const Job &condition, int timeout = WAIT_TIME) const;
/**
* @brief asyncLauncher This method invoke a job on the thread (usnign the asyncHandler method) of this object.
* @param job This is function with needed job.
* @param await This is boolean option for enable or disable waiot of finish of the job function.
* @return true if the job function started correctly. IF the await option is true then
* this method return result of job function.
*/
bool asyncLauncher(const Job &job, bool await = false);
private slots:
/**
* @brief asyncLauncher This is base async launcher method for move jobs to new thread.
* @brief asyncHandler async This is base async launcher method for move jobs to new thread.
* @param job This is job to do.
* @param resultOfWork This is pointer of bool value of a result of the job method.
* @note If you want to disable check results just use nullptr value.
@ -63,7 +71,7 @@ private slots:
* return true;
* }
* bool invoke = QMetaObject::invokeMethod(this,
"asyncLauncher",
"asyncHandler",
Qt::QueuedConnection,
Q_ARG(QH::Async::Job, job),
Q_ARG(bool *, &workResult),
@ -90,14 +98,14 @@ private slots:
* return true;
* }
* bool invoke = QMetaObject::invokeMethod(this,
"asyncLauncher",
"asyncHandler",
Qt::QueuedConnection,
Q_ARG(std::function<bool()>, job));
return invoke;
* \endcode
*/
void asyncLauncher(QH::Async::Job job,
void asyncHandler (QH::Async::Job job,
bool* resultOfWork = nullptr,
bool* endOfWork = nullptr) const;

@ -275,21 +275,20 @@ bool SqlDBCache::changeObjects(const DBObject &templateObject,
return false;
for (const DBObject * obj :list) {
if (obj->isCached()) {
if (!changeAction(getFromCache(obj->dbKey()))) {
return false;
};
auto cachedObject = getFromCache(obj->dbKey());
updateCache(obj);
} else {
if (!changeAction(const_cast<DBObject *>(obj))) {
return false;
};
if (!cachedObject && obj->isCached())
return false;
updateObject(obj);
}
DBObject *ptr = (cachedObject)? cachedObject: const_cast<DBObject*>(obj);
if (!changeAction(ptr)) {
return false;
};
if (!updateObject(ptr)) {
return false;
};
}
return true;

@ -209,24 +209,7 @@ bool SqlDBWriter::initDb(const QVariantMap &params) {
return handleInitDb();
}
bool workOfEnd = false, workResult = false;
bool invockeResult = QMetaObject::invokeMethod(this,
"asyncLauncher",
Qt::QueuedConnection,
Q_ARG(QH::Async::Job, handleInitDb),
Q_ARG(bool *, &workResult),
Q_ARG(bool *, &workOfEnd));
if (!invockeResult)
return false;
if (!waitFor(&workOfEnd)) {
return false;
}
return workResult;
return asyncLauncher(handleInitDb, true);
}
bool SqlDBWriter::isValid() const {
@ -239,134 +222,74 @@ bool SqlDBWriter::getAllObjects(const DBObject &templateObject, QList<const DBO
return SqlDBWriter::selectQuery(templateObject, result);
};
if (QThread::currentThread() == thread()) {
return getAll();
}
bool workOfEnd = false, workResult = false;
bool invockeResult = QMetaObject::invokeMethod(this,
"asyncLauncher",
Qt::QueuedConnection,
Q_ARG(QH::Async::Job, getAll),
Q_ARG(bool *, &workResult),
Q_ARG(bool *, &workOfEnd));
if (!invockeResult)
return false;
if (!waitFor(&workOfEnd)) {
return false;
}
return workResult;
return asyncLauncher(getAll, true);
}
bool SqlDBWriter::updateObject(const DBObject* ptr, bool wait) {
auto updateQueryWraper = [ptr, this]() {
return updateQuery(ptr);
};
if (QThread::currentThread() == thread()) {
return updateQueryWraper();
Async::Job job;
if (wait) {
auto clone = ptr->cloneRaw();
job = [clone, this]() {
bool res = updateQuery(clone);
delete clone;
return res;
};
} else {
job = [this, ptr]() {
return updateQuery(ptr);
};
}
auto clone = ptr->cloneRaw();
bool workOfEnd = false, workResult = false;
bool invockeResult = QMetaObject::invokeMethod(this,
"asyncLauncher",
Qt::QueuedConnection,
Q_ARG(QH::Async::Job, updateQueryWraper),
Q_ARG(bool *, &workResult),
Q_ARG(bool *, &workOfEnd));
delete clone;
if (!invockeResult)
return false;
if (!wait) {
return true;
}
if (!waitFor(&workOfEnd)) {
return false;
}
return workResult;
return asyncLauncher(job, wait);
}
bool SqlDBWriter::deleteObject(const DBObject* ptr, bool wait) {
auto deleteQueryWraper = [ptr, this]() {
return deleteQuery(ptr);
};
if (QThread::currentThread() == thread()) {
return deleteQueryWraper();
Async::Job job;
if (wait) {
auto clone = ptr->cloneRaw();
job = [clone, this]() {
bool res = deleteQuery(clone);
delete clone;
return res;
};
} else {
job = [this, ptr]() {
return deleteQuery(ptr);
};
}
bool workOfEnd = false, workResult = false;
auto clone = ptr->cloneRaw();
bool invockeResult = QMetaObject::invokeMethod(this,
"asyncLauncher",
Qt::QueuedConnection,
Q_ARG(QH::Async::Job, deleteQueryWraper),
Q_ARG(bool *, &workResult),
Q_ARG(bool *, &workOfEnd));
delete clone;
if (!invockeResult)
return false;
if (!wait) {
return true;
}
if (!waitFor(&workOfEnd)) {
return false;
}
return workResult;
return asyncLauncher(job, wait);
}
bool SqlDBWriter::insertObject(const DBObject *saveObject, bool wait) {
bool SqlDBWriter::insertObject(const DBObject *ptr, bool wait) {
auto insertQueryWraper = [saveObject, this]() {
return insertQuery(saveObject);
};
Async::Job job;
if (QThread::currentThread() == thread()) {
return insertQueryWraper();
if (wait) {
auto clone = ptr->cloneRaw();
job = [clone, this]() {
bool res = insertQuery(clone);
delete clone;
return res;
};
} else {
job = [this, ptr]() {
return insertQuery(ptr);
};
}
bool workOfEnd = false, workResult = false;
auto clone = saveObject->cloneRaw();
bool invockeResult = QMetaObject::invokeMethod(this,
"asyncLauncher",
Qt::QueuedConnection,
Q_ARG(QH::Async::Job, insertQueryWraper),
Q_ARG(bool *, &workResult),
Q_ARG(bool *, &workOfEnd));
delete clone;
if (!invockeResult)
return false;
if (!wait) {
return true;
}
if (!waitFor(&workOfEnd)) {
return false;
}
return workResult;
return asyncLauncher(job, wait);
}