QGIS API Documentation 3.39.0-Master (d85f3c2a281)
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 <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
69 Q_ENUM( TaskStatus )
70
71
72 enum Flag SIP_ENUM_BASETYPE( IntFlag )
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;
372 friend class QgsTaskRunnableWrapper;
373 friend class TestQgsTaskManager;
374
375 private slots:
376
377 void processSubTasksForCompletion();
378
379 void processSubTasksForTermination();
380
381};
382
383
385
386
393class CORE_EXPORT QgsTaskManager : public QObject
394{
395 Q_OBJECT
396
397 public:
398
403 QgsTaskManager( QObject *parent SIP_TRANSFERTHIS = nullptr );
404
405 ~QgsTaskManager() override;
406
411 {
412
417 explicit TaskDefinition( QgsTask *task, const QgsTaskList &dependentTasks = QgsTaskList() )
418 : task( task )
419 , dependentTasks( dependentTasks )
420 {}
421
423 QgsTask *task = nullptr;
424
431
432 };
433
439 QThreadPool *threadPool();
440
449 long addTask( QgsTask *task SIP_TRANSFER, int priority = 0 );
450
459 long addTask( const TaskDefinition &task SIP_TRANSFER, int priority = 0 );
460
466 QgsTask *task( long id ) const;
467
471 QList<QgsTask *> tasks() const;
472
474 int count() const;
475
481 long taskId( QgsTask *task ) const;
482
488 void cancelAll();
489
491 bool dependenciesSatisfied( long taskId ) const;
492
497 QSet< long > dependencies( long taskId ) const SIP_SKIP;
498
506 QList< QgsMapLayer * > dependentLayers( long taskId ) const;
507
512 QList< QgsTask * > tasksDependentOnLayer( QgsMapLayer *layer ) const;
513
518 QList< QgsTask * > activeTasks() const;
519
528 int countActiveTasks( bool includeHidden = true ) const;
529
530 public slots:
531
536 void triggerTask( QgsTask *task );
537
538 signals:
539
545 void progressChanged( long taskId, double progress );
546
552 void finalTaskProgressChanged( double progress );
553
559 void statusChanged( long taskId, int status );
560
565 void taskAdded( long taskId );
566
571 void taskAboutToBeDeleted( long taskId );
572
578
583 void countActiveTasksChanged( int count );
584
591 void taskTriggered( QgsTask *task );
592
593 private slots:
594
595 void taskProgressChanged( double progress );
596 void taskStatusChanged( int status );
597 void layersWillBeRemoved( const QList<QgsMapLayer *> &layers );
598
599 private:
600
601 struct TaskInfo
602 {
603 TaskInfo( QgsTask *task = nullptr, int priority = 0 );
604 void createRunnable();
605 QgsTask *task = nullptr;
606 QAtomicInt added;
607 int priority;
608 QgsTaskRunnableWrapper *runnable = nullptr;
609 };
610
611 QThreadPool *mThreadPool = nullptr;
612
613 bool mInitialized = false;
614
615 mutable QRecursiveMutex *mTaskMutex;
616
617 QMap< long, TaskInfo > mTasks;
618 QMap< QgsTask *, long> mMapTaskPtrToId;
619 QMap< long, QgsTaskList > mTaskDependencies;
620 QMap< long, QgsWeakMapLayerPointerList > mLayerDependencies;
621
623 long mNextTaskId = 1;
624
626 QSet< QgsTask * > mActiveTasks;
628 QSet< QgsTask * > mParentTasks;
630 QSet< QgsTask * > mSubTasks;
631
632 QSet< QgsTask * > mPendingDeletion;
633
634 long addTaskPrivate( QgsTask *task,
635 QgsTaskList dependencies,
636 bool isSubTask,
637 int priority );
638
639 bool cleanupAndDeleteTask( QgsTask *task );
640
645 void processQueue();
646
652 void cancelDependentTasks( long taskId );
653
654 bool resolveDependencies( long taskId, QSet< long > &results ) const;
655
657 bool hasCircularDependencies( long taskId ) const;
658
659 friend class TestQgsTaskManager;
660};
661
670class CORE_EXPORT QgsTaskWithSerialSubTasks : public QgsTask
671{
672 Q_OBJECT
673
674 public:
676 QgsTaskWithSerialSubTasks( const QString &desc = QString() ) : QgsTask( desc ) {}
678
688 void addSubTask( QgsTask *subTask SIP_TRANSFER );
689
690 void cancel() override;
691
692 protected:
693
694 QList< QgsTask *> mSubTasksSerial;
695
696 bool run() override;
697};
698
699#endif //QGSTASKMANAGER_H
Base class for all map layer types.
Definition qgsmaplayer.h:76
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.
Task that is composed of sub-tasks to be executed in a serial way, which may be useful for example to...
QList< QgsTask * > mSubTasksSerial
QgsTaskWithSerialSubTasks(const QString &desc=QString())
Constructor.
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.
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.