Krita Source Code Documentation
Loading...
Searching...
No Matches
KisIdleTasksManager Class Reference

#include <KisIdleTasksManager.h>

+ Inheritance diagram for KisIdleTasksManager:

Classes

struct  Private
 
struct  TaskGuard
 

Public Member Functions

TaskGuard addIdleTaskWithGuard (KisIdleTaskStrokeStrategyFactory factory)
 Registers the factory for the idle task.
 
 KisIdleTasksManager ()
 
void setImage (KisImageSP image)
 
 ~KisIdleTasksManager ()
 

Private Slots

void slotImageIsIdle ()
 
void slotImageIsModified ()
 
void slotTaskIsCompleted ()
 

Private Member Functions

int addIdleTask (KisIdleTaskStrokeStrategyFactory factory)
 
void removeIdleTask (int id)
 
void triggerIdleTask (int id)
 

Private Attributes

QScopedPointer< Privatem_d
 

Detailed Description

A special per-main-window manager that handles jobs that should be run in the background while the user is idle. The manager automatically restarts all the jobs when the image is modified. E.g. updates the overview image or histogram.

The manager is owned by KisViewManager, which automatically connects it to the currently active image. When the image becomes idle, the manager starts its tasks one-by-one.

If you want to add a new task to the manager, just provide a factory to addIdleTaskWithGuard() method. This factory should create and return a stroke strategy for the idle task to be run.

The factory will be called by the task manager every time when it thinks that the idle task should be started.

addIdleTaskWithGuard() returns a TaskGuard handle, which represents the registered task. It is a movable object that will automatically de-register the idle task on destruction.

If your idle-task-factory is a lambda object, make sure that the lifetime of the objects you capture into the lambda's closure is longer than the lifetime of the corresponding TaskGuard handle. In other words, if you capture this into your lambda, make sure that the corresponding TaskGuard also belongs to this or destroyed manually in the destructor.

Definition at line 46 of file KisIdleTasksManager.h.

Constructor & Destructor Documentation

◆ KisIdleTasksManager()

KisIdleTasksManager::KisIdleTasksManager ( )

Definition at line 36 of file KisIdleTasksManager.cpp.

37 : m_d(new Private())
38{
39 connect(&m_d->idleWatcher, SIGNAL(startedIdleMode()), SLOT(slotImageIsIdle()));
40 connect(&m_d->idleWatcher, SIGNAL(imageModified()), SLOT(slotImageIsModified()));
41}
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
QScopedPointer< Private > m_d

References connect(), m_d, slotImageIsIdle(), and slotImageIsModified().

◆ ~KisIdleTasksManager()

KisIdleTasksManager::~KisIdleTasksManager ( )
default

Member Function Documentation

◆ addIdleTask()

int KisIdleTasksManager::addIdleTask ( KisIdleTaskStrokeStrategyFactory factory)
private

TODO: don't restart the whole queue on the the task change, just restart the currently added task

Definition at line 57 of file KisIdleTasksManager.cpp.

58{
64 const int newId =
65 !m_d->tasks.isEmpty() ?
66 m_d->tasks.last().id + 1 : 0;
67
68 m_d->tasks.append({newId, factory});
69 triggerIdleTask(newId);
70
71 return newId;
72}

References m_d, and triggerIdleTask().

◆ addIdleTaskWithGuard()

KisIdleTasksManager::TaskGuard KisIdleTasksManager::addIdleTaskWithGuard ( KisIdleTaskStrokeStrategyFactory factory)

Registers the factory for the idle task.

The manager will use this factory to start the task after every image modification.

Parameters
factoryis a functor creating a KisIdleTaskStrokeStrategy that will actually execute the task
Returns
a TaskGuard object that can be used for task manipulations

Definition at line 107 of file KisIdleTasksManager.cpp.

108{
109 return {addIdleTask(factory), this};
110}
int addIdleTask(KisIdleTaskStrokeStrategyFactory factory)

References addIdleTask().

◆ removeIdleTask()

void KisIdleTasksManager::removeIdleTask ( int id)
private

Definition at line 74 of file KisIdleTasksManager.cpp.

75{
76 {
77 auto it = std::remove_if(m_d->tasks.begin(), m_d->tasks.end(),
78 kismpl::mem_equal_to(&TaskStruct::id, id));
79 KIS_SAFE_ASSERT_RECOVER_NOOP(it != m_d->tasks.end());
80 m_d->tasks.erase(it, m_d->tasks.end());
81 }
82
83 {
84 auto it = std::remove(m_d->queue.begin(), m_d->queue.end(), id);
85 m_d->queue.erase(it, m_d->queue.end());
86 }
87}
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
auto mem_equal_to(MemTypeNoRef Class::*ptr, MemType &&value)
mem_equal_to is an unary functor that compares a member of the object to a given value
Definition KisMpl.h:233

