mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-16 00:34:19 +00:00
Added Animated App template and examples
This commit is contained in:
parent
fefcf7aca6
commit
ff6520a89a
1141 changed files with 438491 additions and 94 deletions
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found at: www.gnu.org/licenses
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
struct MultiTimerCallback : public Timer
|
||||
{
|
||||
MultiTimerCallback (const int tid, MultiTimer& mt) noexcept
|
||||
: owner (mt), timerID (tid)
|
||||
{
|
||||
}
|
||||
|
||||
void timerCallback() override
|
||||
{
|
||||
owner.timerCallback (timerID);
|
||||
}
|
||||
|
||||
MultiTimer& owner;
|
||||
const int timerID;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MultiTimerCallback)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
MultiTimer::MultiTimer() noexcept {}
|
||||
MultiTimer::MultiTimer (const MultiTimer&) noexcept {}
|
||||
|
||||
MultiTimer::~MultiTimer()
|
||||
{
|
||||
const SpinLock::ScopedLockType sl (timerListLock);
|
||||
timers.clear();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
Timer* MultiTimer::getCallback (int timerID) const noexcept
|
||||
{
|
||||
for (int i = timers.size(); --i >= 0;)
|
||||
{
|
||||
MultiTimerCallback* const t = static_cast<MultiTimerCallback*> (timers.getUnchecked(i));
|
||||
|
||||
if (t->timerID == timerID)
|
||||
return t;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void MultiTimer::startTimer (const int timerID, const int intervalInMilliseconds) noexcept
|
||||
{
|
||||
const SpinLock::ScopedLockType sl (timerListLock);
|
||||
|
||||
Timer* timer = getCallback (timerID);
|
||||
|
||||
if (timer == nullptr)
|
||||
timers.add (timer = new MultiTimerCallback (timerID, *this));
|
||||
|
||||
timer->startTimer (intervalInMilliseconds);
|
||||
}
|
||||
|
||||
void MultiTimer::stopTimer (const int timerID) noexcept
|
||||
{
|
||||
const SpinLock::ScopedLockType sl (timerListLock);
|
||||
|
||||
if (Timer* const t = getCallback (timerID))
|
||||
t->stopTimer();
|
||||
}
|
||||
|
||||
bool MultiTimer::isTimerRunning (const int timerID) const noexcept
|
||||
{
|
||||
const SpinLock::ScopedLockType sl (timerListLock);
|
||||
|
||||
if (Timer* const t = getCallback (timerID))
|
||||
return t->isTimerRunning();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int MultiTimer::getTimerInterval (const int timerID) const noexcept
|
||||
{
|
||||
const SpinLock::ScopedLockType sl (timerListLock);
|
||||
|
||||
if (Timer* const t = getCallback (timerID))
|
||||
return t->getTimerInterval();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found at: www.gnu.org/licenses
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef JUCE_MULTITIMER_H_INCLUDED
|
||||
#define JUCE_MULTITIMER_H_INCLUDED
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A type of timer class that can run multiple timers with different frequencies,
|
||||
all of which share a single callback.
|
||||
|
||||
This class is very similar to the Timer class, but allows you run multiple
|
||||
separate timers, where each one has a unique ID number. The methods in this
|
||||
class are exactly equivalent to those in Timer, but with the addition of
|
||||
this ID number.
|
||||
|
||||
To use it, you need to create a subclass of MultiTimer, implementing the
|
||||
timerCallback() method. Then you can start timers with startTimer(), and
|
||||
each time the callback is triggered, it passes in the ID of the timer that
|
||||
caused it.
|
||||
|
||||
@see Timer
|
||||
*/
|
||||
class JUCE_API MultiTimer
|
||||
{
|
||||
protected:
|
||||
//==============================================================================
|
||||
/** Creates a MultiTimer.
|
||||
|
||||
When created, no timers are running, so use startTimer() to start things off.
|
||||
*/
|
||||
MultiTimer() noexcept;
|
||||
|
||||
/** Creates a copy of another timer.
|
||||
|
||||
Note that this timer will not contain any running timers, even if the one you're
|
||||
copying from was running.
|
||||
*/
|
||||
MultiTimer (const MultiTimer&) noexcept;
|
||||
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Destructor. */
|
||||
virtual ~MultiTimer();
|
||||
|
||||
//==============================================================================
|
||||
/** The user-defined callback routine that actually gets called by each of the
|
||||
timers that are running.
|
||||
|
||||
It's perfectly ok to call startTimer() or stopTimer() from within this
|
||||
callback to change the subsequent intervals.
|
||||
*/
|
||||
virtual void timerCallback (int timerID) = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** Starts a timer and sets the length of interval required.
|
||||
|
||||
If the timer is already started, this will reset it, so the
|
||||
time between calling this method and the next timer callback
|
||||
will not be less than the interval length passed in.
|
||||
|
||||
@param timerID a unique Id number that identifies the timer to
|
||||
start. This is the id that will be passed back
|
||||
to the timerCallback() method when this timer is
|
||||
triggered
|
||||
@param intervalInMilliseconds the interval to use (any values less than 1 will be
|
||||
rounded up to 1)
|
||||
*/
|
||||
void startTimer (int timerID, int intervalInMilliseconds) noexcept;
|
||||
|
||||
/** Stops a timer.
|
||||
|
||||
If a timer has been started with the given ID number, it will be cancelled.
|
||||
No more callbacks will be made for the specified timer after this method returns.
|
||||
|
||||
If this is called from a different thread, any callbacks that may
|
||||
be currently executing may be allowed to finish before the method
|
||||
returns.
|
||||
*/
|
||||
void stopTimer (int timerID) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Checks whether a timer has been started for a specified ID.
|
||||
@returns true if a timer with the given ID is running.
|
||||
*/
|
||||
bool isTimerRunning (int timerID) const noexcept;
|
||||
|
||||
/** Returns the interval for a specified timer ID.
|
||||
@returns the timer's interval in milliseconds if it's running, or 0 if no
|
||||
timer was running for the ID number specified.
|
||||
*/
|
||||
int getTimerInterval (int timerID) const noexcept;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
private:
|
||||
SpinLock timerListLock;
|
||||
OwnedArray<Timer> timers;
|
||||
|
||||
Timer* getCallback (int) const noexcept;
|
||||
MultiTimer& operator= (const MultiTimer&);
|
||||
};
|
||||
|
||||
#endif // JUCE_MULTITIMER_H_INCLUDED
|
||||
|
|
@ -0,0 +1,350 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found at: www.gnu.org/licenses
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
class Timer::TimerThread : private Thread,
|
||||
private DeletedAtShutdown,
|
||||
private AsyncUpdater
|
||||
{
|
||||
public:
|
||||
typedef CriticalSection LockType; // (mysteriously, using a SpinLock here causes problems on some XP machines..)
|
||||
|
||||
TimerThread()
|
||||
: Thread ("Juce Timer"),
|
||||
firstTimer (nullptr),
|
||||
callbackNeeded (0)
|
||||
{
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
|
||||
~TimerThread() noexcept
|
||||
{
|
||||
stopThread (4000);
|
||||
|
||||
jassert (instance == this || instance == nullptr);
|
||||
if (instance == this)
|
||||
instance = nullptr;
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
uint32 lastTime = Time::getMillisecondCounter();
|
||||
MessageManager::MessageBase::Ptr messageToSend (new CallTimersMessage());
|
||||
|
||||
while (! threadShouldExit())
|
||||
{
|
||||
const uint32 now = Time::getMillisecondCounter();
|
||||
|
||||
if (now == lastTime)
|
||||
{
|
||||
wait (1);
|
||||
continue;
|
||||
}
|
||||
|
||||
const int elapsed = (int) (now >= lastTime ? (now - lastTime)
|
||||
: (std::numeric_limits<uint32>::max() - (lastTime - now)));
|
||||
lastTime = now;
|
||||
|
||||
const int timeUntilFirstTimer = getTimeUntilFirstTimer (elapsed);
|
||||
|
||||
if (timeUntilFirstTimer <= 0)
|
||||
{
|
||||
/* If we managed to set the atomic boolean to true then send a message, this is needed
|
||||
as a memory barrier so the message won't be sent before callbackNeeded is set to true,
|
||||
but if it fails it means the message-thread changed the value from under us so at least
|
||||
some processing is happenening and we can just loop around and try again
|
||||
*/
|
||||
if (callbackNeeded.compareAndSetBool (1, 0))
|
||||
{
|
||||
messageToSend->post();
|
||||
|
||||
/* Sometimes our message can get discarded by the OS (e.g. when running as an RTAS
|
||||
when the app has a modal loop), so this is how long to wait before assuming the
|
||||
message has been lost and trying again.
|
||||
*/
|
||||
const uint32 messageDeliveryTimeout = now + 300;
|
||||
|
||||
while (callbackNeeded.get() != 0)
|
||||
{
|
||||
wait (4);
|
||||
|
||||
if (threadShouldExit())
|
||||
return;
|
||||
|
||||
if (Time::getMillisecondCounter() > messageDeliveryTimeout)
|
||||
{
|
||||
messageToSend->post();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't wait for too long because running this loop also helps keep the
|
||||
// Time::getApproximateMillisecondTimer value stay up-to-date
|
||||
wait (jlimit (1, 50, timeUntilFirstTimer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void callTimers()
|
||||
{
|
||||
const LockType::ScopedLockType sl (lock);
|
||||
|
||||
while (firstTimer != nullptr && firstTimer->countdownMs <= 0)
|
||||
{
|
||||
Timer* const t = firstTimer;
|
||||
t->countdownMs = t->periodMs;
|
||||
|
||||
removeTimer (t);
|
||||
addTimer (t);
|
||||
|
||||
const LockType::ScopedUnlockType ul (lock);
|
||||
|
||||
JUCE_TRY
|
||||
{
|
||||
t->timerCallback();
|
||||
}
|
||||
JUCE_CATCH_EXCEPTION
|
||||
}
|
||||
|
||||
/* This is needed as a memory barrier to make sure all processing of current timers is done
|
||||
before the boolean is set. This set should never fail since if it was false in the first place,
|
||||
we wouldn't get a message (so it can't be changed from false to true from under us), and if we
|
||||
get a message then the value is true and the other thread can only set it to true again and
|
||||
we will get another callback to set it to false.
|
||||
*/
|
||||
callbackNeeded.set (0);
|
||||
}
|
||||
|
||||
void callTimersSynchronously()
|
||||
{
|
||||
if (! isThreadRunning())
|
||||
{
|
||||
// (This is relied on by some plugins in cases where the MM has
|
||||
// had to restart and the async callback never started)
|
||||
cancelPendingUpdate();
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
|
||||
callTimers();
|
||||
}
|
||||
|
||||
static inline void add (Timer* const tim) noexcept
|
||||
{
|
||||
if (instance == nullptr)
|
||||
instance = new TimerThread();
|
||||
|
||||
instance->addTimer (tim);
|
||||
}
|
||||
|
||||
static inline void remove (Timer* const tim) noexcept
|
||||
{
|
||||
if (instance != nullptr)
|
||||
instance->removeTimer (tim);
|
||||
}
|
||||
|
||||
static inline void resetCounter (Timer* const tim, const int newCounter) noexcept
|
||||
{
|
||||
if (instance != nullptr)
|
||||
{
|
||||
tim->countdownMs = newCounter;
|
||||
tim->periodMs = newCounter;
|
||||
|
||||
if ((tim->next != nullptr && tim->next->countdownMs < tim->countdownMs)
|
||||
|| (tim->previous != nullptr && tim->previous->countdownMs > tim->countdownMs))
|
||||
{
|
||||
instance->removeTimer (tim);
|
||||
instance->addTimer (tim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static TimerThread* instance;
|
||||
static LockType lock;
|
||||
|
||||
private:
|
||||
Timer* volatile firstTimer;
|
||||
Atomic <int> callbackNeeded;
|
||||
|
||||
struct CallTimersMessage : public MessageManager::MessageBase
|
||||
{
|
||||
CallTimersMessage() {}
|
||||
|
||||
void messageCallback() override
|
||||
{
|
||||
if (instance != nullptr)
|
||||
instance->callTimers();
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
void addTimer (Timer* const t) noexcept
|
||||
{
|
||||
#if JUCE_DEBUG
|
||||
// trying to add a timer that's already here - shouldn't get to this point,
|
||||
// so if you get this assertion, let me know!
|
||||
jassert (! timerExists (t));
|
||||
#endif
|
||||
|
||||
Timer* i = firstTimer;
|
||||
|
||||
if (i == nullptr || i->countdownMs > t->countdownMs)
|
||||
{
|
||||
t->next = firstTimer;
|
||||
firstTimer = t;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (i->next != nullptr && i->next->countdownMs <= t->countdownMs)
|
||||
i = i->next;
|
||||
|
||||
jassert (i != nullptr);
|
||||
|
||||
t->next = i->next;
|
||||
t->previous = i;
|
||||
i->next = t;
|
||||
}
|
||||
|
||||
if (t->next != nullptr)
|
||||
t->next->previous = t;
|
||||
|
||||
jassert ((t->next == nullptr || t->next->countdownMs >= t->countdownMs)
|
||||
&& (t->previous == nullptr || t->previous->countdownMs <= t->countdownMs));
|
||||
|
||||
notify();
|
||||
}
|
||||
|
||||
void removeTimer (Timer* const t) noexcept
|
||||
{
|
||||
#if JUCE_DEBUG
|
||||
// trying to remove a timer that's not here - shouldn't get to this point,
|
||||
// so if you get this assertion, let me know!
|
||||
jassert (timerExists (t));
|
||||
#endif
|
||||
|
||||
if (t->previous != nullptr)
|
||||
{
|
||||
jassert (firstTimer != t);
|
||||
t->previous->next = t->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
jassert (firstTimer == t);
|
||||
firstTimer = t->next;
|
||||
}
|
||||
|
||||
if (t->next != nullptr)
|
||||
t->next->previous = t->previous;
|
||||
|
||||
t->next = nullptr;
|
||||
t->previous = nullptr;
|
||||
}
|
||||
|
||||
int getTimeUntilFirstTimer (const int numMillisecsElapsed) const
|
||||
{
|
||||
const LockType::ScopedLockType sl (lock);
|
||||
|
||||
for (Timer* t = firstTimer; t != nullptr; t = t->next)
|
||||
t->countdownMs -= numMillisecsElapsed;
|
||||
|
||||
return firstTimer != nullptr ? firstTimer->countdownMs : 1000;
|
||||
}
|
||||
|
||||
void handleAsyncUpdate() override
|
||||
{
|
||||
startThread (7);
|
||||
}
|
||||
|
||||
#if JUCE_DEBUG
|
||||
bool timerExists (Timer* const t) const noexcept
|
||||
{
|
||||
for (Timer* tt = firstTimer; tt != nullptr; tt = tt->next)
|
||||
if (tt == t)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TimerThread)
|
||||
};
|
||||
|
||||
Timer::TimerThread* Timer::TimerThread::instance = nullptr;
|
||||
Timer::TimerThread::LockType Timer::TimerThread::lock;
|
||||
|
||||
//==============================================================================
|
||||
Timer::Timer() noexcept
|
||||
: countdownMs (0),
|
||||
periodMs (0),
|
||||
previous (nullptr),
|
||||
next (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Timer::Timer (const Timer&) noexcept
|
||||
: countdownMs (0),
|
||||
periodMs (0),
|
||||
previous (nullptr),
|
||||
next (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Timer::~Timer()
|
||||
{
|
||||
stopTimer();
|
||||
}
|
||||
|
||||
void Timer::startTimer (const int interval) noexcept
|
||||
{
|
||||
const TimerThread::LockType::ScopedLockType sl (TimerThread::lock);
|
||||
|
||||
if (periodMs == 0)
|
||||
{
|
||||
countdownMs = interval;
|
||||
periodMs = jmax (1, interval);
|
||||
TimerThread::add (this);
|
||||
}
|
||||
else
|
||||
{
|
||||
TimerThread::resetCounter (this, interval);
|
||||
}
|
||||
}
|
||||
|
||||
void Timer::stopTimer() noexcept
|
||||
{
|
||||
const TimerThread::LockType::ScopedLockType sl (TimerThread::lock);
|
||||
|
||||
if (periodMs > 0)
|
||||
{
|
||||
TimerThread::remove (this);
|
||||
periodMs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE Timer::callPendingTimersSynchronously()
|
||||
{
|
||||
if (TimerThread::instance != nullptr)
|
||||
TimerThread::instance->callTimersSynchronously();
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
|
||||
Permission is granted to use this software under the terms of either:
|
||||
a) the GPL v2 (or any later version)
|
||||
b) the Affero GPL v3
|
||||
|
||||
Details of these licenses can be found at: www.gnu.org/licenses
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.juce.com for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef JUCE_TIMER_H_INCLUDED
|
||||
#define JUCE_TIMER_H_INCLUDED
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Makes repeated callbacks to a virtual method at a specified time interval.
|
||||
|
||||
A Timer's timerCallback() method will be repeatedly called at a given
|
||||
interval. When you create a Timer object, it will do nothing until the
|
||||
startTimer() method is called, which will cause the message thread to
|
||||
start making callbacks at the specified interval, until stopTimer() is called
|
||||
or the object is deleted.
|
||||
|
||||
The time interval isn't guaranteed to be precise to any more than maybe
|
||||
10-20ms, and the intervals may end up being much longer than requested if the
|
||||
system is busy. Because the callbacks are made by the main message thread,
|
||||
anything that blocks the message queue for a period of time will also prevent
|
||||
any timers from running until it can carry on.
|
||||
|
||||
If you need to have a single callback that is shared by multiple timers with
|
||||
different frequencies, then the MultiTimer class allows you to do that - its
|
||||
structure is very similar to the Timer class, but contains multiple timers
|
||||
internally, each one identified by an ID number.
|
||||
|
||||
@see HighResolutionTimer, MultiTimer
|
||||
*/
|
||||
class JUCE_API Timer
|
||||
{
|
||||
protected:
|
||||
//==============================================================================
|
||||
/** Creates a Timer.
|
||||
|
||||
When created, the timer is stopped, so use startTimer() to get it going.
|
||||
*/
|
||||
Timer() noexcept;
|
||||
|
||||
/** Creates a copy of another timer.
|
||||
|
||||
Note that this timer won't be started, even if the one you're copying
|
||||
is running.
|
||||
*/
|
||||
Timer (const Timer& other) noexcept;
|
||||
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Destructor. */
|
||||
virtual ~Timer();
|
||||
|
||||
//==============================================================================
|
||||
/** The user-defined callback routine that actually gets called periodically.
|
||||
|
||||
It's perfectly ok to call startTimer() or stopTimer() from within this
|
||||
callback to change the subsequent intervals.
|
||||
*/
|
||||
virtual void timerCallback() = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** Starts the timer and sets the length of interval required.
|
||||
|
||||
If the timer is already started, this will reset it, so the
|
||||
time between calling this method and the next timer callback
|
||||
will not be less than the interval length passed in.
|
||||
|
||||
@param intervalInMilliseconds the interval to use (any values less than 1 will be
|
||||
rounded up to 1)
|
||||
*/
|
||||
void startTimer (int intervalInMilliseconds) noexcept;
|
||||
|
||||
/** Stops the timer.
|
||||
|
||||
No more callbacks will be made after this method returns.
|
||||
|
||||
If this is called from a different thread, any callbacks that may
|
||||
be currently executing may be allowed to finish before the method
|
||||
returns.
|
||||
*/
|
||||
void stopTimer() noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Checks if the timer has been started.
|
||||
|
||||
@returns true if the timer is running.
|
||||
*/
|
||||
bool isTimerRunning() const noexcept { return periodMs > 0; }
|
||||
|
||||
/** Returns the timer's interval.
|
||||
|
||||
@returns the timer's interval in milliseconds if it's running, or 0 if it's not.
|
||||
*/
|
||||
int getTimerInterval() const noexcept { return periodMs; }
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** For internal use only: invokes any timers that need callbacks.
|
||||
Don't call this unless you really know what you're doing!
|
||||
*/
|
||||
static void JUCE_CALLTYPE callPendingTimersSynchronously();
|
||||
|
||||
private:
|
||||
class TimerThread;
|
||||
friend class TimerThread;
|
||||
int countdownMs, periodMs;
|
||||
Timer* previous;
|
||||
Timer* next;
|
||||
|
||||
Timer& operator= (const Timer&);
|
||||
};
|
||||
|
||||
#endif // JUCE_TIMER_H_INCLUDED
|
||||
Loading…
Add table
Add a link
Reference in a new issue