Important: The information in this document is obsolete and should not be used for new development.
MacApp's Idling Mechanism
There are many possible uses for idle-time processing, such as displaying a screen saver (perhaps with a password, to protect sensitive data), checking a network connection, or validating entries in a dialog box. MacApp provides a mechanism to parcel out idle time when your program isn't busy. Idle time can be distributed to the Standard Mail Package (if the application uses it), to an attached script, to any event-handler object or behavior object in the target chain, and to any event-handler object or behavior object in a special chain called the cohandler chain.The Cohandler Chain
The cohandler chain is a list of event-handler objects (objects based on classes that descend from theTEventhandlerclass) pointed to by the application object'sfHeadCohandlerfield. The cohandler chain can be used to add background or polling tasks to your application. Polling means continually checking to see if an event has happened. A background task is one that continues to operate while another task is primary, such as a printing task that operates while you are actively typing in a word processor.A cohandler is an event-handler object that has been installed in the cohandler chain. You install a cohandler by calling
TApplication::InstallCohandler, and you use the same method to remove the cohandler when it has finished its task. You set theTEventHandlerfieldfIdleFreqof the cohandler to determine how often the cohandler is called. The smaller the value offIdleFreq, the more frequently the cohandler is called. A value of 0 indicates that the cohandler should be called as frequently as possible, while a value of LONG_MAX (231 - 1, or 2,147,483,647) essentially disables idling.For an example of how to implement a cohandler, see "Recipe--Ensuring Idle Time for an Event-Handler Object," beginning on page 341.
How Idling Happens
The application object periodically calls itsPollToolboxEventmethod to check for any waiting Toolbox events.PollToolBoxEventalso controls idling in the application, as described in the next sections.The Three Phases of Idling
There are three phases of idling, identified by the constantsidleBegin,idleContinue, andidleEnd. After thePollToolBoxEventmethod retrieves an event, it calls the application'sIdlemethod, passing an idle constant that depends on the type of event and the current idle phase:
The result of these calls is shown in "The Sequence of Idle Phases," beginning on page 136.
- For a non-
NULLevent, and if the current idle phase isidleContinue,PollToolBoxEventmakes the following call to indicate that idling is ending:
this->Idle(idleEnd);It then sets the
fIdlePhasefield toidleBegin(for the next timePollToolBoxEventis called).- For a
NULLevent,PollToolBoxEventcalls
this->Idle(fIdlePhase);to indicate that idling is either beginning or continuing, then sets
fIdlePhasetoidleContinue(for the next timePollToolBoxEventis called).
Distributing Idle Time
Idle time is distributed by the application object'sIdlemethod. If your application class descends fromTMailingApplication, which provides support for PowerTalk mailers, theTMailingApplication::Idlemethod calls theDoMailerEventmethod of the mixin classMMailable. TheDoMailerEventmethod gives the Standard Mail Package a chance to deal with certain kinds of events it is interested in--for example, it may need to focus a mailer window or perform internal processing.The
TMailingApplication::Idlemethod then callsInherited. That results in execution of theTApplication::Idlemethod, which distributes idle time in the following order:
One MacApp class that overrides
- If the phase is
idleContinue, theIdlemethod calls MacApp'sIdleOSAScriptroutine to give an attached script some idle time.- The
Idlemethod iterates over any handlers in the application's cohandler chain, calling theHandleIdlemethod for each cohandler.The
HandleIdlemethod is a method ofTEventHandler. It gives any behaviors attached to the cohandler a chance to have some idle time. Then, if the cohandler is enabled and the phase isidleBeginoridleEnd, or if the phase isidleContinueand the count indicates it is time,HandleIdlecalls the cohandler'sDoIdlemethod. Your cohandler gets control in itsDoIdlemethod.- The
Idlemethod iterates over any objects in the application's target chain, calling theHandleIdlemethod for each event-handler object. Objects and behaviors in the target chain get a chance at idle time in the same way that cohandlers and behaviors do in the cohandler chain.Note that the default value for
fIdleFreq, set in the constructor method for theTEventHandlerclass, iskMaxIdleTime. As a result, an event-handler object will not receive idle time unless you setfIdleFreqto a smaller value.
DoIdleisTTEView. In itsDoIdlemethod it calls the Toolbox routineTEIdleto ensure blinking of the insertion point.The Sequence of Idle Phases
As a result of MacApp's idling algorithm, the sequence of events and idle phases over time may look something like the following (boldface used for emphasis):
This sequence can lead to some surprising results, described in the next section.
- event received
idleBeginphaseidleContinuephaseidleContinuephase- . . . (
idleContinuephase multiple times)idleEndphase- event received
- event received (no idling between events)
idleBeginphaseidleEndphase (noidleContinuephase)- event received
- . . .
Idle Thoughts
Developers often expect that theDoIdlemethod of their event-handler object will be called regularly, everyfIdleFreqticks. It won't. MacApp's idling mechanism is not a timer. YourDoIdlemethod is called only when the application has been idle forfIdleFreqticks. When the application is busy, yourDoIdlemethod will not be called (with theidleContinuevalue) as often, if at all.Another common error is to perform a task in the
DoIdlemethod without checking the idle phase. YourDoIdlemethod may be called withidleBeginandidleEndfor every event the application processes. If you don't check the idle phase, your idle task may be performed much more frequently than you expect.In summary:
DoIdlegets called very frequently with the idle phaseidleBeginoridleEnd. It may be called too frequently to schedule an idle task (at least one of substantial length) for every begin or end phase.DoIdlemay get called withidleContinueless frequently than you expect. Empirical testing can help determine if the frequency is sufficient for your purpose.
Responding to Alien Events With a Cohandler
MacApp defines an event it doesn't anticipate handling as an alien event. Alien events include network events, driver events, null events, events defined by the Toolbox constantsapp1Evt,app2Evt, andapp3Evt, and any other events MacApp doesn't recognize, such as events defined by your application.The application dispatches alien events by calling its
HandleAlienEventmethod. TheHandleAlienEventmethod iterates over the cohandlers in the application's cohandler chain (pointed to byfHeadCohandler), callingDoCoHandlerEvent. TheDoCoHandlerEventmethod does nothing inTEventHandler, but your cohandler class can override it to process alien events.