From: mac@coos.dartmouth.edu (Milton A. Colvin)
Newsgroups: comp.sys.mac.programmer
Subject: Re: Time Manager Sample Code...
Date: 22 Nov 92 22:25:18 GMT
Organization: Dartmouth College, Hanover, NH

urritche@mcs.drexel.edu (Ralph Paul Ritchey) writes:


>	Does anyone know of any code floating around that I can get my
>hands on that uses the Time Manager?  I've poked around but haven't turned
>anything up yet....   Thanks in advance!



Is MPW C++ OK?

FILE Ticker.h
//----------------------------------------------------------------------------------------
// Included files:
//----------------------------------------------------------------------------------------
#include	<Types.h>
#include	<Timer.h>			// toolbox timer manager
 
//========================================================================================
// class CTicker
//========================================================================================
// implement a cyclic subroutine called every (usec) 5sec.
// this typically triggers some event or resets something
// the subroutine is called as a timer task
//	it must be memory resident
//	it cannot reference globals
//	it cannot call the OS
//
class CTicker : public TMTask
{
public:
	CTicker(long usec) : fInterval(-usec),fCount(0) { }	// create inactive ticker
	~CTicker()						{ Off(); }			// inactivate & destroy
	
	void			On();			// start ticking
	void			Off();			// stop
	Boolean			Busy();			// determine whether running
	
	virtual	void	Tick();			// tick went off
	long			Elapsed();		// elapsed time in usec
 
	long			fCount;			// incremented
 
protected:
	QElemPtr		Task();			// timer queue entry
	static pascal void	Ticked();	// handle & forward call
	
	long			fInterval;		// -usec intervals
};
 
//========================================================================================
// class CTicker
//========================================================================================
// run a precise timer
// this timer measures the time from OnIOff
// Once Off the elapsed time is available.
// the timer is reset by reuse
 
class CTimer : public TMTask
{
public:
	CTimer()						{ }		// create inactive timer
	~CTimer()						{ Off(); }	// inactivate & destroy timer
	
	void			On();			// start running
	void			Off();			// stop
	Boolean			Busy();			// determine whether running
	long			Elapsed();		// elapsed time in usec
 
protected:
	QElemPtr		Task();			// timer queue entry
};


FILE Ticker.cp

// implement various kinds of clock
#include	"Ticker.h"
#include	<Types.h>
#include	<Timer.h>			// toolbox timer manager
#include	<Limits.h>			// big numbers for times
 
#pragma segment Main			// some of this must be memory-resident
 
//========================================================================================
// class CTicker
//========================================================================================
 
// a timer task handler is called with the task pointer in A1
 
static void	*GetA1() = 0x2009;					// MOVE.L A1,D0
 
//----------------------------------------------------------------------------------------
// pass to OS as timer queue entry
inline QElemPtr	CTicker::Task()	{ return (QElemPtr)this; }
 
//----------------------------------------------------------------------------------------
// to enable the ticker fill in the timer task and prime it
void
CTicker::On()
{	qLink = NULL;
	qType = 0;
	tmCount = tmWakeUp = tmReserved = 0;
	tmAddr = Ticked;				// our handler
	InsXTime(Task());
	PrimeTime(Task(),fInterval);
}
 
//----------------------------------------------------------------------------------------
// remove ticker from active timer queue
//
void	CTicker::Off()	{ RmvTime(Task()); }
 
// i think this is true
Boolean	CTicker::Busy()	{ return qLink!=NULL; }
 
//----------------------------------------------------------------------------------------
// when called we set up the this pointer
// incrment the counter and forward the call
//
pascal void
CTicker::Ticked()
{	CTicker	&me = *(CTicker*)GetA1();	// this in A1
	PrimeTime(me.Task(),me.fInterval);		// reschedule
	me.fCount++;						// just for good measure
	me.Tick();							// pass control
}
 
//----------------------------------------------------------------------------------------
//
long	CTicker::Elapsed()	{ return fCount*-fInterval; }
 
//----------------------------------------------------------------------------------------
// the default handler does nothing
//
void	CTicker::Tick()	{ }
 
 
//========================================================================================
// class CTimer
//========================================================================================
 
// this limits the maximum duration we can measure
// if we really wanted to be good,
// we could handle the expiration and restart the timer
 
const long kMaxTime = INT_MAX;		// set a timer for as long as possible
 
//----------------------------------------------------------------------------------------
// pass to OS as timer queue entry
//
inline QElemPtr	CTimer::Task()	{ return (QElemPtr)this; }
 
//----------------------------------------------------------------------------------------
// fill in the timer task and prime it
//
void
CTimer::On()
{	qLink = NULL;
	qType = 0;
	tmCount = tmWakeUp = tmReserved = 0;
	tmAddr = NULL;				// no handler
	InsXTime(Task());
	PrimeTime(Task(),-kMaxTime);
}
 
//----------------------------------------------------------------------------------------
//
void	CTimer::Off()	{ RmvTime(Task()); }
 
//----------------------------------------------------------------------------------------
//
long	CTimer::Elapsed()	{ return tmCount-kMaxTime; }