[comp.sys.mac.hypercard] About globals in XCMDs

taylorj@yvax.byu.edu (07/27/90)

I think there's a lot of confusion about globals in XCMDs.  I will attempt to
cast some light on the subject from my limited knowledge, and perhaps others
can either amplify or correct...

As I understand it, there are two completely different meanings for the term
"global".
1) Variables that can be accessed by more than one function or
procedure.  I would also lump C's static variables in this category.
2) Persistent variables that "stick around" between calls from HyperCard to
the XCMD.

It's very easy to work with the first type of global variables in either C or
Pascal (contrary to popular belief and quite a number of manuals).  I use
SetupA4 in Think C 3.0 and can happily use all the global and
static variables that my heart desires, AS LONG AS I don't expect any of these
variables to be valid once my XCMD returns control to HyperCard.

As far as I know, no language directly supports the second kind: persistent
globals.  But there are lots of ways to do it yourself.  Here are a few...

- Store the global data in HyperCard globals.  This works quite well and
doesn't seem to degrade performance much.

- Store the data via a locked handle and return the handle address as the
result of the XFCN (to be returned in future calls) or put the handle address
in a HyperCard global.  This seems to work better for very large amounts of
data, as you only have to deal with HyperCard to get the handle instead of the
entire amount of data.  You also don't have to worry about HyperCard messing up
complex data structures.

- Store the global data in a resource.


It may help to think of calling an XCMD as similar to running a program.  For
example, you expect an application to use global variables, but you would never
expect to run it one day then run it again the next day and still be able
to access the data for those global variables.  You can likewise think of
persistent global variables as similar to preferences, which must be stored in
resources or a file in the System Folder in order to stick around between uses
of an application.

Please correct me if any of this is wrong or unclear.


Jim Taylor
Microcomputer Support for Curriculum   |
Brigham Young University               |   Bitnet: taylorj@byuvax.bitnet
101 HRCB, Provo, UT  84602             |   Internet: taylorj@yvax.byu.edu

bc@Apple.COM (bill coderre) (08/04/90)

In article <1425taylorj@yvax.byu.edu> taylorj@yvax.byu.edu writes:
|As far as I know, no language directly supports the second kind: persistent
|globals.  But there are lots of ways to do it yourself.  Here are a few...

A good mechanism for variables which are persistent across XCMD calls
but not across program runs can be gleaned from how many device
drivers are written.

Basically, you need 3 or 5 calls (the optional ones are in parens):

fooINIT		-- takes no argument, returns a handle
(fooWARMUP) 	-- "gets ready" to do work
fooGO		-- does some quantum of work
(fooWRAPUP)	-- stop doing work
fooDIE		-- go away now

INIT should create a handle, stuff whatever constants or whatnot in
it, and return it. The Hypercard program is responsible for keeping
the handle around, and sending it with EACH of the calls below.

WARMUP should do whatever is needed to prepare to do work without
actually doing it. In a printer driver, this would be to allocate the
port, send setup codes, etc. On a screen saver, this would be to turn
the screen black and set up an interrupt routine to check for events.

GO does a small amount of work, such as printing a little text or
drawing a few stars on the black screen.

WRAPUP takes care of shutting the job down, such as padding and
flushing the buffe and closing the port, or sending a message to the
window system to update itself.

DIE destroys the handle. If the HC program doesn't call die, it is a
fatal error.

Obviously, many XCMDs won't need WARMUP and WRAPUP. And there might be
different GO commands, to do different things. But the basic ideas of
INIT creating a handle before doing any work and DIE deleting it on
program exit are the important ones to allow for persistence in many
systems.