References KIS_SAFE_ASSERT_RECOVER_NOOP, m_d, and kismpl::mem_equal_to().

◆ setImage()

void KisIdleTasksManager::setImage ( KisImageSP image)

Definition at line 45 of file KisIdleTasksManager.cpp.

46{
47 m_d->idleWatcher.setTrackedImage(image);
48 m_d->image = image;
49 m_d->queue.clear();
50
51 if (image) {
53 m_d->idleWatcher.triggerCountdownNoDelay();
54 }
55}

References m_d, and slotImageIsModified().

◆ slotImageIsIdle

void KisIdleTasksManager::slotImageIsIdle ( )
privateslot

Definition at line 121 of file KisIdleTasksManager.cpp.

122{
123 KisImageSP image = m_d->image;
124 if (!image) return;
125
126 if (m_d->currentTaskCookie) {
127 m_d->idleWatcher.restartCountdown();
128 return;
129 }
130
131 if (m_d->queue.isEmpty()) return;
132
133 const int newTaskId = m_d->queue.dequeue();
134
135 auto it = std::find_if(m_d->tasks.begin(), m_d->tasks.end(),
136 kismpl::mem_equal_to(&TaskStruct::id, newTaskId));
137 KIS_SAFE_ASSERT_RECOVER_NOOP(it != m_d->tasks.end());
138
139 KisIdleTaskStrokeStrategy *strategy = it->factory(image);
140
141 connect(strategy, SIGNAL(sigIdleTaskFinished()), SLOT(slotTaskIsCompleted()));
142 m_d->currentTaskCookie = strategy->idleTaskCookie();
143
144 KisStrokeId strokeId = image->startStroke(strategy);
145 image->endStroke(strokeId);
146}
QWeakPointer< boost::none_t > idleTaskCookie()
KisStrokeId startStroke(KisStrokeStrategy *strokeStrategy) override
void endStroke(KisStrokeId id) override

References connect(), KisImage::endStroke(), KisIdleTaskStrokeStrategy::idleTaskCookie(), KIS_SAFE_ASSERT_RECOVER_NOOP, m_d, kismpl::mem_equal_to(), slotTaskIsCompleted(), and KisImage::startStroke().

◆ slotImageIsModified

void KisIdleTasksManager::slotImageIsModified ( )
privateslot

Definition at line 112 of file KisIdleTasksManager.cpp.

113{
114 m_d->queue.clear();
115 m_d->queue.reserve(m_d->tasks.size());
116 std::transform(m_d->tasks.begin(), m_d->tasks.end(),
117 std::back_inserter(m_d->queue),
118 std::mem_fn(&TaskStruct::id));
119}

References m_d.

◆ slotTaskIsCompleted

void KisIdleTasksManager::slotTaskIsCompleted ( )
privateslot

Definition at line 148 of file KisIdleTasksManager.cpp.

149{
150 if (m_d->queue.isEmpty()) {
151 // all tasks are completed!
152 } else {
153 if (m_d->idleWatcher.isIdle()) {
155 } else if (!m_d->idleWatcher.isCounting()) {
156 m_d->idleWatcher.restartCountdown();
157 }
158 }
159}

References m_d, and slotImageIsIdle().

◆ triggerIdleTask()

void KisIdleTasksManager::triggerIdleTask ( int id)
private

Definition at line 89 of file KisIdleTasksManager.cpp.

90{
91 {
92 // just verify that this tasks actually exists
93 auto it = std::find_if(m_d->tasks.begin(), m_d->tasks.end(),
94 kismpl::mem_equal_to(&TaskStruct::id, id));
95 KIS_SAFE_ASSERT_RECOVER_NOOP(it != m_d->tasks.end());
96 }
97
98 auto it = std::find(m_d->queue.begin(), m_d->queue.end(), id);
99 if (it == m_d->queue.end()) {
100 m_d->queue.enqueue(id);
101 }
102
103 m_d->idleWatcher.triggerCountdownNoDelay();
104}

References KIS_SAFE_ASSERT_RECOVER_NOOP, m_d, and kismpl::mem_equal_to().

Member Data Documentation

◆ m_d

QScopedPointer<Private> KisIdleTasksManager::m_d
private

Definition at line 138 of file KisIdleTasksManager.h.


The documentation for this class was generated from the following files: