QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
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 <QObject>
22#include "qgis_sip.h"
23#include <QMap>
24#include <QFuture>
25#include <QReadWriteLock>
26#include <QSemaphore>
27#include <QElapsedTimer>
28
29#include "qgis_core.h"
30#include "qgsmaplayer.h"
31
32class QgsTask;
33class QgsTaskRunnableWrapper;
34
36typedef QList< QgsTask * > QgsTaskList;
37
54class CORE_EXPORT QgsTask : public QObject
55{
56 Q_OBJECT
57
58 public:
59
62 {
68 };
69 Q_ENUM( TaskStatus )
70
71
72 enum Flag
73 {
74 CanCancel = 1 << 1,
75 CancelWithoutPrompt = 1 << 2,
76 Hidden = 1 << 3,
77 Silent = 1 << 4,
78 AllFlags = CanCancel,
79 };
80 Q_DECLARE_FLAGS( Flags, Flag )
81
82
87 QgsTask( const QString &description = QString(), QgsTask::Flags flags = AllFlags );
88
89 ~QgsTask() override;
90
94 Flags flags() const { return mFlags; }
95
101 void setDescription( const QString &description );
102
106 bool canCancel() const { return mFlags & CanCancel; }
107
112 bool isActive() const { return mOverallStatus == Running; }
113
117 TaskStatus status() const { return mOverallStatus; }
118
122 QString description() const { return mDescription; }
123
127 double progress() const { return mTotalProgress; }
128
136 qint64 elapsedTime() const;
137
147 virtual void cancel();
148
156 void hold();
157
164 void unhold();
165
168 {
169 SubTaskIndependent = 0,
171 };
172
193 void addSubTask( QgsTask *subTask SIP_TRANSFER, const QgsTaskList &dependencies = QgsTaskList(),
194 SubTaskDependency subTaskDependency = SubTaskIndependent );
195
201 void setDependentLayers( const QList<QgsMapLayer *> &dependentLayers );
202
208 QList< QgsMapLayer * > dependentLayers() const;
209
219 bool waitForFinished( int timeout = 30000 );
220
221 signals:
222
229 void progressChanged( double progress );
230
237 void statusChanged( int status );
238
244 void begun();
245
252
261
262 protected:
263
272 virtual bool run() = 0;
273
284 virtual void finished( bool result ) { Q_UNUSED( result ) }
285
291 bool isCanceled() const;
292
293 protected slots:
294
300 void setProgress( double progress );
301
302 private slots:
303 void subTaskStatusChanged( int status );
304
305 private:
306
307 Flags mFlags;
308 QString mDescription;
310 TaskStatus mStatus = Queued;
312 TaskStatus mOverallStatus = Queued;
313
318 QMutex mNotFinishedMutex;
319
324 QSemaphore mNotStartedMutex;
325
327 double mProgress = 0.0;
329 double mTotalProgress = 0.0;
330 bool mShouldTerminate = false;
331 mutable QMutex mShouldTerminateMutex;
332 int mStartCount = 0;
333
334 struct SubTask
335 {
336 SubTask( QgsTask *task, const QgsTaskList &dependencies, SubTaskDependency dependency )
337 : task( task )
338 , dependencies( dependencies )
339 , dependency( dependency )
340 {}
341 QgsTask *task = nullptr;
342 QgsTaskList dependencies;
343 SubTaskDependency dependency;
344 };
345 QList< SubTask > mSubTasks;
346
347 QgsWeakMapLayerPointerList mDependentLayers;
348
349 QElapsedTimer mElapsedTime;
350
351
355 void start();
356
360 void completed();
361
365 void terminated();
366
367
368 void processSubTasksForHold();
369
370 friend class QgsTaskManager;
371 friend class QgsTaskRunnableWrapper;
372 friend class TestQgsTaskManager;
373
374 private slots:
375
376 void processSubTasksForCompletion();
377
378 void processSubTasksForTermination();
379
380};
381
382
383Q_DECLARE_OPERATORS_FOR_FLAGS( QgsTask::Flags )
384
385
392class CORE_EXPORT QgsTaskManager : public QObject
393{
394 Q_OBJECT
395
396 public:
397
402 QgsTaskManager( QObject *parent SIP_TRANSFERTHIS = nullptr );
403
404 ~QgsTaskManager() override;
405
410 {
411
416 explicit TaskDefinition( QgsTask *task, const QgsTaskList &dependentTasks = QgsTaskList() )
417 : task( task )
418 , dependentTasks( dependentTasks )
419 {}
420
422 QgsTask *task = nullptr;
423
430
431 };
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
563 void taskAboutToBeDeleted( long taskId );
564
570
575 void countActiveTasksChanged( int count );
576
583 void taskTriggered( QgsTask *task );
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
593 struct TaskInfo
594 {
595 TaskInfo( QgsTask *task = nullptr, int priority = 0 );
596 void createRunnable();
597 QgsTask *task = nullptr;
598 QAtomicInt added;
599 int priority;
600 QgsTaskRunnableWrapper *runnable = nullptr;
601 };
602
603 bool mInitialized = false;
604
605 mutable QRecursiveMutex *mTaskMutex;
606
607 QMap< long, TaskInfo > mTasks;
608 QMap< long, QgsTaskList > mTaskDependencies;
609 QMap< long, QgsWeakMapLayerPointerList > mLayerDependencies;
610
612 long mNextTaskId = 1;
613
615 QSet< QgsTask * > mActiveTasks;
617 QSet< QgsTask * > mParentTasks;
619 QSet< QgsTask * > mSubTasks;
620
621 QSet< QgsTask * > mPendingDeletion;
622
623 long addTaskPrivate( QgsTask *task,
624 QgsTaskList dependencies,
625 bool isSubTask,
626 int priority );
627
628 bool cleanupAndDeleteTask( QgsTask *task );
629
634 void processQueue();
635
641 void cancelDependentTasks( long taskId );
642
643 bool resolveDependencies( long firstTaskId, long currentTaskId, QSet< long > &results ) const;
644
646 bool hasCircularDependencies( long taskId ) const;
647
648 friend class TestQgsTaskManager;
649};
650
651#endif //QGSTASKMANAGER_H
Base class for all map layer types.
Definition: qgsmaplayer.h:73
Task manager for managing a set of long-running QgsTask tasks.
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.
void taskAboutToBeDeleted(long taskId)
Emitted when a task is about to be deleted.
void allTasksFinished()
Emitted when all tasks are complete.
void progressChanged(long taskId, double progress)
Will be emitted when a task reports a progress change.
void countActiveTasksChanged(int count)
Emitted when the number of active tasks changes.
void taskTriggered(QgsTask *task)
Emitted when a task is triggered.
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.
void begun()
Will be emitted by task to indicate its commencement.
bool isActive() const
Returns true if the task is active, ie it is not complete and has not been canceled.
Flag
Task flags.
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.
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.
@ 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:53
#define SIP_SKIP
Definition: qgis_sip.h:126
#define SIP_TRANSFER
Definition: qgis_sip.h:36
Q_DECLARE_OPERATORS_FOR_FLAGS(QgsField::ConfigurationFlags) CORE_EXPORT QDataStream &operator<<(QDataStream &out
Writes the field to stream out. QGIS version compatibility is not guaranteed.
QList< QgsWeakMapLayerPointer > QgsWeakMapLayerPointerList
A list of weak pointers to QgsMapLayers.
Definition: qgsmaplayer.h:2213
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.