#include #include "cVBLtask.h" // =========================================================================== // cVBLtask.cpp Version 1.2 ©1998 Joakim Braun All rights reserved. // =========================================================================== // // CONTENTS: A base class for vertical retrace tasks (VBL tasks). Handles installing // and removing of tasks. Subclass to add functionality. // HOW TO USE: Derive a class from cVBLtask. Override GotVBLResources() and DoVBLTask(). // Instantiate the object. VBL task lasts until object goes out of scope. // cVBLtask is free for any and all use. // Do not distribute modified source code under my name. // No support promised, no liability accepted. Provided "as is". // That said, I can be reached at braun@swipnet.se. // Change history: // 1.1 March 30, 1997 First release // 1.2 August 30, 1998 Cleaned up code (gah!!) for re-release // =========================================================================== // Ä Constructor // =========================================================================== // // Store VBL interval, set sets taskIsRunning to false. // Remember to call this constructor BEFORE doing any constructing on your own // in sub-classes, such as automatically installing the task. cVBLtask:: cVBLtask(Int16 newVBLinterval){ mVblInterval = newVBLinterval; mTaskIsRunning = false; } // =========================================================================== // Ä Destructor // =========================================================================== // // Removes VBL task (if running) cVBLtask:: ~cVBLtask(void){ RemoveVBLtask(); } // =========================================================================== // Ä VBLtask() // =========================================================================== // // The VBL task called by the system, which in turn calls DoVBLtask(). #if GENERATINGCFM pascal void cVBLtask:: VBLtask(VBLTaskPtr vblTaskPtr){ long oldA5; smartVBLtaskPtr myTaskPtr = (smartVBLtaskPtr) vblTaskPtr; oldA5 = SetA5(myTaskPtr->A5); // Call virtual doVBLtask() func myTaskPtr->vblObject->DoVBLtask(); // Reset vblCount, so that we get called again myTaskPtr->theTask.vblCount = myTaskPtr->vblObject->mVblInterval; SetA5(oldA5); } #else pascal void cVBLtask:: VBLtask(VBLTaskPtr vblTaskPtr: __A0){ long oldA5; smartVBLtaskPtr myTaskPtr = (smartVBLtaskPtr) vblTaskPtr; oldA5 = SetA5(myTaskPtr->A5); // Call virtual doVBLtask() func myTaskPtr->vblObject->DoVBLtask(); // Reset vblCount, so that we get called again myTaskPtr->theTask.vblCount = myTaskPtr->vblObject->mVblInterval; SetA5(oldA5); } #endif // =========================================================================== // Ä InstallVBLtask() // =========================================================================== // // Check if we have everything we need, give subclass a chance to do some extra // initialization, and start the VBL task. void cVBLtask:: InstallVBLtask(void){ // If we have the resources, and if we're not running... if(!mTaskIsRunning && GotVBLresources()){ // Make a VBL task ptr mTaskRecord = (smartVBLtaskPtr) ::NewPtr(sizeof(VBLTaskWithA5AndObjectPtr)); // If we got it, install VBL task if(mTaskRecord){ InitBeforeVBLinstall(); mTaskRecord->theTask.qType = vType; mTaskRecord->theTask.vblAddr = NewVBLProc(VBLtask); mTaskRecord->theTask.vblCount = mVblInterval; mTaskRecord->theTask.vblPhase = 0; mTaskRecord->A5 = (long) SetCurrentA5(); mTaskRecord->vblObject = this; ::VInstall((QElemPtr) mTaskRecord); mTaskIsRunning = true; } } } // =========================================================================== // Ä RemoveVBLtask() // =========================================================================== // // Remove the task, if it's running, and give subclass a chance to clean up void cVBLtask:: RemoveVBLtask(void){ // If we have a task installed... if(mTaskIsRunning){ // ...remove it... ::VRemove((QElemPtr) mTaskRecord); //...get rid of the UPP to our static VBLTask function... DisposeRoutineDescriptor(mTaskRecord->theTask.vblAddr); // ...and deallocate the task record. ::DisposePtr((Ptr) mTaskRecord); CleanupAfterVBLremove(); mTaskIsRunning = false; } } // =========================================================================== // Ä InitBeforeVBLinstall() // =========================================================================== // // This gets called immediately prior to installing the VBL task. // Do any preparation you need by overriding this func void cVBLtask:: InitBeforeVBLinstall(void){} // =========================================================================== // Ä CleanupAfterVBLremove() // =========================================================================== // // This gets called immediately after removal of the VBL task. // Override to deallocate resources or clean up // (Like restoring the arrow cursor, if your subclass is an asynchronous spinning cursor) void cVBLtask:: CleanupAfterVBLremove(void){} // =========================================================================== // Ä GotVBLresources() // =========================================================================== // // This gets called prior to installing the VBL task. // Task only gets installed if this returns true. // Override in subclass to tell object if you got resources you need to run the task. Boolean cVBLtask:: GotVBLresources(void){ return false; } // =========================================================================== // Ä DoVBLtask() // =========================================================================== // // The actual, task which your subclass needs to override. void cVBLtask:: DoVBLtask(void){}