Files
Renderive/YSGraphic_Core/base/Global.cpp
T

82 lines
2.7 KiB
C++

#include "asio.hpp"
#include "Global.h"
#include <QApplication>
#include <algorithm>
#include <thread>
#include "Plot_p.h"
namespace YSG {
struct TimerThreadPrivate {
asio::io_context mIoContext;
std::unique_ptr<asio::executor_work_guard<asio::io_context::executor_type>> mWorkGuard;
std::unique_ptr<asio::thread_pool> mCpuPool;
std::thread::id mSchedulerThreadId;
};
TimerThread::TimerThread() : d(std::make_unique<TimerThreadPrivate>()) {
connect(QApplication::instance(), &QApplication::aboutToQuit, [this]() {
if (isRunning()) {
d->mIoContext.stop();
if(d->mCpuPool) d->mCpuPool->stop();
wait();
}
delete this;
});
}
TimerThread::~TimerThread() = default;
void TimerThread::run() {
d->mSchedulerThreadId = std::this_thread::get_id();
d->mIoContext.restart();
d->mWorkGuard = std::make_unique<asio::executor_work_guard<asio::io_context::executor_type>>(d->mIoContext.get_executor());
unsigned cpuCount = std::max(1u, std::thread::hardware_concurrency() > 1 ? std::thread::hardware_concurrency() - 1 : 1u);
d->mCpuPool = std::make_unique<asio::thread_pool>(cpuCount);
for (auto &plot: mPlots) {
plot->d->mTimerThread = this;
plot->d->mRenderTimer = std::make_unique<asio::steady_timer>(d->mIoContext);
if(plot->isVisible()) plot->d->mRenderEnabled = true;
if(plot->d->mRenderEnabled) plot->scheduleRenderTimer();
plot->requestRender();
}
d->mIoContext.run();
for (auto &plot: mPlots) {
if(plot->d->mRenderTimer) {
plot->d->mRenderTimer->cancel();
plot->d->mRenderTimer.reset();
}
}
if(d->mCpuPool) {
d->mCpuPool->stop();
d->mCpuPool->join();
d->mCpuPool.reset();
}
d->mWorkGuard.reset();
}
void TimerThread::post(std::function<void()> task) {
asio::post(d->mIoContext, std::move(task));
}
void TimerThread::postCpu(std::function<void()> task) {
if(d->mCpuPool) {
asio::post(*d->mCpuPool, std::move(task));
} else {
post(std::move(task));
}
}
bool TimerThread::isSchedulerThread() const {
return std::this_thread::get_id() == d->mSchedulerThreadId;
}
asio::io_context& TimerThread::ioContext() {
return d->mIoContext;
}
void Global::startAllTimeThread() {
for (auto &thread: mTimerThreadMap) {
if(!thread->isRunning()) thread->start();
}
}
void Global::timerEvent(QTimerEvent* event) {
Q_UNUSED(event)
}
}