Article
Difficulty Rating
7
StackFiles

.

.

.

Is your stack a bloated, heavyweight RAM guzzler? Want to save changes to individual subStacks in your standalone on a users machine? Can't stand the inconvenience of removing images from your stack and referencing them by fileName prior to delivery? Split your single mainStack/subStack combination into multiple files (each of which can be loaded and unloaded from memory individually), and use stackFiles to prevent scripts that refer to these subStacks being broken.

stackFiles is a stack property that is used to reference separate stacks stored in separate files by name, just as if they were subStacks.

Here's how to utilise the power of stackFiles.

Split your large stack up into multiple files, making the subStacks into mainStacks (though you can leave little stacks like ask and answer as subStacks of the mainStack if you like). To do that, open each stack and choose "Save As..." from the File menu. Note that Save As... will remove a subStack from its original mainStack and save it into a file (it does not leave a copy in the original mainStack).

Create a new folder called "Data" or something that equally conveys "don't go here"to the end user. Move all the subStacks that have newly been turned into files (of single mainStacks) into the new folder. This folder should be in the same folder as the standalone, but more about that later.

 

Toplevel your original mainStack, called "My Program" in the diagram. This should be the stack that actually gets built into the standalone, i.e. the one that loads from the desktop when you open up. (A good use for a stack like this is to display a splash screen or welcome notice.)

Select Stack Properties from the Edit menu, then click the Stack Files... button. Make sure the menu is showing the name of the current mainStack selected.

Type the stack names of each of the subStacks you just saved into separate files, one per line. Those are the actual names you have for each of these stacks, the ones you use on the stacks and in your scripts not the file path for each.

Next, go back up the list and add a comma to the end of each line.

Now, go through each line and add the file path to the file that each stack is now stored in.

For example:

C:/Program Files/MetaCard/Program/MyApp/Data/myfirstwindow.mc
                                             

However, a complete path like that is actually not a good idea. That's because when you install the application, you're not likely to be installing it in that directory. Your install directory will probably read something like..

C:/Program Files/MyApp/Data/myfirstwindow.mc
                                             

Don't try to guess this complete path, as the installation directory might be changed by the user. For example, the user might be instal onto drive "D" or run your program directly from the CD...

The solution to this problem is to use relative paths. Relative paths start at the current directory and move up from there. The current directory is set on start up by MetaCard to the directory the MetaCard application is running from. When you load a stack as a non-standalone, the directory will be set to the directory that the MetaCard application is in. When you load as a standalone, it will be the directory to the actual standalone application file.

Let's assume we're working with a standalone for the moment. The user installed it in a folder, and inside that folder your installation package put the Data folder with all your stacks (see the diagram above). The relative path to a stack in the Data folder is going to be..

Data/mywhateverexamplestack.mc
                                             

..as in the diagram. Note that you musn't start the relative path with a /, but rather with the name of the directory or file.

Go through all those lines of stackFiles and put the relative paths in. Close the stackFiles dialog and save the stack. Whenever that stack has been loaded, MetaCard will be able to find the stacks inside all those files by name. No need to alter your scripts that have been refering to subStacks during development.

Here is an example of what your stackFiles might look like. You have stacks named: First Window, Second window, and Third Window. You save these as mainStacks into first.mc, second.mc and third.mc and place them in the Data directory you created:

First Window,Data/first.mc
Second Window,Data/second.mc
Third Window,Data/third.mc
                                             

How do you test this when not in standalone mode? The directory path is set to the MC application on startup - so the relative path won't find those stacks. Either you move your stack to be in the MetaCard program folder (and the Data folder a folder inside the MetaCard program folder), or you put a few lines into your startup script that reads something like this:

on preOpenStack
  get the effective fileName of this stack
  set the itemDelimiter to "/"
  put empty into last item of it
  set the directory to it
  set the itemDelimiter to comma
  --put rest of preOpenStack script here
end preOpenStack
                                             

That should mean that your stack works both in standalone mode (where the directory is correct anyway) and non-standalone mode (where this script sets it to be correct).

Best of all, in standalone mode, since only the original mainStack is a standalone you can save changes to all the other stacks (a standalone can't be saved when running, and large stacks take ages to save, but little ones in their own files are no problem).

You don't need to name the stacks in that Data folder with a .mc extension. its often a good idea not to put an extension on them at all, that way people don't go poking at them. MetaCard will look at any file listed in stackFiles regardless of extension. So the example above would look like this:

First Window,Data/first
Second Window,Data/second
Third Window,Data/third
                                             

Once your stacks are in separate files you have much more control about when they get loaded into and out of memory. MetaCard will not load any of these stacks until they are opened by script, so memory is not used up until the stack is first used. Memory can also be freed automatically when the stack is closed, by setting the destroyStack and destroyWindow properties of each separate mainStack to true. Of course, if you set these properties to true, it will mean that the stack must be reloaded from disk each time it is used (this is slower). Setting these properties is therefore usually a good idea on larger stacks that are less likely to be wanted over and over again by the user, but often not a good idea on stacks that smaller or more frequently used, or where the load time of the invididual stack is critical.

Did you find this article useful? Have any ideas for future topics? Email Us!