Krita Source Code Documentation
Loading...
Searching...
No Matches
KisIdleTasksManager.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2023 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
7
8#include <QQueue>
9#include <kis_idle_watcher.h>
10#include <kis_image.h>
11#include <KisMpl.h>
12#include <boost/none.hpp>
13
14
15namespace {
16struct TaskStruct {
17 int id = 0;
19};
20}
21
35
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}
42
44
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}
56
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}
73
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}
88
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}
105
111
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}
120
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}
147
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}
160
std::function< KisIdleTaskStrokeStrategy *(KisImageSP image)> KisIdleTaskStrokeStrategyFactory
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
QWeakPointer< boost::none_t > idleTaskCookie()
int addIdleTask(KisIdleTaskStrokeStrategyFactory factory)
void setImage(KisImageSP image)
QScopedPointer< Private > m_d
TaskGuard addIdleTaskWithGuard(KisIdleTaskStrokeStrategyFactory factory)
Registers the factory for the idle task.
KisStrokeId startStroke(KisStrokeStrategy *strokeStrategy) override
void endStroke(KisStrokeId id) override
#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
QWeakPointer< boost::none_t > currentTaskCookie