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

View File

@@ -447,6 +447,27 @@ private:
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
* on a target device. It controls start and stop, and handles
@@ -510,8 +531,8 @@ public:
RunWorker *createWorker(Core::Id id);
using WorkerCreator = std::function<RunWorker *(RunControl *)>;
using Constraint = std::function<bool(RunConfiguration *)>;
using WorkerCreator = RunWorkerFactory::WorkerCreator;
using Constraint = RunWorkerFactory::Constraint;
static void registerWorkerCreator(Core::Id id, const WorkerCreator &workerCreator);
@@ -534,18 +555,6 @@ public:
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);
signals:
@@ -561,7 +570,7 @@ private:
friend class RunWorker;
friend class Internal::RunWorkerPrivate;
static void addWorkerFactory(const WorkerFactory &workerFactory);
static void addWorkerFactory(const RunWorkerFactory &workerFactory);
Internal::RunControlPrivate *d;
};