#include #include #include #include using namespace std; #include "renderermanager.hpp" #include "renderchild.hpp" static int compteur = 0; RendererManager::RendererManager(QObject *parent) : QThread(parent), childs() { threadRndSeed = qrand(); terminate = false; pause = false; qRegisterMetaType("QImage"); initChilds(1); } RendererManager::~RendererManager() { terminate = true; initChilds(0); condition.wakeOne(); wait(); } void RendererManager::process(const size_t nOfThreads, const QImage &image) { initChilds(nOfThreads); this->image = image; emit(renderedImage(image)); terminate = false; currentline = 0; firstAssignator(); start(LowPriority); } void RendererManager::run() { running = true; forever { if(terminate) { emit(manager_up("manager has terminated : " + QString::number(compteur))); running = false; return; }else emit(startChildsCalc()); mutex.lock(); condition.wait(&mutex); mutex.unlock(); emit(manager_up("manager condition wake")); } } void RendererManager::pauseProcess() { pause = !pause; for(int i = 0; i < childs.count(); i++) { childs[i]->pauseCalc(pause); } } void RendererManager::stopProcess() { for(int i = 0; i < childs.count(); i++) { childs[i]->abortCalc(); } pause = false; } void RendererManager::childFinished() { RenderChild* child = dynamic_cast(sender()); QString data = "thread " + QString::number(child->getId()) + " has finished!"; emit(manager_up(data)); if(terminate) return; if(currentline < image.height()) { child->assign(currentline, 10); emit(manager_up("thread " + QString::number(child->getId()) + " assign : " + QString::number(currentline))); currentline+=10; compteur++; }else terminate = true; condition.wakeOne(); } void RendererManager::firstAssignator() { for(int i = 0; i < childs.count(); i++) { if(currentline < image.height()) { childs[i]->assign(currentline, 10); currentline+=10; }else return; } } void RendererManager::initChilds(int nb) { if(nb < childs.count()) { for(int i = nb ; i < childs.count(); ++i) { delete childs[i]; childs[i] = 0; } } childs.resize(nb); for(int i = 0; i < childs.count(); ++i) { if(!childs[i]) { childs[i] = new RenderChild(&image, threadRndSeed++); connect(this, SIGNAL(startChildsCalc()), childs[i], SLOT(startCalc())); connect(childs[i], SIGNAL(threadFinished()), this, SLOT(childFinished())); childs[i]->start(LowPriority); } } } void RendererManager::incThreads() { initChilds(childs.count() + 1); if(running) { if(currentline < image.height()) { childs.last()->assign(currentline, 10); currentline+=10; emit(startChildsCalc()); } } QString data = "inc threads : " + QString::number(childs.count()); emit(manager_up(data)); } void RendererManager::decThreads() { if(childs.size() <= 1) return; initChilds(childs.count() - 1); if(running) currentline -= 10; QString data = "dec threads : " + QString::number(childs.count()); emit(manager_up(data)); } void RendererManager::refreshPixmap() { emit(renderedImage(image)); }