QGIS API Documentation 3.39.0-Master (52f98f8c831)
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
53class CORE_EXPORT QgsTask : public QObject
54{
55 Q_OBJECT
56
57 public:
58
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;
371 friend class QgsTaskRunnableWrapper;
372 friend class TestQgsTaskManager;
373
374 private slots:
375
376 void processSubTasksForCompletion();
377
378 void processSubTasksForTermination();
379
380};
381
382
384
385
391class CORE_EXPORT QgsTaskManager : public QObject
392{
393 Q_OBJECT
394
395 public:
396
401 QgsTaskManager( QObject *parent SIP_TRANSFERTHIS = nullptr );
402
403 ~QgsTaskManager() override;
404
409 {
410
415 explicit TaskDefinition( QgsTask *task, const QgsTaskList &dependentTasks = QgsTaskList() )
416 : task( task )
417 , dependentTasks( dependentTasks )
418 {}
419
421 QgsTask *task = nullptr;
422
429
430 };
431
437 QThreadPool *threadPool();
438
447 long addTask( QgsTask *task SIP_TRANSFER, int priority = 0 );
448
457 long addTask( const TaskDefinition &task SIP_TRANSFER, int priority = 0 );
458
464 QgsTask *task( long id ) const;
465
469 QList<QgsTask *> tasks() const;
470
472 int count() const;
473
479 long taskId( QgsTask *task ) const;
480
486 void cancelAll();
487
489 bool dependenciesSatisfied( long taskId ) const;
490
495 QSet< long > dependencies( long taskId ) const SIP_SKIP;
496
504 QList< QgsMapLayer * > dependentLayers( long taskId ) const;
505
510 QList< QgsTask * > tasksDependentOnLayer( QgsMapLayer *layer ) const;
511
516 QList< QgsTask * > activeTasks() const;
517
526 int countActiveTasks( bool includeHidden = true ) const;
527
528 public slots:
529
534 void triggerTask( QgsTask *task );
535
536 signals:
537
543 void progressChanged( long taskId, double progress );
544
550 void finalTaskProgressChanged( double progress );
551
557 void statusChanged( long taskId, int status );
558
563 void taskAdded( long taskId );
564
569 void taskAboutToBeDeleted( long taskId );
570
576
581 void countActiveTasksChanged( int count );
582
589 void taskTriggered( QgsTask *task );
590
591 private slots:
592
593 void taskProgressChanged( double progress );
594 void taskStatusChanged( int status );
595 void layersWillBeRemoved( const QList<QgsMapLayer *> &layers );
596
597 private:
598
599 struct TaskInfo
600 {
601 TaskInfo( QgsTask *task = nullptr, int priority = 0 );
602 void createRunnable();
603 QgsTask *task = nullptr;
604 QAtomicInt added;
605 int priority;
606 QgsTaskRunnableWrapper *runnable = nullptr;
607 };
608
609 QThreadPool *mThreadPool = nullptr;
610
611 bool mInitialized = false;
612
613 mutable QRecursiveMutex *mTaskMutex;
614
615 QMap< long, TaskInfo > mTasks;
616 QMap< QgsTask *, long> mMapTaskPtrToId;
617 QMap< long, QgsTaskList > mTaskDependencies;
618 QMap< long, QgsWeakMapLayerPointerList > mLayerDependencies;
619
621 long mNextTaskId = 1;
622
624 QSet< QgsTask * > mActiveTasks;
626 QSet< QgsTask * > mParentTasks;
628 QSet< QgsTask * > mSubTasks;
629
630 QSet< QgsTask * > mPendingDeletion;
631
632 long addTaskPrivate( QgsTask *task,
633 QgsTaskList dependencies,
634 bool isSubTask,
635 int priority );
636
637 bool cleanupAndDeleteTask( QgsTask *task );
638
643 void processQueue();
644
650 void cancelDependentTasks( long taskId );
651
652 bool resolveDependencies( long taskId, QSet< long > &results ) const;
653
655 bool hasCircularDependencies( long taskId ) const;
656
657 friend class TestQgsTaskManager;
658};
659
668class CORE_EXPORT QgsTaskWithSerialSubTasks : public QgsTask
669{
670 Q_OBJECT
671
672 public:
674 QgsTaskWithSerialSubTasks( const QString &desc = QString() ) : QgsTask( desc ) {}
675
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: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.
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.