File indexing completed on 2024-05-19 04:29:13
0001 /* 0002 * SPDX-FileCopyrightText: 2023 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #ifndef KISIDLETASKSMANAGER_H 0007 #define KISIDLETASKSMANAGER_H 0008 0009 #include "kritaui_export.h" 0010 #include <KisIdleTaskStrokeStrategy.h> 0011 #include <QPointer> 0012 0013 0014 /** 0015 * A special per-main-window manager that handles jobs that 0016 * should be run in the background while the user is idle. The 0017 * manager automatically restarts all the jobs when the image is 0018 * modified. E.g. updates the overview image or histogram. 0019 * 0020 * The manager is owned by KisViewManager, which automatically 0021 * connects it to the currently active image. When the image 0022 * becomes idle, the manager starts its tasks one-by-one. 0023 * 0024 * If you want to add a new task to the manager, just provide 0025 * a factory to addIdleTaskWithGuard() method. This factory 0026 * should create and return a stroke strategy for the idle 0027 * task to be run. 0028 * 0029 * The factory will be called by the task manager every time 0030 * when it thinks that the idle task should be started. 0031 * 0032 * 0033 * addIdleTaskWithGuard() returns a TaskGuard handle, which 0034 * represents the registered task. It is a movable object 0035 * that will automatically de-register the idle task on 0036 * destruction. 0037 * 0038 * If your idle-task-factory is a lambda object, make sure 0039 * that the lifetime of the objects you capture into the 0040 * lambda's closure is longer than the lifetime of the 0041 * corresponding TaskGuard handle. In other words, if you 0042 * capture `this` into your lambda, make sure that 0043 * the corresponding `TaskGuard` also belongs to `this` or 0044 * destroyed manually in the destructor. 0045 */ 0046 class KRITAUI_EXPORT KisIdleTasksManager : public QObject 0047 { 0048 Q_OBJECT 0049 0050 public: 0051 /** 0052 * A simple **movable** handle that represents a task 0053 * registered in the manager. When the handle is destroyed, 0054 * the task it automatically de-registered. 0055 */ 0056 struct TaskGuard { 0057 TaskGuard() {} 0058 TaskGuard(int _taskId, 0059 QPointer<KisIdleTasksManager> _manager) 0060 : taskId(_taskId) 0061 , manager(_manager) 0062 {} 0063 0064 TaskGuard(const TaskGuard &rhs) = delete; 0065 TaskGuard& operator=(const TaskGuard &rhs) = delete; 0066 0067 TaskGuard(TaskGuard &&rhs) { 0068 std::swap(taskId, rhs.taskId); 0069 std::swap(manager, rhs.manager); 0070 }; 0071 0072 TaskGuard& operator=(TaskGuard &&rhs) { 0073 std::swap(taskId, rhs.taskId); 0074 std::swap(manager, rhs.manager); 0075 return *this; 0076 } 0077 0078 ~TaskGuard() { 0079 if (manager) { 0080 manager->removeIdleTask(taskId); 0081 } 0082 } 0083 0084 /** 0085 * @return true if the task is valid and registered at the manager 0086 */ 0087 bool isValid() const { 0088 return manager; 0089 } 0090 0091 /** 0092 * Explicitly request restart of the task, e.g. explicitly 0093 * restart recalculation of the overview image when the display 0094 * profile is changed 0095 */ 0096 void trigger() { 0097 KIS_SAFE_ASSERT_RECOVER_RETURN(manager); 0098 manager->triggerIdleTask(taskId); 0099 } 0100 0101 int taskId = -1; 0102 QPointer<KisIdleTasksManager> manager; 0103 }; 0104 0105 public: 0106 KisIdleTasksManager(); 0107 ~KisIdleTasksManager(); 0108 0109 void setImage(KisImageSP image); 0110 0111 /** 0112 * @brief Registers the factory for the idle task 0113 * 0114 * The manager will use this factory to start the task after 0115 * every image modification. 0116 * 0117 * @param factory is a functor creating a KisIdleTaskStrokeStrategy 0118 * that will actually execute the task 0119 * @return a TaskGuard object that can be used for task manipulations 0120 */ 0121 [[nodiscard]] 0122 TaskGuard addIdleTaskWithGuard(KisIdleTaskStrokeStrategyFactory factory); 0123 0124 private: 0125 int addIdleTask(KisIdleTaskStrokeStrategyFactory factory); 0126 void removeIdleTask(int id); 0127 void triggerIdleTask(int id); 0128 0129 private Q_SLOTS: 0130 void slotImageIsModified(); 0131 void slotImageIsIdle(); 0132 void slotTaskIsCompleted(); 0133 0134 private: 0135 0136 private: 0137 struct Private; 0138 QScopedPointer<Private> m_d; 0139 }; 0140 0141 #endif // KISIDLETASKSMANAGER_H