51 auto elapsed = (
int) (now >= lastTime ? (now - lastTime)
59 if (callbackArrived.
wait (0))
67 if (! callbackArrived.
wait (300))
91 while (! timers.
empty())
93 auto& first = timers.
front();
95 if (first.countdownMs > 0)
98 auto* timer = first.timer;
99 first.countdownMs = timer->timerPeriodMs;
100 shuffleTimerBackInQueue (0);
107 timer->timerCallback();
119 void callTimersSynchronously()
124 void addTimer (
Timer* t)
134 [t] (TimerCountdown i) { return i.timer == t; }));
136 auto pos = timers.
size();
138 timers.
push_back ({ t, t->timerPeriodMs });
139 t->positionInQueue = pos;
140 shuffleTimerForwardInQueue (pos);
144 void removeTimer (
Timer* t)
148 auto pos = t->positionInQueue;
149 auto lastIndex = timers.
size() - 1;
152 jassert (timers[pos].timer == t);
154 for (
auto i = pos; i < lastIndex; ++i)
156 timers[i] = timers[i + 1];
157 timers[i].timer->positionInQueue = i;
163 void resetTimerCounter (
Timer* t)
noexcept
167 auto pos = t->positionInQueue;
170 jassert (timers[pos].timer == t);
180 shuffleTimerBackInQueue (pos);
182 shuffleTimerForwardInQueue (pos);
191 struct TimerCountdown
199 WaitableEvent callbackArrived;
201 struct CallTimersMessage
final :
public MessageManager::MessageBase
203 CallTimersMessage() =
default;
205 void messageCallback()
override
208 (*instance)->callTimers();
213 void shuffleTimerBackInQueue (
size_t pos)
219 auto t = timers[pos];
225 if (next ==
numTimers || timers[next].countdownMs >= t.countdownMs)
228 timers[pos] = timers[
next];
229 timers[pos].timer->positionInQueue = pos;
235 t.timer->positionInQueue = pos;
239 void shuffleTimerForwardInQueue (
size_t pos)
243 auto t = timers[pos];
249 if (
prev.countdownMs <= t.countdownMs)
253 timers[pos].timer->positionInQueue = pos;
259 t.timer->positionInQueue = pos;
270 for (
auto& t : timers)
273 return timers.
front().countdownMs;
303 timerPeriodMs =
jmax (1, interval);
306 timerThread->addTimer (
this);
308 timerThread->resetTimerCounter (
this);
321 if (timerPeriodMs > 0)
323 timerThread->removeTimer (
this);
331 (*instance)->callTimersSynchronously();
338 : function (std::move (f))
350 NullCheckedInvocation::invoke (function);
GenericScopedLock< CriticalSection > ScopedLockType
Provides the type of scoped lock to use with a CriticalSection.
GenericScopedUnlock< CriticalSection > ScopedUnlockType
Provides the type of scoped unlocker to use with a CriticalSection.
Classes derived from this will be automatically deleted when the application exits.
static MessageManager * getInstanceWithoutCreating() noexcept
Returns the global instance of the MessageManager, or nullptr if it doesn't exist.
A smart-pointer class which points to a reference-counted object.
A smart-pointer that automatically creates and manages the lifetime of a shared static instance of a ...
static std::optional< SharedResourcePointer > getSharedObjectWithoutCreating()
Returns the SharedResourcePointer if one already exists, or a null optional otherwise.
bool startThread()
Attempts to start a new thread with default ('Priority::normal') priority.
bool threadShouldExit() const
Checks whether the thread has been told to stop running.
bool stopThread(int timeOutMilliseconds)
Attempts to stop the thread running.
void notify() const
Wakes up the thread.
void signalThreadShouldExit()
Sets a flag to tell the thread it should stop.
@ high
Makes use of performance cores and higher clocks.
bool isThreadRunning() const
Returns true if the thread is currently active.
static uint32 getMillisecondCounter() noexcept
Returns the number of millisecs since a fixed event (usually system startup).
void run() override
Must be implemented to perform the thread's actual code.
Makes repeated callbacks to a virtual method at a specified time interval.
virtual ~Timer()
Destructor.
void stopTimer() noexcept
Stops the timer.
Timer() noexcept
Creates a Timer.
void startTimerHz(int timerFrequencyHz) noexcept
Starts the timer with an interval specified in Hertz.
bool isTimerRunning() const noexcept
Returns true if the timer is currently running.
static void JUCE_CALLTYPE callPendingTimersSynchronously()
For internal use only: invokes any timers that need callbacks.
static void JUCE_CALLTYPE callAfterDelay(int milliseconds, std::function< void()> functionToCall)
Invokes a lambda after a given number of milliseconds.
void startTimer(int intervalInMilliseconds) noexcept
Starts the timer and sets the length of interval required.
void signal() const
Wakes up any threads that are currently waiting on this object.
bool wait(double timeOutMilliseconds=-1.0) const
Suspends the calling thread until the event has been signalled.
#define JUCE_TRY
The JUCE_TRY/JUCE_CATCH_EXCEPTION wrappers can be used to pass any uncaught exceptions to the JUCEApp...
#define JUCE_CATCH_EXCEPTION
The JUCE_TRY/JUCE_CATCH_EXCEPTION wrappers can be used to pass any uncaught exceptions to the JUCEApp...
#define JUCE_ASSERT_MESSAGE_MANAGER_EXISTS
This macro is used to catch unsafe use of functions which expect to not be called outside the lifetim...
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Constrains a value to keep it within a given range.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
void timerCallback() final
The user-defined callback routine that actually gets called periodically.