forked from qt-creator/qt-creator
Add gui thread mode to BuildStep
Change-Id: I11501635bc5c17db557ea8379eb63c9d3915a05e Reviewed-on: http://codereview.qt.nokia.com/1316 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Christian Kandeler <christian.kandeler@nokia.com>
This commit is contained in:
@@ -84,6 +84,7 @@ struct BuildManagerPrivate {
|
||||
ProjectExplorerPlugin *m_projectExplorerPlugin;
|
||||
bool m_running;
|
||||
QFutureWatcher<bool> m_watcher;
|
||||
QFutureInterface<bool> m_futureInterfaceForAysnc;
|
||||
BuildStep *m_currentBuildStep;
|
||||
QString m_currentConfiguration;
|
||||
// used to decide if we are building a project to decide when to emit buildStateChanged(Project *)
|
||||
@@ -91,6 +92,8 @@ struct BuildManagerPrivate {
|
||||
Project *m_previousBuildStepProject;
|
||||
// is set to true while canceling, so that nextBuildStep knows that the BuildStep finished because of canceling
|
||||
bool m_canceling;
|
||||
bool m_doNotEnterEventLoop;
|
||||
QEventLoop *m_eventLoop;
|
||||
|
||||
// Progress reporting to the progress manager
|
||||
int m_progress;
|
||||
@@ -103,6 +106,8 @@ BuildManagerPrivate::BuildManagerPrivate() :
|
||||
m_running(false)
|
||||
, m_previousBuildStepProject(0)
|
||||
, m_canceling(false)
|
||||
, m_doNotEnterEventLoop(false)
|
||||
, m_eventLoop(0)
|
||||
, m_maxProgress(0)
|
||||
, m_progressFutureInterface(0)
|
||||
{
|
||||
@@ -190,7 +195,20 @@ void BuildManager::cancel()
|
||||
if (d->m_running) {
|
||||
d->m_canceling = true;
|
||||
d->m_watcher.cancel();
|
||||
d->m_watcher.waitForFinished();
|
||||
if (d->m_currentBuildStep->runInGuiThread()) {
|
||||
// This is evil. A nested event loop.
|
||||
d->m_currentBuildStep->cancel();
|
||||
if (d->m_doNotEnterEventLoop) {
|
||||
d->m_doNotEnterEventLoop = false;
|
||||
} else {
|
||||
d->m_eventLoop = new QEventLoop;
|
||||
d->m_eventLoop->exec();
|
||||
delete d->m_eventLoop;
|
||||
d->m_eventLoop = 0;
|
||||
}
|
||||
} else {
|
||||
d->m_watcher.waitForFinished();
|
||||
}
|
||||
|
||||
// The cancel message is added to the output window via a single shot timer
|
||||
// since the canceling is likely to have generated new addToOutputWindow signals
|
||||
@@ -332,6 +350,21 @@ void BuildManager::addToOutputWindow(const QString &string, BuildStep::OutputFor
|
||||
d->m_outputWindow->appendText(stringToWrite, format);
|
||||
}
|
||||
|
||||
void BuildManager::buildStepFinishedAsync()
|
||||
{
|
||||
disconnect(d->m_currentBuildStep, SIGNAL(finished()),
|
||||
this, SLOT(buildStepFinishedAsync()));
|
||||
d->m_futureInterfaceForAysnc = QFutureInterface<bool>();
|
||||
if (d->m_canceling) {
|
||||
if (d->m_eventLoop)
|
||||
d->m_eventLoop->exit();
|
||||
else
|
||||
d->m_doNotEnterEventLoop = true;
|
||||
} else {
|
||||
nextBuildQueue();
|
||||
}
|
||||
}
|
||||
|
||||
void BuildManager::nextBuildQueue()
|
||||
{
|
||||
if (d->m_canceling)
|
||||
@@ -393,7 +426,14 @@ void BuildManager::nextStep()
|
||||
.arg(projectName), BuildStep::MessageOutput);
|
||||
d->m_previousBuildStepProject = d->m_currentBuildStep->buildConfiguration()->target()->project();
|
||||
}
|
||||
d->m_watcher.setFuture(QtConcurrent::run(&BuildStep::run, d->m_currentBuildStep));
|
||||
if (d->m_currentBuildStep->runInGuiThread()) {
|
||||
connect (d->m_currentBuildStep, SIGNAL(finished()),
|
||||
this, SLOT(buildStepFinishedAsync()));
|
||||
d->m_watcher.setFuture(d->m_futureInterfaceForAysnc.future());
|
||||
d->m_currentBuildStep->run(d->m_futureInterfaceForAysnc);
|
||||
} else {
|
||||
d->m_watcher.setFuture(QtConcurrent::run(&BuildStep::run, d->m_currentBuildStep));
|
||||
}
|
||||
} else {
|
||||
d->m_running = false;
|
||||
d->m_previousBuildStepProject = 0;
|
||||
|
||||
@@ -87,6 +87,7 @@ private slots:
|
||||
void addToOutputWindow(const QString &string, ProjectExplorer::BuildStep::OutputFormat,
|
||||
ProjectExplorer::BuildStep::OutputNewlineSetting = BuildStep::DoAppendNewline);
|
||||
|
||||
void buildStepFinishedAsync();
|
||||
void nextBuildQueue();
|
||||
void progressChanged();
|
||||
void progressTextChanged();
|
||||
|
||||
@@ -69,13 +69,18 @@
|
||||
\fn void ProjectExplorer::BuildStep::run(QFutureInterface<bool> &fi)
|
||||
|
||||
Reimplement this. This function is called when the target is build.
|
||||
This function is NOT run in the gui thread. It runs in its own thread
|
||||
If you need an event loop, you need to create one.
|
||||
By default this function is NOT run in the gui thread. It runs in its
|
||||
own thread. If you need an event loop, you need to create one.
|
||||
This function should block until the task is done
|
||||
|
||||
The absolute minimal implementation is:
|
||||
\code
|
||||
fi.reportResult(true);
|
||||
\endcode
|
||||
|
||||
By returning true from \sa runInGuiThread() this function is called in the
|
||||
gui thread. Then the function should not block and instead the
|
||||
finished() signal should be emitted.
|
||||
*/
|
||||
|
||||
/*!
|
||||
@@ -106,6 +111,17 @@
|
||||
It should be in plain text, with the format in the parameter.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void ProjectExplorer::BuildStep::cancel() const
|
||||
|
||||
This function needs to be reimplemented only for BuildSteps that return false from \sa runInGuiThread.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void ProjectExplorer::BuildStep::finished()
|
||||
\brief This signal needs to be emitted if the BuildStep runs in the gui thread.
|
||||
*/
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
BuildStep::BuildStep(BuildStepList *bsl, const QString &id) :
|
||||
@@ -150,6 +166,16 @@ bool BuildStep::immutable() const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BuildStep::runInGuiThread() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void BuildStep::cancel()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
IBuildStepFactory::IBuildStepFactory(QObject *parent) :
|
||||
QObject(parent)
|
||||
{ }
|
||||
|
||||
@@ -68,6 +68,8 @@ public:
|
||||
virtual BuildStepConfigWidget *createConfigWidget() = 0;
|
||||
|
||||
virtual bool immutable() const;
|
||||
virtual bool runInGuiThread() const;
|
||||
virtual void cancel();
|
||||
|
||||
BuildConfiguration *buildConfiguration() const;
|
||||
DeployConfiguration *deployConfiguration() const;
|
||||
@@ -81,6 +83,8 @@ signals:
|
||||
|
||||
void addOutput(const QString &string, ProjectExplorer::BuildStep::OutputFormat format,
|
||||
ProjectExplorer::BuildStep::OutputNewlineSetting newlineSetting = DoAppendNewline) const;
|
||||
|
||||
void finished();
|
||||
};
|
||||
|
||||
class PROJECTEXPLORER_EXPORT IBuildStepFactory :
|
||||
|
||||
Reference in New Issue
Block a user