QGIS API Documentation 4.1.0-Master (60fea48833c)
Loading...
Searching...
No Matches
qgstaskmanager.h
Go to the documentation of this file.
1/***************************************************************************
2 qgstaskmanager.h
3 ----------------
4 begin : April 2016
5 copyright : (C) 2016 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#ifndef QGSTASKMANAGER_H
19#define QGSTASKMANAGER_H
20
21#include "qgis_core.h"
22#include "qgis_sip.h"
23#include "qgsmaplayer.h"
24
25#include <QElapsedTimer>
26#include <QFuture>
27#include <QMap>
28#include <QObject>
29#include <QReadWriteLock>
30#include <QSemaphore>
31
32class QgsTask;
33class QgsTaskRunnableWrapper;
34
36typedef QList< QgsTask * > QgsTaskList;
37
54class CORE_EXPORT QgsTask : public QObject
55{
56 Q_OBJECT
57
58 public:
68 Q_ENUM( TaskStatus )
69
70
71 enum Flag SIP_ENUM_BASETYPE( IntFlag )
72 {
73 CanCancel = 1 << 1,
75 Hidden = 1 << 3,
76 Silent = 1 << 4,
78 };
79 Q_DECLARE_FLAGS( Flags, Flag )
80
81
86 QgsTask( const QString &description = QString(), QgsTask::Flags flags = AllFlags );
87
88 ~QgsTask() override;
89
93 Flags flags() const { return mFlags; }
94
100 void setDescription( const QString &description );
101
105 bool canCancel() const { return mFlags & CanCancel; }
106
111 bool isActive() const { return mOverallStatus == Running; }
112
116 TaskStatus status() const { return mOverallStatus; }
117
121 QString description() const { return mDescription; }
122
126 double progress() const { return mTotalProgress; }
127
135 qint64 elapsedTime() const;
136
146 virtual void cancel();
147
155 void hold();
156
163 void unhold();
164
171
192 void addSubTask( QgsTask *subTask SIP_TRANSFER, const QgsTaskList &dependencies = QgsTaskList(), SubTaskDependency subTaskDependency = SubTaskIndependent );
193
199 void setDependentLayers( const QList<QgsMapLayer *> &dependentLayers );
200
206 QList< QgsMapLayer * > dependentLayers() const;
207
217 bool waitForFinished( int timeout = 30000 );
218
219 signals:
220
227 void progressChanged( double progress );
228
236
242 void begun();
243
250
259
260 protected:
269 virtual bool run() = 0;
270
281 virtual void finished( bool result ) { Q_UNUSED( result ) }
282
288 bool isCanceled() const;
289
290 protected slots:
291
297 void setProgress( double progress );
298
299 private slots:
300 void subTaskStatusChanged( int status );
301
302 private:
303 Flags mFlags;
304 QString mDescription;
306 TaskStatus mStatus = Queued;
308 TaskStatus mOverallStatus = Queued;
309
314 QMutex mNotFinishedMutex;
315
320 QSemaphore mNotStartedMutex;
321
323 double mProgress = 0.0;
325 double mTotalProgress = 0.0;
326 bool mShouldTerminate = false;
327 mutable QMutex mShouldTerminateMutex;
328 int mStartCount = 0;
329
330 struct SubTask
331 {
332 SubTask( QgsTask *task, const QgsTaskList &dependencies, SubTaskDependency dependency )
333 : task( task )
334 , dependencies( dependencies )
335 , dependency( dependency )
336 {}
337 QgsTask *task = nullptr;
338 QgsTaskList dependencies;
339 SubTaskDependency dependency;
340 };
341 QList< SubTask > mSubTasks;
342
343 QgsWeakMapLayerPointerList mDependentLayers;
344
345 QElapsedTimer mElapsedTime;
346
347
351 void start();
352
356 void completed();
357
361 void terminated();
362
363
364 void processSubTasksForHold();
365
366 friend class QgsTaskManager;
369 friend class TestQgsTaskManager;
370
371 private slots:
372
373 void processSubTasksForCompletion();
374
375 void processSubTasksForTermination();
376};
377
378
380
381
388class CORE_EXPORT QgsTaskManager : public QObject
389{
390 Q_OBJECT
391
392 public:
397 QgsTaskManager( QObject *parent SIP_TRANSFERTHIS = nullptr );
398
399 ~QgsTaskManager() override;
400
425
431 QThreadPool *threadPool();
432
441 long addTask( QgsTask *task SIP_TRANSFER, int priority = 0 );
442
451 long addTask( const TaskDefinition &task SIP_TRANSFER, int priority = 0 );
452
458 QgsTask *task( long id ) const;
459
463 QList<QgsTask *> tasks() const;
464
466 int count() const;
467
473 long taskId( QgsTask *task ) const;
474
480 void cancelAll();
481
483 bool dependenciesSatisfied( long taskId ) const;
484
489 QSet< long > dependencies( long taskId ) const SIP_SKIP;
490
498 QList< QgsMapLayer * > dependentLayers( long taskId ) const;
499
504 QList< QgsTask * > tasksDependentOnLayer( QgsMapLayer *layer ) const;
505
510 QList< QgsTask * > activeTasks() const;
511
520 int countActiveTasks( bool includeHidden = true ) const;
521
522 public slots:
523
528 void triggerTask( QgsTask *task );
529
530 signals:
531
537 void progressChanged( long taskId, double progress );
538
544 void finalTaskProgressChanged( double progress );
545
551 void statusChanged( long taskId, int status );
552
557 void taskAdded( long taskId );
558
564
570
576
584
585 private slots:
586
587 void taskProgressChanged( double progress );
588 void taskStatusChanged( int status );
589 void layersWillBeRemoved( const QList<QgsMapLayer *> &layers );
590
591 private:
592 struct TaskInfo
593 {
594 TaskInfo( QgsTask *task = nullptr, int priority = 0 );
595 void createRunnable();
596 QgsTask *task = nullptr;
597 QAtomicInt added;
598 int priority;
599 QgsTaskRunnableWrapper *runnable = nullptr;
600 };
601
602 QThreadPool *mThreadPool = nullptr;
603
604 bool mInitialized = false;
605
606 mutable QRecursiveMutex *mTaskMutex;
607
608 QMap< long, TaskInfo > mTasks;
609 QMap< QgsTask *, long> mMapTaskPtrToId;
610 QMap< long, QgsTaskList > mTaskDependencies;
611 QMap< long, QgsWeakMapLayerPointerList > mLayerDependencies;
612
614 long mNextTaskId = 1;
615
617 QSet< QgsTask * > mActiveTasks;
619 QSet< QgsTask * > mParentTasks;
621 QSet< QgsTask * > mSubTasks;
622
623 QSet< QgsTask * > mPendingDeletion;
624
625 long addTaskPrivate( QgsTask *task, QgsTaskList dependencies, bool isSubTask, int priority );
626
627 bool cleanupAndDeleteTask( QgsTask *task );
628
633 void processQueue();
634
640 void cancelDependentTasks( long taskId );
641
642 bool resolveDependencies( long taskId, QSet< long > &results ) const;
643
645 bool hasCircularDependencies( long taskId ) const;
646
647 friend class TestQgsTaskManager;
648};
649
659class CORE_EXPORT QgsTaskWithSerialSubTasks : public QgsTask
660{
661 Q_OBJECT
662
663 public:
665 QgsTaskWithSerialSubTasks( const QString &desc = QString() )
666 : QgsTask( desc )
667 {}
669
679 void addSubTask( QgsTask *subTask SIP_TRANSFER );
680
681 void cancel() override;
682
683 protected:
684 QList< QgsTask *> mSubTasksSerial;
685
686 bool run() override;
687};
688
689#endif //QGSTASKMANAGER_H
Base class for all map layer types.
Definition qgsmaplayer.h:83
QList< QgsTask * > tasks() const
Returns all tasks tracked by the manager.
void finalTaskProgressChanged(double progress)
Will be emitted when only a single task remains to complete and that task has reported a progress cha...
void statusChanged(long taskId, int status)
Will be emitted when a task reports a status change.
void taskAdded(long taskId)
Emitted when a new task has been added to the manager.
friend class TestQgsTaskManager
QList< QgsTask * > activeTasks() const
Returns a list of the active (queued or running) tasks.
QgsTaskManager(QObject *parent=nullptr)
Constructor for QgsTaskManager.
void taskAboutToBeDeleted(long taskId)
Emitted when a task is about to be deleted.
long taskId(QgsTask *task) const
Returns the unique task ID corresponding to a task managed by the class.
int count() const
Returns the number of tasks tracked by the manager.
QList< QgsTask * > tasksDependentOnLayer(QgsMapLayer *layer) const
Returns a list of tasks which depend on a layer.
void allTasksFinished()
Emitted when all tasks are complete.
bool dependenciesSatisfied(long taskId) const
Returns true if all dependencies for the specified task are satisfied.
QThreadPool * threadPool()
Returns the threadpool utilized by the task manager.
void cancelAll()
Instructs all tasks tracked by the manager to terminate.
QSet< long > dependencies(long taskId) const
Returns the set of task IDs on which a task is dependent.
QgsTask * task(long id) const
Returns the task with matching ID.
void progressChanged(long taskId, double progress)
Will be emitted when a task reports a progress change.
int countActiveTasks(bool includeHidden=true) const
Returns the number of active (queued or running) tasks.
void triggerTask(QgsTask *task)
Triggers a task, e.g.
void countActiveTasksChanged(int count)
Emitted when the number of active tasks changes.
QList< QgsMapLayer * > dependentLayers(long taskId) const
Returns a list of layers on which as task is dependent.
long addTask(QgsTask *task, int priority=0)
Adds a task to the manager.
void taskTriggered(QgsTask *task)
Emitted when a task is triggered.
A task that is composed of sub-tasks to be executed in a serial way.
QList< QgsTask * > mSubTasksSerial
QgsTaskWithSerialSubTasks(const QString &desc=QString())
Constructor.
bool run() override
Performs the task's operation.
Abstract base class for long running background tasks.
TaskStatus status() const
Returns the current task status.
Flags flags() const
Returns the flags associated with the task.
void taskCompleted()
Will be emitted by task to indicate its successful completion.
double progress() const
Returns the task's progress (between 0.0 and 100.0).
virtual void finished(bool result)
If the task is managed by a QgsTaskManager, this will be called after the task has finished (whether ...
virtual bool run()=0
Performs the task's operation.
void progressChanged(double progress)
Will be emitted by task when its progress changes.
QFlags< Flag > Flags
friend class TestQgsTaskManager
friend class QgsTaskRunnableWrapper
void begun()
Will be emitted by task to indicate its commencement.
QgsTask(const QString &description=QString(), QgsTask::Flags flags=AllFlags)
Constructor for QgsTask.
bool isActive() const
Returns true if the task is active, ie it is not complete and has not been canceled.
Flag
Task flags.
@ Hidden
Hide task from GUI.
@ CanCancel
Task can be canceled.
@ AllFlags
Task supports all flags.
@ CancelWithoutPrompt
Task can be canceled without any users prompts, e.g. when closing a project or QGIS.
@ Silent
Don't show task updates (such as completion/failure messages) as operating-system level notifications...
void taskTerminated()
Will be emitted by task if it has terminated for any reason other then completion (e....
void statusChanged(int status)
Will be emitted by task when its status changes.
friend class QgsTaskWithSerialSubTasks
friend class QgsTaskManager
TaskStatus
Status of tasks.
@ Terminated
Task was terminated or errored.
@ Queued
Task is queued and has not begun.
@ OnHold
Task is queued but on hold and will not be started.
@ Running
Task is currently running.
@ Complete
Task successfully completed.
QString description() const
Returns the task's description.
SubTaskDependency
Controls how subtasks relate to their parent task.
@ SubTaskIndependent
Subtask is independent of the parent, and can run before, after or at the same time as the parent.
@ ParentDependsOnSubTask
Subtask must complete before parent can begin.
bool canCancel() const
Returns true if the task can be canceled.
#define SIP_TRANSFERTHIS
Definition qgis_sip.h:52
#define SIP_ENUM_BASETYPE(type)
Definition qgis_sip.h:274
#define SIP_SKIP
Definition qgis_sip.h:133
#define SIP_TRANSFER
Definition qgis_sip.h:35
QList< QgsWeakMapLayerPointer > QgsWeakMapLayerPointerList
A list of weak pointers to QgsMapLayers.
Q_DECLARE_OPERATORS_FOR_FLAGS(QgsProjectionSelectionWidget::CrsOptions)
QList< QgsTask * > QgsTaskList
List of QgsTask objects.
Definition of a task for inclusion in the manager.
TaskDefinition(QgsTask *task, const QgsTaskList &dependentTasks=QgsTaskList())
Constructor for TaskDefinition.
QgsTaskList dependentTasks
List of dependent tasks which must be completed before task can run.