ProjectExplorer: Create a RunWorkerFactory class

This paddles back a bit on the RunWorker creation setup mainly
to get a more flexible setup when it comes to share RunWorkers
between different setups.

Change-Id: I263742cb1df3689f133a2f6f948ed59a2a52d383
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
hjk
2018-05-11 11:05:40 +02:00
parent 7b3ed7799d
commit 1f3381a3c2
2 changed files with 50 additions and 36 deletions

View File

@@ -680,23 +680,32 @@ FixedRunConfigurationFactory::availableCreators(Target *parent) const
return {rci}; return {rci};
} }
using WorkerFactories = std::vector<RunControl::WorkerFactory>;
static WorkerFactories &theWorkerFactories() // RunWorkerFactory
using RunWorkerFactories = std::vector<RunWorkerFactory>;
static RunWorkerFactories &theWorkerFactories()
{ {
static WorkerFactories factories; static RunWorkerFactories factories;
return factories; return factories;
} }
bool RunControl::WorkerFactory::canRun(RunConfiguration *runConfiguration, Core::Id runMode) const RunWorkerFactory::RunWorkerFactory(Core::Id mode, Constraint constr, const WorkerCreator &prod, int prio)
: m_runMode(mode), m_constraint(constr), m_producer(prod), m_priority(prio)
{}
bool RunWorkerFactory::canRun(RunConfiguration *runConfiguration, Core::Id runMode) const
{ {
if (runMode != this->runMode) if (runMode != this->m_runMode)
return false; return false;
if (!constraint) if (!m_constraint)
return true; return true;
return constraint(runConfiguration); return m_constraint(runConfiguration);
} }
/*! /*!
\class ProjectExplorer::RunControl \class ProjectExplorer::RunControl
\brief The RunControl class instances represent one item that is run. \brief The RunControl class instances represent one item that is run.
@@ -885,7 +894,7 @@ public:
QPointer<Project> project; // Not owned. QPointer<Project> project; // Not owned.
QPointer<Utils::OutputFormatter> outputFormatter = nullptr; QPointer<Utils::OutputFormatter> outputFormatter = nullptr;
std::function<bool(bool*)> promptToStop; std::function<bool(bool*)> promptToStop;
std::vector<RunControl::WorkerFactory> m_factories; std::vector<RunWorkerFactory> m_factories;
// A handle to the actual application process. // A handle to the actual application process.
Utils::ProcessHandle applicationProcessHandle; Utils::ProcessHandle applicationProcessHandle;
@@ -991,27 +1000,23 @@ RunWorker *RunControl::createWorker(Core::Id id)
return nullptr; return nullptr;
} }
RunControl::WorkerCreator RunControl::producer(RunConfiguration *runConfiguration, Core::Id runMode) RunWorkerFactory::WorkerCreator RunControl::producer(RunConfiguration *runConfig, Core::Id runMode)
{ {
WorkerFactories candidates; const auto canRun = std::bind(&RunWorkerFactory::canRun, std::placeholders::_1, runConfig, runMode);
for (const RunControl::WorkerFactory &factory : theWorkerFactories()) { const RunWorkerFactories candidates = Utils::filtered(theWorkerFactories(), canRun);
if (factory.canRun(runConfiguration, runMode))
candidates.push_back(factory);
}
if (candidates.empty()) if (candidates.empty())
return {}; return {};
RunControl::WorkerFactory bestFactory = *candidates.begin(); const auto higherPriority = std::bind(std::greater<int>(),
for (const RunControl::WorkerFactory &factory : candidates) { std::bind(&RunWorkerFactory::priority, std::placeholders::_1),
if (factory.priority > bestFactory.priority) std::bind(&RunWorkerFactory::priority, std::placeholders::_2));
bestFactory = factory; const auto bestFactory = std::max_element(candidates.begin(), candidates.end(), higherPriority);
return bestFactory->producer();
} }
return bestFactory.producer; void RunControl::addWorkerFactory(const RunWorkerFactory &workerFactory)
}
void RunControl::addWorkerFactory(const RunControl::WorkerFactory &workerFactory)
{ {
theWorkerFactories().push_back(workerFactory); theWorkerFactories().push_back(workerFactory);
} }

View File

@@ -447,6 +447,27 @@ private:
Internal::RunWorkerPrivate *d; Internal::RunWorkerPrivate *d;
}; };
class PROJECTEXPLORER_EXPORT RunWorkerFactory
{
public:
using WorkerCreator = std::function<RunWorker *(RunControl *)>;
using Constraint = std::function<bool(RunConfiguration *)>;
RunWorkerFactory(Core::Id mode, Constraint constr, const WorkerCreator &prod,
int prio = 0);
bool canRun(RunConfiguration *runConfiguration, Core::Id m_runMode) const;
int priority() const { return m_priority; }
WorkerCreator producer() const { return m_producer; }
private:
Core::Id m_runMode;
Constraint m_constraint;
WorkerCreator m_producer;
int m_priority = 0;
};
/** /**
* A RunControl controls the running of an application or tool * A RunControl controls the running of an application or tool
* on a target device. It controls start and stop, and handles * on a target device. It controls start and stop, and handles
@@ -510,8 +531,8 @@ public:
RunWorker *createWorker(Core::Id id); RunWorker *createWorker(Core::Id id);
using WorkerCreator = std::function<RunWorker *(RunControl *)>; using WorkerCreator = RunWorkerFactory::WorkerCreator;
using Constraint = std::function<bool(RunConfiguration *)>; using Constraint = RunWorkerFactory::Constraint;
static void registerWorkerCreator(Core::Id id, const WorkerCreator &workerCreator); static void registerWorkerCreator(Core::Id id, const WorkerCreator &workerCreator);
@@ -534,18 +555,6 @@ public:
addWorkerFactory({runMode, constraint, producer, priority}); addWorkerFactory({runMode, constraint, producer, priority});
} }
struct WorkerFactory {
Core::Id runMode;
Constraint constraint;
WorkerCreator producer;
int priority = 0;
WorkerFactory(const Core::Id &mode, Constraint constr, const WorkerCreator &prod,
int prio = 0)
: runMode(mode), constraint(constr), producer(prod), priority(prio) {}
bool canRun(RunConfiguration *runConfiguration, Core::Id runMode) const;
};
static WorkerCreator producer(RunConfiguration *runConfiguration, Core::Id runMode); static WorkerCreator producer(RunConfiguration *runConfiguration, Core::Id runMode);
signals: signals:
@@ -561,7 +570,7 @@ private:
friend class RunWorker; friend class RunWorker;
friend class Internal::RunWorkerPrivate; friend class Internal::RunWorkerPrivate;
static void addWorkerFactory(const WorkerFactory &workerFactory); static void addWorkerFactory(const RunWorkerFactory &workerFactory);
Internal::RunControlPrivate *d; Internal::RunControlPrivate *d;
}; };