ClockSignal for sharing a sync'd timer


A very small and perhaps pointless thing to share, but it was the answer to my puzzle and could be for others in the future.

Basically, i had several objects that each needed a timer to keep them running, but they had to be in sync. They also needed to remain as separate objects, and also to remain in direct access without having relying on their container being a timer subclass.

It’s a clock signal, with a user specified timing resolution (in ms). Each tick of the clock calls clockAdvanced (double secondsAdvanced) for all registered listeners. If they require a timing update, with how far to advance, and they must all stay in sync, this is a solution.



#include "juce.h"

/** Base class for objects that need to share a synchronised timer. */
class ClockSignalListener
	/** This is called for every tick of the clock, and provides
		the time elapsed since the last clock tick. This will be the
		same value for all listeners so that they can be kept in sync. */
	virtual void clockAdvanced (double timeInSeconds) = 0;

class ClockSignal	:	public Timer

	ClockSignal ();

	/** Start the clock signal ticking. */
	void start ();
	/** Stop the clock signal ticking. */
	void stop ();

	/** Register a listener to recieve tick events from the clock. */
	void addListener (ClockSignalListener* listener);
	/** Unregister a ClockSignalListener. */
	void removeListener (ClockSignalListener* listener);

	/** Set the desired timing resolution. This can vary depending
		on CPU usage, so you can't guarantee that this is the exact
		time between ticks, but it should be reasonably close. The
		actual elapsed time is provided with each tick. */
	void setResolution (int ms);
	/** This implements the clock ticking. */
	void timerCallback ();


	int interval;	// the desired interval between ticks (ms)

	Array <ClockSignalListener*> listeners;	// listeners
	Time timeOfLastCycle; // the time of the previous tick




#include “ClockSignal.h”

ClockSignal::ClockSignal ()
interval = 10;

void ClockSignal::addListener (ClockSignalListener* listener)
listeners.addIfNotAlreadyThere (listener);

void ClockSignal::removeListener (ClockSignalListener* listener)
listeners.removeValue (listener);

void ClockSignal::setResolution (int ms)
interval = ms;
if (isTimerRunning ()) startTimer (interval);

void ClockSignal::start ()
timeOfLastCycle = Time::getCurrentTime ();
startTimer (interval);

void ClockSignal::stop ()
stopTimer ();

void ClockSignal::timerCallback ()
RelativeTime elapsed = Time::getCurrentTime () - timeOfLastCycle;
for (int i=listeners.size(); --i >= 0;)
listeners.getUnchecked (i)->clockAdvanced (elapsed.inSeconds ());
timeOfLastCycle = Time::getCurrentTime ();