110 timer->timerCallback();
122 void callTimersSynchronously()
135 void addTimer (
Timer* t)
141 jassert (std::none_of (timers.begin(), timers.end(),
142 [t] (TimerCountdown i) { return i.timer == t; }));
144 auto pos = timers.size();
146 timers.push_back ({ t, t->timerPeriodMs });
147 t->positionInQueue = pos;
148 shuffleTimerForwardInQueue (pos);
152 void removeTimer (
Timer* t)
156 auto pos = t->positionInQueue;
157 auto lastIndex = timers.size() - 1;
159 jassert (pos <= lastIndex);
160 jassert (timers[pos].timer == t);
162 for (
auto i = pos; i < lastIndex; ++i)
164 timers[i] = timers[i + 1];
165 timers[i].timer->positionInQueue = i;
171 void resetTimerCounter (
Timer* t)
noexcept
175 auto pos = t->positionInQueue;
177 jassert (pos < timers.size());
178 jassert (timers[pos].timer == t);
180 auto lastCountdown = timers[pos].countdownMs;
181 auto newCountdown = t->timerPeriodMs;
183 if (newCountdown != lastCountdown)
185 timers[pos].countdownMs = newCountdown;
187 if (newCountdown > lastCountdown)
188 shuffleTimerBackInQueue (pos);
190 shuffleTimerForwardInQueue (pos);
199 struct TimerCountdown
205 std::vector<TimerCountdown> timers;
207 WaitableEvent callbackArrived;
209 struct CallTimersMessage final :
public MessageManager::MessageBase
211 CallTimersMessage() =
default;
213 void messageCallback()
override
216 (*instance)->callTimers();
221 void shuffleTimerBackInQueue (
size_t pos)
223 auto numTimers = timers.size();
225 if (pos < numTimers - 1)
227 auto t = timers[pos];
233 if (next == numTimers || timers[next].countdownMs >= t.countdownMs)
236 timers[pos] = timers[next];
237 timers[pos].timer->positionInQueue = pos;
243 t.timer->positionInQueue = pos;
247 void shuffleTimerForwardInQueue (
size_t pos)
251 auto t = timers[pos];
255 auto& prev = timers[(size_t) pos - 1];
257 if (prev.countdownMs <= t.countdownMs)
261 timers[pos].timer->positionInQueue = pos;
267 t.timer->positionInQueue = pos;
271 int getTimeUntilFirstTimer (
int numMillisecsElapsed)
278 for (
auto& t : timers)
279 t.countdownMs -= numMillisecsElapsed;
281 return timers.front().countdownMs;
284 void handleAsyncUpdate()
override
289 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TimerThread)
313 JUCE_ASSERT_MESSAGE_MANAGER_EXISTS
315 bool wasStopped = (timerPeriodMs == 0);
316 timerPeriodMs = jmax (1, interval);
319 timerThread->addTimer (
this);
321 timerThread->resetTimerCounter (
this);
326 if (timerFrequencyHz > 0)
334 if (timerPeriodMs > 0)
336 timerThread->removeTimer (
this);