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 theTEventhandler
class) pointed to by the application object'sfHeadCohandler
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 theTEventHandler
fieldfIdleFreq
of 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 itsPollToolboxEvent
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 constantsidleBegin
,idleContinue
, andidleEnd
. After thePollToolBoxEvent
method retrieves an event, it calls the application'sIdle
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.
- For a non-
NULL
event, and if the current idle phase isidleContinue
,PollToolBoxEvent
makes the following call to indicate that idling is ending:
this->Idle(idleEnd);It then sets the
fIdlePhase
field toidleBegin
(for the next timePollToolBoxEvent
is called).- For a
NULL
event,PollToolBoxEvent
calls
this->Idle(fIdlePhase);to indicate that idling is either beginning or continuing, then sets
fIdlePhase
toidleContinue
(for the next timePollToolBoxEvent
is called).
Distributing Idle Time
Idle time is distributed by the application object'sIdle
method. If your application class descends fromTMailingApplication
, which provides support for PowerTalk mailers, theTMailingApplication::Idle
method calls theDoMailerEvent
method of the mixin classMMailable
. TheDoMailerEvent
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 callsInherited
. That results in execution of theTApplication::Idle
method, which distributes idle time in the following order:
One MacApp class that overrides
- If the phase is
idleContinue
, theIdle
method calls MacApp'sIdleOSAScript
routine to give an attached script some idle time.- The
Idle
method iterates over any handlers in the application's cohandler chain, calling theHandleIdle
method for each cohandler.The
HandleIdle
method 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 isidleBegin
oridleEnd
, or if the phase isidleContinue
and the count indicates it is time,HandleIdle
calls the cohandler'sDoIdle
method. Your cohandler gets control in itsDoIdle
method.- The
Idle
method iterates over any objects in the application's target chain, calling theHandleIdle
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 theTEventHandler
class, iskMaxIdleTime
. As a result, an event-handler object will not receive idle time unless you setfIdleFreq
to a smaller value.
DoIdle
isTTEView
. In itsDoIdle
method it calls the Toolbox routineTEIdle
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.
- event received
idleBegin
phaseidleContinue
phaseidleContinue
phase- . . . (
idleContinue
phase multiple times)idleEnd
phase- event received
- event received (no idling between events)
idleBegin
phaseidleEnd
phase (noidleContinue
phase)- event received
- . . .
Idle Thoughts
Developers often expect that theDoIdle
method of their event-handler object will be called regularly, everyfIdleFreq
ticks. It won't. MacApp's idling mechanism is not a timer. YourDoIdle
method is called only when the application has been idle forfIdleFreq
ticks. When the application is busy, yourDoIdle
method will not be called (with theidleContinue
value) as often, if at all.Another common error is to perform a task in the
DoIdle
method without checking the idle phase. YourDoIdle
method may be called withidleBegin
andidleEnd
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:
DoIdle
gets called very frequently with the idle phaseidleBegin
oridleEnd
. It may be called too frequently to schedule an idle task (at least one of substantial length) for every begin or end phase.DoIdle
may get called withidleContinue
less 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
HandleAlienEvent
method. TheHandleAlienEvent
method iterates over the cohandlers in the application's cohandler chain (pointed to byfHeadCohandler
), callingDoCoHandlerEvent
. TheDoCoHandlerEvent
method does nothing inTEventHandler
, but your cohandler class can override it to process alien events.