1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Timer: Replace DeletedAtShutdown with SharedResourcePointer

This commit is contained in:
Anthony Nicholls 2023-11-27 14:08:26 +00:00
parent 418d7b9c38
commit 47be26deed
2 changed files with 37 additions and 64 deletions

View file

@ -24,7 +24,6 @@ namespace juce
{ {
class Timer::TimerThread final : private Thread, class Timer::TimerThread final : private Thread,
private DeletedAtShutdown,
private AsyncUpdater private AsyncUpdater
{ {
public: public:
@ -42,10 +41,6 @@ public:
signalThreadShouldExit(); signalThreadShouldExit();
callbackArrived.signal(); callbackArrived.signal();
stopThread (4000); stopThread (4000);
jassert (instance == this || instance == nullptr);
if (instance == this)
instance = nullptr;
} }
void run() override void run() override
@ -137,54 +132,10 @@ public:
callTimers(); callTimers();
} }
static void add (Timer* tim) noexcept
{
if (instance == nullptr)
instance = new TimerThread();
instance->addTimer (tim);
}
static void remove (Timer* tim) noexcept
{
if (instance != nullptr)
instance->removeTimer (tim);
}
static void resetCounter (Timer* tim) noexcept
{
if (instance != nullptr)
instance->resetTimerCounter (tim);
}
static TimerThread* instance;
static LockType lock;
private:
struct TimerCountdown
{
Timer* timer;
int countdownMs;
};
std::vector<TimerCountdown> timers;
WaitableEvent callbackArrived;
struct CallTimersMessage final : public MessageManager::MessageBase
{
CallTimersMessage() {}
void messageCallback() override
{
if (instance != nullptr)
instance->callTimers();
}
};
//==============================================================================
void addTimer (Timer* t) void addTimer (Timer* t)
{ {
const LockType::ScopedLockType sl (lock);
// Trying to add a timer that's already here - shouldn't get to this point, // Trying to add a timer that's already here - shouldn't get to this point,
// so if you get this assertion, let me know! // so if you get this assertion, let me know!
jassert (std::none_of (timers.begin(), timers.end(), jassert (std::none_of (timers.begin(), timers.end(),
@ -200,6 +151,8 @@ private:
void removeTimer (Timer* t) void removeTimer (Timer* t)
{ {
const LockType::ScopedLockType sl (lock);
auto pos = t->positionInQueue; auto pos = t->positionInQueue;
auto lastIndex = timers.size() - 1; auto lastIndex = timers.size() - 1;
@ -217,6 +170,8 @@ private:
void resetTimerCounter (Timer* t) noexcept void resetTimerCounter (Timer* t) noexcept
{ {
const LockType::ScopedLockType sl (lock);
auto pos = t->positionInQueue; auto pos = t->positionInQueue;
jassert (pos < timers.size()); jassert (pos < timers.size());
@ -238,6 +193,31 @@ private:
} }
} }
private:
LockType lock;
struct TimerCountdown
{
Timer* timer;
int countdownMs;
};
std::vector<TimerCountdown> timers;
WaitableEvent callbackArrived;
struct CallTimersMessage final : public MessageManager::MessageBase
{
CallTimersMessage() = default;
void messageCallback() override
{
if (auto instance = SharedResourcePointer<TimerThread>::getSharedObjectWithoutCreating())
(*instance)->callTimers();
}
};
//==============================================================================
void shuffleTimerBackInQueue (size_t pos) void shuffleTimerBackInQueue (size_t pos)
{ {
auto numTimers = timers.size(); auto numTimers = timers.size();
@ -309,9 +289,6 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TimerThread) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TimerThread)
}; };
Timer::TimerThread* Timer::TimerThread::instance = nullptr;
Timer::TimerThread::LockType Timer::TimerThread::lock;
//============================================================================== //==============================================================================
Timer::Timer() noexcept {} Timer::Timer() noexcept {}
Timer::Timer (const Timer&) noexcept {} Timer::Timer (const Timer&) noexcept {}
@ -335,15 +312,13 @@ void Timer::startTimer (int interval) noexcept
// running, then you're not going to get any timer callbacks! // running, then you're not going to get any timer callbacks!
JUCE_ASSERT_MESSAGE_MANAGER_EXISTS JUCE_ASSERT_MESSAGE_MANAGER_EXISTS
const TimerThread::LockType::ScopedLockType sl (TimerThread::lock);
bool wasStopped = (timerPeriodMs == 0); bool wasStopped = (timerPeriodMs == 0);
timerPeriodMs = jmax (1, interval); timerPeriodMs = jmax (1, interval);
if (wasStopped) if (wasStopped)
TimerThread::add (this); timerThread->addTimer (this);
else else
TimerThread::resetCounter (this); timerThread->resetTimerCounter (this);
} }
void Timer::startTimerHz (int timerFrequencyHz) noexcept void Timer::startTimerHz (int timerFrequencyHz) noexcept
@ -356,19 +331,17 @@ void Timer::startTimerHz (int timerFrequencyHz) noexcept
void Timer::stopTimer() noexcept void Timer::stopTimer() noexcept
{ {
const TimerThread::LockType::ScopedLockType sl (TimerThread::lock);
if (timerPeriodMs > 0) if (timerPeriodMs > 0)
{ {
TimerThread::remove (this); timerThread->removeTimer (this);
timerPeriodMs = 0; timerPeriodMs = 0;
} }
} }
void JUCE_CALLTYPE Timer::callPendingTimersSynchronously() void JUCE_CALLTYPE Timer::callPendingTimersSynchronously()
{ {
if (TimerThread::instance != nullptr) if (auto instance = SharedResourcePointer<TimerThread>::getSharedObjectWithoutCreating())
TimerThread::instance->callTimersSynchronously(); (*instance)->callTimersSynchronously();
} }
struct LambdaInvoker final : private Timer struct LambdaInvoker final : private Timer

View file

@ -127,9 +127,9 @@ public:
private: private:
class TimerThread; class TimerThread;
friend class TimerThread;
size_t positionInQueue = (size_t) -1; size_t positionInQueue = (size_t) -1;
int timerPeriodMs = 0; int timerPeriodMs = 0;
SharedResourcePointer<TimerThread> timerThread;
Timer& operator= (const Timer&) = delete; Timer& operator= (const Timer&) = delete;
}; };