Optimizing the stack for MetaCardWhile the converted Tech Support TimeSaver runs fine now, there are some things that will optimize it for MetaCard which will make the scripts run more efficiently and provide additional features that HyperCard doesn't offer. None of these changes are required, but adding them will improve the functionality of the stack.
Use send to instead of idle handlersAs mentioned elsewhere, the idle message is supported for compatibility with HyperCard but is extremely inefficient, tying up the CPU and creating a great deal of overhead. It is highly recommended that idle handlers be avoided in scripts. MetaCard offers many other messages and commands to do what HyperCard users traditionally use idle to do. Take a look, for example, at the grab command, which makes an object follow the mouse, or the move command which puts objects into animated motion. But one of the most useful structures for replacing idle is the send to object command, which sends a message repeatedly to an object at an interval specified by the script.
Both the title card and the timer card of the Tech Support TimeSaver stack use an idle handler; in the first case to implement the repeated sound of a watch ticking, and in the second to update a timer display showing elapsed seconds. We will change both of these.
Go to the title card of the stack and open its card script. Delete or comment out the idle handler. Enter this handler in its place:
Now comment out the line in the openCard handler that sets the idleRate, and comment out or delete the entire closeCard handler as well. Insert the command doTicks just before the pass openCard command in the openCard handler. Finally, add a new closeCard handler:on doTicks play "Tick.rev" send "doTicks" to me in 1 second end doTicks
The entire script of the title card should now look like this (changes are in red):on closeCard repeat for each line l in the pendingmessages cancel item 1 of l end repeat pass closeCard end closeCard
Close the script editor. If you leave the card and then return, you will hear a steady ticking about once per second. What did we do?on openCard global gShowDialog -- set the idleRate to 800 if gShowDialog is "Yes" then put "No" into gShowDialog -- play "Bell" answer "This program is $5 shareware." & return & return & \ "NOTICE: Do not distribute this stack except in its original," \ && "unaltered form as a HyperCard file. See the About card" && \ "for details." with "More Info" or "OK" if it is "More Info" then lock screen go next card set scroll of card field "Info" to 0 unlock screen with visual effect dissolve fast end if end if doTicks pass openCard end openCard
The doTicks handler simply plays the sound and then instructs itself to call its own handler name again 1 second later. The doTicks command we inserted into the openCard script is the trigger that starts the process initially; after that, doTicks repeats itself on its own. When the card is closed, the closeCard handler examines the pendingMessages, which is a list of messages that are queued up waiting to be sent, and it loops through the list, canceling each one. The loop could optionally test for a condition if there were several different handlers queueing up lots of different kinds of pending messages, but in this case, we have only one type of pending message so we just cancel them all.
The advantage to using this approach instead of idle is that while pending messages are being sent and executed, MetaCard continues to be fully operational; the user has full control of the mouse and keyboard, other messages are sent normally, and there is no slowdown while the system waits for an idle handler to finish before moving on to the next task.
Go to the Timer2 card now and open its script. Change every instance of the word idle to checkTime. Delete the pass idle line in the idle script completely. Insert the line send checkTime to me in 200 milliseconds at the end of the checkTime handler, and insert the command checkTime just before the pass openCard command in the openCard handler.
In addition, add the same closeCard handler we used before so that all pending messages will be canceled when the user leaves the Timer card.
The revised card script looks like this:
Leave the card and return again to trigger the openCard handler. Then try the timer.on openCard global gTimerOpenOrClosed put "Open" into gTimerOpenOrClosed checkTime pass openCard end openCard
All contents copyright (C) 1996, HyperActive Software. All rights reserved.
Revised: December 3, 2001