Previous Book Contents Book Index Next

Inside Macintosh: Programmer's Guide to MacApp / Part 1 - MacApp Theory and Architecture
Chapter 5 - Events and Commands

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 the TEventhandler class) pointed to by the application object's fHeadCohandler field. 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 the TEventHandler field fIdleFreq of 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 Happens

The application object periodically calls its PollToolboxEvent method to check for any waiting Toolbox events. PollToolBoxEvent also 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 constants idleBegin, idleContinue, and idleEnd. After the PollToolBoxEvent method retrieves an event, it calls the application's Idle method, 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.

Distributing Idle Time

Idle time is distributed by the application object's Idle method. If your application class descends from TMailingApplication, which provides support for PowerTalk mailers, the TMailingApplication::Idle method calls the DoMailerEvent method of the mixin class MMailable. The DoMailerEvent method 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::Idle method then calls Inherited. That results in execution of the TApplication::Idle method, which distributes idle time in the following order:

  1. If the phase is idleContinue, the Idle method calls MacApp's IdleOSAScript routine to give an attached script some idle time.
  2. The Idle method iterates over any handlers in the application's cohandler chain, calling the HandleIdle method for each cohandler.

    The HandleIdle method 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 idleBegin or idleEnd, or if the phase is idleContinue and the count indicates it is time, HandleIdle calls the cohandler's DoIdle method. Your cohandler gets control in its DoIdle method.

  3. The Idle method iterates over any objects in the application's target chain, calling the HandleIdle method 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 TEventHandler class, is kMaxIdleTime. As a result, an event-handler object will not receive idle time unless you set fIdleFreq to a smaller value.

One MacApp class that overrides DoIdle is TTEView. In its DoIdle method it calls the Toolbox routine TEIdle to 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.

Idle Thoughts

Developers often expect that the DoIdle method of their event-handler object will be called regularly, every fIdleFreq ticks. It won't. MacApp's idling mechanism is not a timer. Your DoIdle method is called only when the application has been idle for fIdleFreq ticks. When the application is busy, your DoIdle method will not be called (with the idleContinue value) as often, if at all.

Another common error is to perform a task in the DoIdle method without checking the idle phase. Your DoIdle method may be called with idleBegin and idleEnd for 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:

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 constants app1Evt, app2Evt, and app3Evt, and any other events MacApp doesn't recognize, such as events defined by your application.

The application dispatches alien events by calling its HandleAlienEvent method. The HandleAlienEvent method iterates over the cohandlers in the application's cohandler chain (pointed to by fHeadCohandler), calling DoCoHandlerEvent. The DoCoHandlerEvent method does nothing in TEventHandler, but your cohandler class can override it to process alien events.

Previous Book Contents Book Index Next

© Apple Computer, Inc.
25 JUL 1996