Skip to content

Commit

Permalink
Timer: Replace DeletedAtShutdown with SharedResourcePointer
Browse files Browse the repository at this point in the history
  • Loading branch information
Anthony-Nicholls committed Dec 1, 2023
1 parent 418d7b9 commit 47be26d
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 64 deletions.
99 changes: 36 additions & 63 deletions modules/juce_events/timers/juce_Timer.cpp
Expand Up @@ -24,7 +24,6 @@ namespace juce
{

class Timer::TimerThread final : private Thread,
private DeletedAtShutdown,
private AsyncUpdater
{
public:
Expand All @@ -42,10 +41,6 @@ class Timer::TimerThread final : private Thread,
signalThreadShouldExit();
callbackArrived.signal();
stopThread (4000);
jassert (instance == this || instance == nullptr);

if (instance == this)
instance = nullptr;
}

void run() override
Expand Down Expand Up @@ -137,54 +132,10 @@ class Timer::TimerThread final : private Thread,
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)
{
const LockType::ScopedLockType sl (lock);

// 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 (std::none_of (timers.begin(), timers.end(),
Expand All @@ -200,6 +151,8 @@ class Timer::TimerThread final : private Thread,

void removeTimer (Timer* t)
{
const LockType::ScopedLockType sl (lock);

auto pos = t->positionInQueue;
auto lastIndex = timers.size() - 1;

Expand All @@ -217,6 +170,8 @@ class Timer::TimerThread final : private Thread,

void resetTimerCounter (Timer* t) noexcept
{
const LockType::ScopedLockType sl (lock);

auto pos = t->positionInQueue;

jassert (pos < timers.size());
Expand All @@ -238,6 +193,31 @@ class Timer::TimerThread final : private Thread,
}
}

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)
{
auto numTimers = timers.size();
Expand Down Expand Up @@ -309,9 +289,6 @@ class Timer::TimerThread final : private Thread,
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 (const Timer&) noexcept {}
Expand All @@ -335,15 +312,13 @@ void Timer::startTimer (int interval) noexcept
// running, then you're not going to get any timer callbacks!
JUCE_ASSERT_MESSAGE_MANAGER_EXISTS

const TimerThread::LockType::ScopedLockType sl (TimerThread::lock);

bool wasStopped = (timerPeriodMs == 0);
timerPeriodMs = jmax (1, interval);

if (wasStopped)
TimerThread::add (this);
timerThread->addTimer (this);
else
TimerThread::resetCounter (this);
timerThread->resetTimerCounter (this);
}

void Timer::startTimerHz (int timerFrequencyHz) noexcept
Expand All @@ -356,19 +331,17 @@ void Timer::startTimerHz (int timerFrequencyHz) noexcept

void Timer::stopTimer() noexcept
{
const TimerThread::LockType::ScopedLockType sl (TimerThread::lock);

if (timerPeriodMs > 0)
{
TimerThread::remove (this);
timerThread->removeTimer (this);
timerPeriodMs = 0;
}
}

void JUCE_CALLTYPE Timer::callPendingTimersSynchronously()
{
if (TimerThread::instance != nullptr)
TimerThread::instance->callTimersSynchronously();
if (auto instance = SharedResourcePointer<TimerThread>::getSharedObjectWithoutCreating())
(*instance)->callTimersSynchronously();
}

struct LambdaInvoker final : private Timer
Expand Down
2 changes: 1 addition & 1 deletion modules/juce_events/timers/juce_Timer.h
Expand Up @@ -127,9 +127,9 @@ class JUCE_API Timer

private:
class TimerThread;
friend class TimerThread;
size_t positionInQueue = (size_t) -1;
int timerPeriodMs = 0;
SharedResourcePointer<TimerThread> timerThread;

Timer& operator= (const Timer&) = delete;
};
Expand Down

0 comments on commit 47be26d

Please sign in to comment.