* factor having a runner into QueryMatch::isEnabled

* only run a match when the job is actually done, in case people write runners that don't like to have both match and run entered simultaneously (high likliehood of that happening); lets them write runners with fewer threading concerns

svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=805919
This commit is contained in:
Aaron J. Seigo 2008-05-09 17:19:27 +00:00
parent 09fb90b051
commit c0279bc3e2
3 changed files with 67 additions and 17 deletions

View File

@ -169,7 +169,7 @@ void QueryMatch::setEnabled( bool enabled )
bool QueryMatch::isEnabled() const
{
return d->enabled;
return d->enabled && d->runner;
}
bool QueryMatch::operator<(const QueryMatch& other) const
@ -190,7 +190,6 @@ void QueryMatch::run(const RunnerContext &context) const
{
//kDebug() << "we run the term" << context->query() << "whose type is" << context->mimetype();
if (d->runner) {
//TODO: this could be dangerous if the runner is deleted behind our backs.
d->runner->run(context, *this);
}
}

View File

@ -143,22 +143,21 @@ void RunnerRestrictionPolicy::destructed(Job* job)
class FindMatchesJob : public Job
{
public:
FindMatchesJob(const QString& term, Plasma::AbstractRunner* runner, Plasma::RunnerContext* context, QObject* parent = 0);
FindMatchesJob(Plasma::AbstractRunner* runner, Plasma::RunnerContext* context, QObject* parent = 0);
int priority() const;
Plasma::AbstractRunner* runner() const;
protected:
void run();
private:
QString m_term;
Plasma::RunnerContext* m_context;
Plasma::AbstractRunner* m_runner;
};
FindMatchesJob::FindMatchesJob( const QString& term, Plasma::AbstractRunner* runner,
FindMatchesJob::FindMatchesJob(Plasma::AbstractRunner* runner,
Plasma::RunnerContext* context, QObject* parent)
: ThreadWeaver::Job(parent),
m_term(term),
m_context(context),
m_runner(runner)
{
@ -178,6 +177,10 @@ int FindMatchesJob::priority() const
return m_runner->priority();
}
Plasma::AbstractRunner* FindMatchesJob::runner() const
{
return m_runner;
}
/*****************************************************
* RunnerManager::Private class
@ -188,7 +191,8 @@ class RunnerManager::Private
public:
Private(RunnerManager *parent)
: q(parent)
: q(parent),
deferredRun(0)
{
matchChangeTimer.setSingleShot(true);
connect(&matchChangeTimer, SIGNAL(timeout()), q, SLOT(scheduleMatchesChanged()));
@ -273,11 +277,24 @@ public:
//kDebug() << "All runners loaded, total:" << runners.count();
}
void jobDone(ThreadWeaver::Job* job)
{
FindMatchesJob *runJob = static_cast<FindMatchesJob*>(job);
if (deferredRun.isEnabled() && runJob->runner() == deferredRun.runner()) {
//kDebug() << "job actually done, running now **************";
deferredRun.run(context);
deferredRun = QueryMatch(0);
}
searchJobs.removeAll(runJob);
delete runJob;
}
RunnerManager *q;
QueryMatch deferredRun;
RunnerContext context;
QTimer matchChangeTimer;
AbstractRunner::List runners;
QList<ThreadWeaver::Job*> searchJobs;
QList<FindMatchesJob*> searchJobs;
QStringList prioritylist;
QStringList blacklist;
KConfigGroup config;
@ -341,8 +358,26 @@ QList<QueryMatch> RunnerManager::matches() const
void RunnerManager::run(const QueryMatch &match)
{
if (!match.isEnabled()) {
return;
}
//TODO: this function is not const as it may be used for learning
AbstractRunner *runner = match.runner();
foreach (FindMatchesJob *job, d->searchJobs) {
if (job->runner() == runner && !job->isFinished()) {
//kDebug() << "!!!!!!!!!!!!!!!!!!! uh oh!";
d->deferredRun = match;
return;
}
}
match.run(d->context);
if (d->deferredRun.isValid()) {
d->deferredRun = QueryMatch(0);
}
}
void RunnerManager::launchQuery(const QString & term, const QString & runnerName)
@ -370,12 +405,11 @@ void RunnerManager::launchQuery (const QString & term, const QString & runnerNam
runable = d->runners;
}
bool jobsLaunched=false;
foreach (Plasma::AbstractRunner* r, runable) {
if ((r->ignoredTypes() & d->context.type()) == 0) {
// kDebug() << "launching" << r->name();
jobsLaunched=true;
Job *job = new FindMatchesJob(term, r, &d->context, this);
FindMatchesJob *job = new FindMatchesJob(r, &d->context, this);
connect(job, SIGNAL(done(ThreadWeaver::Job*)), this, SLOT(jobDone(ThreadWeaver::Job*)));
Weaver::instance()->enqueue(job);
d->searchJobs.append(job);
}
@ -416,6 +450,11 @@ bool RunnerManager::execQuery(const QString &term, const QString &runnerName)
return true;
}
QString RunnerManager::query() const
{
return d->context.query();
}
void RunnerManager::reset()
{
// If ThreadWeaver is idle, it is safe to clear previous jobs
@ -425,6 +464,13 @@ void RunnerManager::reset()
} else {
Weaver::instance()->dequeue();
}
if (d->deferredRun.isEnabled()) {
//kDebug() << "job actually done, running now **************";
d->deferredRun.run(d->context);
d->deferredRun = QueryMatch(0);
}
d->context.reset();
//FIXME: if the weaver is not idle we have a number of jobs that
@ -433,7 +479,6 @@ void RunnerManager::reset()
// or discard results
}
}
} // Plasma namespace
#include "runnermanager.moc"

View File

@ -95,6 +95,11 @@ class PLASMA_EXPORT RunnerManager : public QObject
*/
bool execQuery(const QString &term, const QString & runnerName);
/**
* @return the current query term
*/
QString query() const;
/**
* Reset the current data and stops the query
*/
@ -109,6 +114,7 @@ class PLASMA_EXPORT RunnerManager : public QObject
private:
Q_PRIVATE_SLOT(d, void scheduleMatchesChanged())
Q_PRIVATE_SLOT(d, void matchesChanged())
Q_PRIVATE_SLOT(d, void jobDone(ThreadWeaver::Job*))
class Private;
Private * const d;