Changeset View
Changeset View
Standalone View
Standalone View
libs/global/kis_relaxed_timer.cpp
Context not available. | |||||
28 | { | 28 | { | ||
---|---|---|---|---|---|
29 | } | 29 | } | ||
30 | 30 | | |||
31 | void KisRelaxedTimer::setInterval(int interval) | 31 | void KisRelaxedTimer::setInterval(int interval, int maxOffEarly, int maxOffLate) | ||
32 | { | 32 | { | ||
33 | Q_ASSERT(!isActive()); | 33 | Q_ASSERT(!m_timer.isActive()); | ||
34 | m_interval = interval; | 34 | m_interval = interval; | ||
35 | m_maxOffEarly = maxOffEarly; | ||||
36 | m_maxOffLate = maxOffLate; | ||||
35 | } | 37 | } | ||
36 | 38 | | |||
37 | void KisRelaxedTimer::setSingleShot(bool singleShot) | 39 | void KisRelaxedTimer::setSingleShot(bool singleShot) | ||
Context not available. | |||||
63 | // us a timeout event on the next possible tick which will be exactly | 65 | // us a timeout event on the next possible tick which will be exactly | ||
64 | // \p m_interval ms in the future. | 66 | // \p m_interval ms in the future. | ||
65 | 67 | | |||
66 | m_emitOnTimeTick = m_nextTimerTickSeqNo; | 68 | resync(); | ||
67 | m_timer.start(m_interval, this); | | |||
68 | } else if (m_isEmitting) { | 69 | } else if (m_isEmitting) { | ||
69 | // an internal timer is running and we are actually called from a | 70 | // an internal timer is running and we are actually called from a | ||
70 | // timeout event. so we know the next tick will happen in exactly | 71 | // timeout event. so we know the next tick will happen in exactly | ||
Context not available. | |||||
72 | 73 | | |||
73 | m_emitOnTimeTick = m_nextTimerTickSeqNo; | 74 | m_emitOnTimeTick = m_nextTimerTickSeqNo; | ||
74 | } else { | 75 | } else { | ||
75 | // an internal timer is already running, but we do not know when | 76 | // an internal timer is already running. try to use it if we are | ||
76 | // the next tick will happen. we need to skip next tick as it | 77 | // in the tolerance limits given to us. | ||
77 | // will be sooner than m_delay. the one after that will be good as | 78 | const int elapsed = m_tick.elapsed(); | ||
78 | // it will be m_interval * (1 + err) in the future. | 79 | | ||
79 | 80 | // how much too early are we if we take m_nextTimerTickSeqNo? | |||
80 | m_emitOnTimeTick = m_nextTimerTickSeqNo + 1; | 81 | if (elapsed < m_maxOffEarly) { | ||
82 | m_emitOnTimeTick = m_nextTimerTickSeqNo; | ||||
83 | } else { | ||||
84 | // how much off too late we if we take m_nextTimerTickSeqNo + 1? | ||||
85 | if (qMax(0, m_interval - elapsed) < m_maxOffLate) { | ||||
86 | m_emitOnTimeTick = m_nextTimerTickSeqNo + 1; | ||||
87 | } else { | ||||
88 | // we are too much off, need to resync. | ||||
89 | resync(); | ||||
90 | } | ||||
91 | } | ||||
81 | } | 92 | } | ||
82 | } | 93 | } | ||
83 | 94 | | |||
95 | void KisRelaxedTimer::resync() | ||||
96 | { | ||||
97 | m_emitOnTimeTick = m_nextTimerTickSeqNo; | ||||
98 | m_timer.start(m_interval, this); | ||||
99 | m_tick.start(); | ||||
100 | } | ||||
101 | | ||||
84 | void KisRelaxedTimer::timerEvent(QTimerEvent *event) | 102 | void KisRelaxedTimer::timerEvent(QTimerEvent *event) | ||
85 | { | 103 | { | ||
86 | Q_UNUSED(event); | 104 | Q_UNUSED(event); | ||
Context not available. | |||||
101 | } else if (timerTickSeqNo - m_emitOnTimeTick > ticksStopThreshold) { | 119 | } else if (timerTickSeqNo - m_emitOnTimeTick > ticksStopThreshold) { | ||
102 | m_timer.stop(); | 120 | m_timer.stop(); | ||
103 | } | 121 | } | ||
122 | | ||||
123 | m_tick.start(); | ||||
104 | } | 124 | } | ||
Context not available. |