Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_signal_compressor.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2013 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
31
32#include <QTimer>
33#include "kis_assert.h"
34#include "kis_debug.h"
35
36
38 : QObject(0)
39 , m_timer(new QTimer(this))
40{
41 m_timer->setSingleShot(false);
42 connect(m_timer, SIGNAL(timeout()), SLOT(slotTimerExpired()));
43}
44
45KisSignalCompressor::KisSignalCompressor(int delay, Mode mode, QObject *parent)
46 : KisSignalCompressor(delay, mode, PRECISE_INTERVAL, parent)
47{
48}
49
50KisSignalCompressor::KisSignalCompressor(int delay, Mode mode, SlowHandlerMode slowHandlerMode, QObject *parent)
51 : QObject(parent),
52 m_timer(new QTimer(this)),
53 m_mode(mode),
54 m_slowHandlerMode(slowHandlerMode),
55 m_timeout(delay)
56{
57 m_timer->setSingleShot(false);
58 m_timer->setInterval(delay);
59 connect(m_timer, SIGNAL(timeout()), SLOT(slotTimerExpired()));
60}
61
63{
64 const bool wasActive = m_timer->isActive();
65
66 if (wasActive) {
67 m_timer->stop();
68 }
69
70 m_timer->setInterval(delay);
71
72 if (wasActive) {
73 m_timer->start();
74 }
75}
76
83
84void KisSignalCompressor::setDelay(std::function<bool ()> idleCallback, int idleDelay, int timeout)
85{
87 m_idleCallback = idleCallback;
88 setDelayImpl(idleDelay);
89}
90
92{
94
95 const bool isFirstStart = !m_timer->isActive();
96
99
100
101 switch (m_mode) {
102 case POSTPONE:
103 if (isFirstStart) {
104 m_timer->start();
105 }
106 m_lastEmittedTimer.restart();
107 m_signalsPending = true;
108 break;
110 case FIRST_ACTIVE:
111 if (isFirstStart) {
112 m_timer->start();
114 m_lastEmittedTimer.restart();
115 }
116 m_signalsPending = false;
117 if (!tryEmitSignalSafely()) {
118 m_signalsPending = true;
119 }
121 m_lastEmittedTimer.restart();
122 }
123 } else {
124 if (m_mode == FIRST_ACTIVE) {
125 m_signalsPending = true;
126 tryEmitOnTick(false);
127 } else {
128 m_lastEmittedTimer.restart();
129 m_signalsPending = true;
130 }
131 }
132 break;
133 case FIRST_INACTIVE:
134 if (isFirstStart) {
135 m_timer->start();
136 m_lastEmittedTimer.restart();
137 m_signalsPending = true;
138 } else {
139 m_signalsPending = true;
140 tryEmitOnTick(false);
141 }
142 case UNDEFINED:
143 ; // Should never happen, but do nothing
144 };
145
147
148 KIS_SAFE_ASSERT_RECOVER(m_timer->isActive()) {
149 m_timer->start();
150 }
151}
152
154{
155 bool wasEmitted = false;
156
157 // we have different requirements for hi-frequency events (the mean
158 // of the events rate must be min(compressorRate, eventsRate)
159 const int realInterval = m_timeout;
160 const int minInterval = realInterval < 100 ? 0.5 * realInterval : realInterval;
161
162 // Enable for debugging:
163 // ENTER_FUNCTION() << ppVar(isFromTimer) << ppVar(m_signalsPending) << m_lastEmittedTimer.elapsed() << ppVar((m_idleCallback && m_idleCallback()));
164
165 if (m_signalsPending &&
166 (m_lastEmittedTimer.elapsed() >= minInterval ||
168
170
172 m_lastEmittedTimer.start();
173 }
174
175 m_signalsPending = false;
176 if (!tryEmitSignalSafely()) {
177 m_signalsPending = true;
178 }
179
181 m_lastEmittedTimer.start();
182 }
183
184 wasEmitted = true;
185 } else if (!isFromTimer) {
186 m_signalsPending = true;
187 }
188
189 return wasEmitted;
190}
191
193{
194 bool wasEmitted = false;
195
196 m_isEmitting++;
197
198 if (m_isEmitting == 1) {
199 Q_EMIT timeout();
200 wasEmitted = true;
201 }
202
203 m_isEmitting--;
204
205 return wasEmitted;
206}
207
209{
212 if (!tryEmitOnTick(true)) {
213 const int calmDownInterval = 5 * m_timeout;
214
215 if (!m_lastEmittedTimer.isValid() ||
216 m_lastEmittedTimer.elapsed() > calmDownInterval) {
217
218 m_timer->stop();
219 }
220 }
221}
222
224{
225 m_timer->stop();
226 m_signalsPending = false;
227 m_lastEmittedTimer.invalidate();
228}
229
231{
232 return m_signalsPending && m_timer->isActive();
233}
234
239
241{
242 return m_timeout;
243}
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
std::function< bool()> m_idleCallback
void setDelay(std::function< bool()> idleCallback, int idleDelay, int timeout)
bool tryEmitOnTick(bool isFromTimer)
SlowHandlerMode m_slowHandlerMode
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
#define KIS_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:97
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130