QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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
53class CORE_EXPORT QgsTask : public QObject
54{
55 Q_OBJECT
56
57 public:
58
61 {
67 };
68 Q_ENUM( TaskStatus )
69
70
71 enum Flag SIP_ENUM_BASETYPE( IntFlag )
72 {
73 CanCancel = 1 << 1,
74 CancelWithoutPrompt = 1 << 2,
75 Hidden = 1 << 3,
76 Silent = 1 << 4,
77 AllFlags = CanCancel,
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
167 {
168 SubTaskIndependent = 0,
170 };
171
192 void addSubTask( QgsTask *subTask SIP_TRANSFER, const QgsTaskList &dependencies = QgsTaskList(),
193 SubTaskDependency subTaskDependency = SubTaskIndependent );
194
200 void setDependentLayers( const QList<QgsMapLayer *> &dependentLayers );
201
207 QList< QgsMapLayer * > dependentLayers() const;
208
218 bool waitForFinished( int timeout = 30000 );
219
220 signals:
221
228 void progressChanged( double progress );
229
236 void statusChanged( int status );
237
243 void begun();
244
251
260
261 protected:
262
271 virtual bool run() = 0;
272
283 virtual void finished( bool result ) { Q_UNUSED( result ) }
284
290 bool isCanceled() const;
291
292 protected slots:
293
299 void setProgress( double progress );
300
301 private slots:
302 void subTaskStatusChanged( int status );
303
304 private:
305
306 Flags mFlags;
307 QString mDescription;
309 TaskStatus mStatus = Queued;
311 TaskStatus mOverallStatus = Queued;
312
317 QMutex mNotFinishedMutex;
318
323 QSemaphore mNotStartedMutex;
324
326 double mProgress = 0.0;
328 double mTotalProgress = 0.0;
329 bool mShouldTerminate = false;
330 mutable QMutex mShouldTerminateMutex;
331 int mStartCount = 0;
332
333 struct SubTask
334 {
335 SubTask( QgsTask *task, const QgsTaskList &dependencies, SubTaskDependency dependency )
336 : task( task )
337 , dependencies( dependencies )
338 , dependency( dependency )
339 {}
340 QgsTask *task = nullptr;
341 QgsTaskList dependencies;
342 SubTaskDependency dependency;
343 };
344 QList< SubTask > mSubTasks;
345
346 QgsWeakMapLayerPointerList mDependentLayers;
347
348 QElapsedTimer mElapsedTime;
349
350
354 void start();
355
359 void completed();
360
364 void terminated();
365
366
367 void processSubTasksForHold();
368
369 friend class QgsTaskManager;
370 friend class QgsTaskRunnableWrapper;
371 friend class TestQgsTaskManager;
372
373 private slots:
374
375 void processSubTasksForCompletion();
376
377 void processSubTasksForTermination();
378
379};
380
381
383
384
390class CORE_EXPORT QgsTaskManager : public QObject
391{
392 Q_OBJECT
393
394 public:
395
400 QgsTaskManager( QObject *parent SIP_TRANSFERTHIS = nullptr );
401
402 ~QgsTaskManager() override;
403
408 {
409
414 explicit TaskDefinition( QgsTask *task, const QgsTaskList &dependentTasks = QgsTaskList() )
415 : task( task )
416 , dependentTasks( dependentTasks )
417 {}
418
420 QgsTask *task = nullptr;
421
428
429 };
430
436 QThreadPool *threadPool();
437
446 long addTask( QgsTask *task SIP_TRANSFER, int priority = 0 );
447
456 long addTask( const TaskDefinition &task SIP_TRANSFER, int priority = 0 );
457
463 QgsTask *task( long id ) const;
464
468 QList<QgsTask *> tasks() const;
469
471 int count() const;
472
478 long taskId( QgsTask *task ) const;
479
485 void cancelAll();
486
488 bool dependenciesSatisfied( long taskId ) const;
489
494 QSet< long > dependencies( long taskId ) const SIP_SKIP;
495
503 QList< QgsMapLayer * > dependentLayers( long taskId ) const;
504
509 QList< QgsTask * > tasksDependentOnLayer( QgsMapLayer *layer ) const;
510
515 QList< QgsTask * > activeTasks() const;
516
525 int countActiveTasks( bool includeHidden = true ) const;
526
527 public slots:
528
533 void triggerTask( QgsTask *task );
534
535 signals:
536
542 void progressChanged( long taskId, double progress );
543
549 void finalTaskProgressChanged( double progress );
550
556 void statusChanged( long taskId, int status );
557
562 void taskAdded( long taskId );
563
568 void taskAboutToBeDeleted( long taskId );
569
575
580 void countActiveTasksChanged( int count );
581
588 void taskTriggered( QgsTask *task );
589
590 private slots:
591
592 void taskProgressChanged( double progress );
593 void taskStatusChanged( int status );
594 void layersWillBeRemoved( const QList<QgsMapLayer *> &layers );
595
596 private:
597
598 struct TaskInfo
599 {
600 TaskInfo( QgsTask *task = nullptr, int priority = 0 );
601 void createRunnable();
602 QgsTask *task = nullptr;
603 QAtomicInt added;
604 int priority;
605 QgsTaskRunnableWrapper *runnable = nullptr;
606 };
607
608 QThreadPool *mThreadPool = nullptr;
609
610 bool mInitialized = false;
611
612 mutable QRecursiveMutex *mTaskMutex;
613
614 QMap< long, TaskInfo > mTasks;
615 QMap< long, QgsTaskList > mTaskDependencies;
616 QMap< long, QgsWeakMapLayerPointerList > mLayerDependencies;
617
619 long mNextTaskId = 1;
620
622 QSet< QgsTask * > mActiveTasks;
624 QSet< QgsTask * > mParentTasks;
626 QSet< QgsTask * > mSubTasks;
627
628 QSet< QgsTask * > mPendingDeletion;
629
630 long addTaskPrivate( QgsTask *task,
631 QgsTaskList dependencies,
632 bool isSubTask,
633 int priority );
634
635 bool cleanupAndDeleteTask( QgsTask *task );
636
641 void processQueue();
642
648 void cancelDependentTasks( long taskId );
649
650 bool resolveDependencies( long firstTaskId, long currentTaskId, QSet< long > &results ) const;
651
653 bool hasCircularDependencies( long taskId ) const;
654
655 friend class TestQgsTaskManager;
656};
657
658#endif //QGSTASKMANAGER_H
Base class for all map layer types.
Definition: qgsmaplayer.h:75
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.
QFlags< Flag > Flags
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_ENUM_BASETYPE(type)
Definition: qgis_sip.h:278
#define SIP_SKIP
Definition: qgis_sip.h:126
#define SIP_TRANSFER
Definition: qgis_sip.h:36
QList< QgsWeakMapLayerPointer > QgsWeakMapLayerPointerList
A list of weak pointers to QgsMapLayers.
Definition: qgsmaplayer.h:2355
QList< QgsTask * > QgsTaskList
List of QgsTask objects.
Q_DECLARE_OPERATORS_FOR_FLAGS(QgsTextRendererUtils::CurvedTextFlags)
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.