Ok, here’s my modified source code anyway, OS X only:
EDIT: MADE A MODIFICATION IN juce_mac_timers.cpp on 15th may 2008. MAKE SURE TO USE THIS VERSION.
JUCE_Timer.cpp
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the
GNU General Public License, as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
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.
You should have received a copy of the GNU General Public License
along with JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../juce_core/basics/juce_StandardHeader.h"
#include "../../../build/macosx/platform_specific_code/juce_mac_Timers.h"
BEGIN_JUCE_NAMESPACE
void mac_startTimer(void *timer, int milliseconds);
void mac_stopTimer(void *timer);
#include "juce_Timer.h"
#include "juce_MessageManager.h"
#include "juce_AsyncUpdater.h"
#include "../application/juce_Application.h"
#include "../application/juce_DeletedAtShutdown.h"
#include "../../juce_core/basics/juce_Time.h"
#include "../../juce_core/threads/juce_Thread.h"
#include "../../juce_core/threads/juce_ScopedLock.h"
#include "../../juce_core/containers/juce_VoidArray.h"
Timer::Timer() throw()
: countdownMs (0),
periodMs (0),
previous (0),
next (0)
{
#ifdef JUCE_DEBUG
activeTimers.add (this);
#endif
}
Timer::Timer (const Timer&) throw()
: countdownMs (0),
periodMs (0),
previous (0),
next (0)
{
}
Timer::~Timer()
{
stopTimer();
}
void Timer::startTimer (const int interval) throw()
{
stopTimer();
periodMs=interval;
if (interval>0) mac_startTimer((void*)this,interval);
}
void Timer::stopTimer() throw()
{
if (periodMs>0) mac_stopTimer(this);
periodMs=0;
}
END_JUCE_NAMESPACE
Juce_Timer.h
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the
GNU General Public License, as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
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.
You should have received a copy of the GNU General Public License
along with JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_TIMER_JUCEHEADER__
#define __JUCE_TIMER_JUCEHEADER__
class InternalTimerThread;
//==============================================================================
/**
Repeatedly calls a user-defined method at a specified time interval.
A Timer's timerCallback() method will be repeatedly called at a given
interval. Initially when a Timer object is created, they will do nothing
until the startTimer() method is called, then the message thread will
start calling it back until stopTimer() is called.
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 it's the message thread that is doing the callbacks,
any messages that take a significant amount of time to process will block
all the timers for that period.
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 MultiTimer
*/
class JUCE_API Timer
{
protected:
//==============================================================================
/** Creates a Timer.
When created, the timer is stopped, so use startTimer() to get it going.
*/
Timer() throw();
/** 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) throw();
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 (const int intervalInMilliseconds) throw();
/** 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() throw();
//==============================================================================
/** Checks if the timer has been started.
@returns true if the timer is running.
*/
bool isTimerRunning() const throw() { 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 throw() { return periodMs; }
//==============================================================================
void* OSXEventLoopTimerRef;
void* OSXEventLoopTimerUPP;
private:
friend class InternalTimerThread;
int countdownMs, periodMs;
Timer* previous;
Timer* next;
const Timer& operator= (const Timer&);
};
#endif // __JUCE_TIMER_JUCEHEADER__
juce_mac_timers.cpp
#include <Carbon/Carbon.h>
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/events/juce_Timer.h"
OSStatus timerProc(EventLoopTimerRef inTimer, void *inUserData) // inUserData is the pointer to our Timer object
{
((Timer*)inUserData)->timerCallback();
return noErr;
}
void mac_startTimer(void *timer_, int milliseconds)
{
Timer *timer=(Timer*)timer_;
EventLoopTimerRef ref;
EventLoopTimerUPP timerUPP = NewEventLoopTimerUPP((EventLoopTimerProcPtr)timerProc);
InstallEventLoopTimer(GetMainEventLoop(),kEventDurationMillisecond*milliseconds,kEventDurationMillisecond*milliseconds,timerUPP,(void*)timer,&ref);
timer->OSXEventLoopTimerRef=(void*)ref;
timer->OSXEventLoopTimerUPP=(void*)timerUPP;
}
void mac_stopTimer(void *timer_)
{
Timer *timer=(Timer*)timer_;
EventLoopTimerUPP timerUPP=(EventLoopTimerUPP)timer->OSXEventLoopTimerUPP;
EventLoopTimerRef ref=(EventLoopTimerRef)timer->OSXEventLoopTimerRef;
RemoveEventLoopTimer(ref);
DisposeEventLoopTimerUPP(timerUPP);
}
END_JUCE_NAMESPACE
juce_mac_timers.h
void mac_startTimer(void *timer, int milliseconds);
void mac_stopTimer(void *timer);