Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
GameSource/xthing.c
/* |
xthing |
------ |
A little set of routines that allow you to stuff |
tasks in the time manager queue, which will be fed back to you |
in the XThingList queue, accessed within the application's |
main loop by calling ProcessXThingTask. |
7:17:22 PM 10/28/92 |
By Brigham Stevens |
Apple Computer, Inc. |
Developer Technical Support |
At init time call InitXThingTimer. |
Call StartXThing to add a task and start its clock. |
Call AddXThing to only add a task and NOT start its clock. |
At the end of your program call KillAllXThingTasks |
If your task wants to remove itself, it should return false. |
Xthing tasks have the form of: |
Boolean XThingUpdateTask(xthing *xtp, long dataRef) |
{ |
myDataStruct *mdp; |
Boolean result; |
mdp = (myDataStruct *)dataRef; |
mdp.count++; // do something usefull (less) |
if(mdp.count) |
result = true; // want to be run again |
else |
result = false; // tell Xthing not to re-install us |
} |
See Sprite.c for more examples. |
*/ |
#include "xthing.h" |
#include "ZAMProtos.h" |
static void XThingTimeTask(void); |
static long xThingCount = 0; |
static xQHdr XThingList; |
void InitXThingTimer(void) |
{ |
xInitQueueHeader(&XThingList); |
} |
static void XThingTimeTask(void) |
{ |
/* Time manager points to time task record in a1 */ |
/* We have all our data located after that, so it */ |
/* is simple to just do our thing */ |
asm { |
st.b xthing.taskFlag(a1) |
} |
} |
void ProcessXThingTask(short numTasksToProcess) |
/* |
Whip through the queue until there |
are no more entires. Each item is |
ripped from the queue, it's associated task |
is called, and the item is then fed back to |
the Time Manager task, which will give it back to us here |
when it is done chewing on it. |
If the user interface slows down because of too many things going on, |
you might want to add a task that basically calls your event loop |
once in a while. Then you could make this the main loop of your |
program if you were so inclined. |
*/ |
{ |
xthing *xtp; |
updateProc updateJSR; |
Boolean reTime; |
OSErr err; |
for(xtp = (xthing*)XThingList.qHead; xtp != nil; xtp = xtp->next) { |
if(xtp->taskFlag) { |
xtp->taskFlag = false; |
updateJSR = (updateProc)xtp->actionProc; |
if(updateJSR) { |
reTime = (*updateJSR)(xtp,xtp->dataRef); |
if(reTime) { |
RmvTime(&xtp->timer); |
InsTime(&xtp->timer); |
PrimeTime(&xtp->timer, xtp->interval); |
} |
} |
} |
} |
} |
void EnqueueXThing(xthing *xtp) |
{ |
xThingCount++; |
if(xtp->inList == false) { // change to bit field in taskFlag later |
xEnqueue(xtp,&XThingList); |
xtp->inList = true; |
} |
} |
void AddXThing(xthing *xtp, long prime, updateProc updtProc, long dataRef) |
/* |
This adds a thing to the xthing list, but does not start the tasks |
*/ |
{ |
short err = noErr; |
if(err == noErr) { |
/* set up default values */ |
xtp->timer.tmAddr = (ProcPtr)XThingTimeTask; |
xtp->interval = prime; |
xtp->taskFlag = false; |
xtp->dataRef = dataRef; |
xtp->actionProc = updtProc; |
xtp->waiting = true; |
EnqueueXThing(xtp); |
} |
} |
xthing *StartXThing(xthing *xtp, long prime, updateProc updtProc, long dataRef) |
/* |
The best thing about this |
is that it takes almost NO parameters |
pass the timing interval in prime |
a pointer to the update routine in updtProc |
and an application-defined reference in refcon. |
*/ |
{ |
short err = noErr; |
/* allocate a new thing */ |
if(xtp == nil) { |
xtp = (xthing*)NewPtrClear(sizeof(xthing)); |
if(!xtp){ |
err = MemError(); |
ErrMsgCode("\pNewPtrClear failed in StartThing",err); |
} |
} |
if(err == noErr) { |
/* set up default values */ |
xtp->timer.tmAddr = (ProcPtr)XThingTimeTask; |
xtp->interval = prime; |
xtp->taskFlag = false; |
xtp->dataRef = dataRef; |
xtp->actionProc = updtProc; |
xtp->waiting = true; |
EnqueueXThing(xtp); |
InsTime((QElemPtr)&xtp->timer); |
PrimeTime(&xtp->timer, xtp->interval); |
} |
return xtp; |
} |
void KillAllXThingTasks(void) |
{ |
xthing *xtp; |
for(xtp = (xthing*)XThingList.qHead; xtp != nil; xtp = xtp->next) { |
if( (xtp->timer.qType & TaskActiveFlag) != 0) |
RmvTime(&xtp->timer); |
} |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14