1
0
mirror of https://github.com/jaredtao/TaoQuick.git synced 2025-01-31 21:22:58 +08:00
TaoQuick/3rdparty/TaoCommon/Thread/threadworkercontroller.h
2020-06-30 00:34:25 +08:00

130 lines
4.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include "taocommonglobal.h"
#include "threadcommon.h"
#include <QMap>
#include <QThread>
namespace TaoCommon
{
// 对Qt Worker-Controller 线程模型的简单封装,适合精确控制的任务。
// 用法: ThreadController::getInstance()->work(workCall, resultCall)
// workCall是在新线程中执行的任务resultCall是任务执行完成后回到调用线程中用来处理执行结果。
// work函数返回值为任务id。
// 取消任务用ThreadController::getInstance()->cancle(id)函数。
class ThreadWorker : public QObject
{
Q_OBJECT
public:
ThreadWorker(uint64_t id, const WorkCallback &workCall, QObject *parent = nullptr) : QObject(parent), m_id(id), m_workCall(workCall) {}
signals:
void workFinished(bool, uint64_t);
public slots:
void doWork()
{
bool ret = m_workCall();
emit workFinished(ret, m_id);
}
private:
const uint64_t m_id;
WorkCallback m_workCall;
};
class TAO_API ThreadController : public QObject
{
Q_OBJECT
public:
static ThreadController *getInstance()
{
static ThreadController controller;
return &controller;
}
~ThreadController()
{
for (auto k : m_threadMap.uniqueKeys())
{
if (m_threadMap.value(k)->isRunning())
{
m_threadMap.value(k)->quit();
m_threadMap.value(k)->wait();
}
}
qDeleteAll(m_threadMap);
m_threadMap.clear();
m_resultCallback.clear();
}
uint64_t work(const WorkCallback &workCall, const WorkResultCallback &resultCall)
{
QThread *thread = new QThread;
m_rollId++;
ThreadWorker *obj = new ThreadWorker(m_rollId, workCall);
m_threadMap[m_rollId] = thread;
m_resultCallback[m_rollId] = resultCall;
obj->moveToThread(thread);
connect(thread, &QThread::finished, obj, &QObject::deleteLater);
connect(thread, &QThread::started, obj, &ThreadWorker::doWork);
connect(obj, &ThreadWorker::workFinished, this, &ThreadController::onWorkFinished, Qt::QueuedConnection);
thread->start();
return m_rollId;
}
void cancle(uint64_t id)
{
auto it = m_threadMap.find(id);
if (it != m_threadMap.end())
{
if ((*it)->isRunning())
{
(*it)->terminate();
}
}
m_resultCallback.remove(id);
}
void quit(uint64_t id)
{
auto it = m_threadMap.find(id);
if (it != m_threadMap.end())
{
if ((*it)->isRunning())
{
(*it)->quit();
(*it)->wait();
(*it)->deleteLater();
}
}
m_resultCallback.remove(id);
}
QList<uint64_t> getAllWorkId() const
{
return m_threadMap.uniqueKeys();
}
protected slots :
void onWorkFinished(bool ok, uint64_t id)
{
auto it = m_threadMap.find(id);
if (it != m_threadMap.end())
{
if ((*it)->isRunning())
{
(*it)->quit();
(*it)->wait();
(*it)->deleteLater();
}
m_threadMap.remove(id);
}
auto caller = m_resultCallback.find(id);
if (caller != m_resultCallback.end())
{
(*caller)(ok);
m_resultCallback.remove(id);
}
}
protected:
ThreadController(QObject *parent = nullptr) : QObject(parent) {}
private:
uint64_t m_rollId = 0;
QMap<uint64_t, QThread *> m_threadMap;
QMap<uint64_t, WorkResultCallback> m_resultCallback;
};
} // namespace LCIM