MacApp's Idling MechanismThere 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 ChainThe cohandler chain is a list of event-handler objects (objects based on classes that descend from the
TEventhandlerclass) pointed to by the application object's
fHeadCohandlerfield. 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
InstallCohandler, and you use the same method to remove the cohandler when it has finished its task. You set the
fIdleFreqof the cohandler to determine how often the cohandler is called. The smaller the value of
fIdleFreq, 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 HappensThe application object periodically calls its
PollToolboxEventmethod to check for any waiting Toolbox events.
PollToolBoxEventalso controls idling in the application, as described in the next sections.
The Three Phases of IdlingThere are three phases of idling, identified by the constants
idleEnd. After the
PollToolBoxEventmethod retrieves an event, it calls the application's
Idlemethod, 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 is
PollToolBoxEventmakes the following call to indicate that idling is ending:
- For a
Distributing Idle TimeIdle time is distributed by the application object's
Idlemethod. If your application class descends from
TMailingApplication, which provides support for PowerTalk mailers, the
TMailingApplication::Idlemethod calls the
DoMailerEventmethod of the mixin class
DoMailerEventmethod 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.
TMailingApplication::Idlemethod then calls
Inherited. That results in execution of the
TApplication::Idlemethod, which distributes idle time in the following order:
One MacApp class that overrides
- If the phase is
Idlemethod calls MacApp's
IdleOSAScriptroutine to give an attached script some idle time.
Idlemethod iterates over any handlers in the application's cohandler chain, calling the
HandleIdlemethod for each cohandler.
HandleIdlemethod is a method of
TEventHandler. It gives any behaviors attached to the cohandler a chance to have some idle time. Then, if the cohandler is enabled and the phase is
idleEnd, or if the phase is
idleContinueand the count indicates it is time,
HandleIdlecalls the cohandler's
DoIdlemethod. Your cohandler gets control in its
Idlemethod iterates over any objects in the application's target chain, calling the
HandleIdlemethod 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 the
kMaxIdleTime. As a result, an event-handler object will not receive idle time unless you set
fIdleFreqto a smaller value.
TTEView. In its
DoIdlemethod it calls the Toolbox routine
TEIdleto ensure blinking of the insertion point.
The Sequence of Idle PhasesAs 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
- . . . (
idleContinuephase multiple times)
- event received
- event received (no idling between events)
- event received
- . . .
Idle ThoughtsDevelopers often expect that the
DoIdlemethod of their event-handler object will be called regularly, every
fIdleFreqticks. It won't. MacApp's idling mechanism is not a timer. Your
DoIdlemethod is called only when the application has been idle for
fIdleFreqticks. When the application is busy, your
DoIdlemethod will not be called (with the
idleContinuevalue) as often, if at all.
Another common error is to perform a task in the
DoIdlemethod without checking the idle phase. Your
DoIdlemethod may be called with
idleEndfor 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.
DoIdlegets called very frequently with the idle phase
idleEnd. 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 with
idleContinueless frequently than you expect. Empirical testing can help determine if the frequency is sufficient for your purpose.
Responding to Alien Events With a CohandlerMacApp 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 constants
app3Evt, and any other events MacApp doesn't recognize, such as events defined by your application.
The application dispatches alien events by calling its
HandleAlienEventmethod iterates over the cohandlers in the application's cohandler chain (pointed to by
DoCoHandlerEventmethod does nothing in
TEventHandler, but your cohandler class can override it to process alien events.