Book Contents          Previous Chapter          Next Chapter

Software Packages

Software Packages

This chapter describes software packages, collections of objects that perform functions and provide features for Magic Cap users. Software packages are often called simply packages. Before reading this chapter, you should be familiar with the fundamental concepts of Magic Cap's object runtime.

About Software Packages

Magic Cap includes several major sets of features, such as the datebook, notebook and name card file, that provide services usually handled by application programs on conventional computer systems. In addition to these built-in features, Magic Cap provides a platform for additional features to be added via software packages. Whenever you deliver any additional features to Magic Cap users, you'll provide a software package.

Software packages are represented by storage boxes on storeroom shelves

In addition to collecting the objects that implement your features, software packages also provide an interface in the storeroom for users to install and remove your objects.

Software packages can install their objects in many different places in Magic Cap. You can have your package install its objects wherever appropriate. Some typical locations for package objects are as follows:

The list above shows suggested installation points for some kinds of objects. Many more installation points are available. Each package designates where to install its objects. In many cases, users can customize the location of package objects by moving viewables in Magic Cap. For example, a user who wants quicker access to the calculator can move it out of the desk accessories drawer and place it directly on the desk. Similarly, a user can get faster access to a favorite game by copying the game's icon in the game room and placing the copy in a more convenient location.

Packages appear to users as storage boxes on shelves in the storeroom. Users can pack up, unpack, copy, send, throw away, and otherwise work with packages by manipulating their storage boxes. The user can look inside the storage box in the storeroom to learn more about a package. You can customize the scene that appears when the user looks inside the storage box for your package.

Your software packages install their objects when the user unpacks them. You specify the objects you want your package to install and their destinations. When your package is packed up or removed, Magic Cap removes your package's objects from their installation points.

When the communicator shuts off, power to transient RAM isn't maintained, so your package must be designed to handle the sudden loss of transient objects. Magic Cap provides various operations that provide notification when the communicator turns on so that you can allocate buffers, restart servers, and rebuild other transient objects.

Magic Cap defines an extensive set of interpackage operability features that allow users to exchange objects between packages where appropriate. Using these features, your package can use objects defined by other packages and call operations of classes defined by other packages. Your package can use these features to provide other packages with access to its own objects.

Kinds of Packages

A package's contents can range from a small set to a large, complex collection, providing users with a single stamp or an entire application. Every package includes exactly one object that is a member of class SoftwarePackage. This vitally important software package object specifies information about the package, as described throughout this chapter and in the SoftwarePackage chapter of Magic Cap Class and Method Reference.

Software packages can be categorized according to how they appear to users, although there are no technical differences in creating and building the various kinds of packages. Using this categorization, there are three kinds of packages: applications, feature collections, and object collections.

Applications are packages that perform the functions of traditional software applications. Examples of applications include packages for e-mail clients, spreadsheets, and games. Applications generally provide their own scenes and usually appear to users as a door in the hallway or a building downtown, or in the desk drawer or the game room.

Feature collections provide tools, commands, or other functions that are available throughout Magic Cap or in particular places. For example, a feature collection package might provide a new set of drawing tools for the tool holder, a spell checker button for the Magic Lamp, a directory for the storeroom that lists all installed packages, a group of coupons that align viewables, or a handwriting recognizer pad that appears as a type of keyboard. Feature collections generally don't provide their own scenes, but instead appear inside other viewables.

Object collections install items that users can add to messages, name cards, and other objects they create. Example of these packages include collections of stamps, sets of songs, a group of datebook appointments, coupons for fonts or colors, or new stationery types for telecards. Object collections are distinguished from feature collections in that object collections add mostly content, not functions, and contain little or no code, while feature collections mainly add functions, not content, and can contain significant amounts of code.

Note that Magic Cap doesn't distinguish among these kinds of packages. They are all created in the same way, and they all contain a single object that is a member of class SoftwarePackage. The categories exist only to help users and developers understand what packages can do. Applications, feature collections, and object collections are all built by developers and manipulated by users in the same way. Some packages contain aspects of more than one of these types, while other packages defy categorization entirely.

Packages and Storage Boxes

Users occasionally need direct control over packages for such important but rare activities as installing and removing them. Users see packages as storage boxes on shelves in the storeroom. They appear in one of two states, as shown in the following figure:

At the left is a storage box for a package that is unpacked. An unpacked package has its objects installed and ready to use. The storage box on the right represents a package that is packed up. All of its objects have been removed from their places in Magic Cap, including any door in the hallway or building downtown, and none of its features can be used until the user unpacks it (although its objects still occupy memory). The only vestige of a packed-up package that is visible to users is its storage box, which remains in the storeroom.

Users can permanently remove a package by sliding it to the trash and emptying the trash. Most Magic Cap implementations include some packages in ROM. These packages can be packed up, but not removed.

When the user touches a package in the storeroom, it opens to fill the screen with a package storeroom scene. The package storeroom scene displays information about the package and provides a user interface for other housekeeping functions.

Package storeroom scene

In the package storeroom scene above, the name and version number of the package are displayed along with an image (in this case, a roast turkey with trimmings). The scene also shows the name of the package's author (General Magic DTS) and publisher (General Magic), their associated images, and the package's version number.

You specify all this information in your instance definition file when you create your package.

The name of the software package object becomes the name of the storage box and the name displayed in the package storeroom scene. The version number comes from an object of class Citation specified by the package. The software package object's citation field refers to this object. Magic Cap gets an image from item 15 of the package root list and displays it to the left of the package name.

The package author and publisher and their images are specified by the package object's author and publisher fields. These fields refer to objects of class AddressCard, the class of objects that provide the content for name cards. To set the author and publisher for your package, you'll provide the appropriate address cards, then set the package object's fields to refer to them.

The right side of the scene includes five buttons used for various actions. The top button, pack up, packs the package and removes its objects from their places in Magic Cap. When the package is packed up, the top button changes its name and action to unpack. Touching the second button, go to, takes the user to the package. If the package provides online documentation, the user can touch guide to see the documentation, which is usually an object of class Book.

The fourth button, credits, goes to a scene that gives more information about who made the package. Touching respond creates a new message card from stationery provided by the package. This card can be used for registering the software, providing comments, or any other purpose.

Magic Cap provides these buttons automatically. You don't have to specify them in your packages. Only the first button, pack/unpack, appears for every package. The other four buttons are optional and appear only if your package provides the appropriate objects. Otherwise, the buttons are disabled and are not drawn.

To give your package a go to button, specify an object list of your package's scenes as package root list item 6, with your package's main scene as the first entry in this object list. To enable your package's guide button, specify a book object in item 17 of the package root list. When the user touches guide, the specified book will open in its scene.

If your package has a custom credits scene, refer to it in item 18 of the package root list. To enable the respond button, include an object of class Stationery in your package and set item 19 in the package root list to refer to it. You should also include a telecard, which the stationary object refers to. When the user touches respond, Magic Cap will create a new message card from your stationery and take the user to the message scene.

When the user packs or unpacks the package, Magic Cap displays a public address announcement describing the action that just took place. Magic Cap supplies simple default announcements for these actions. If you want to provide custom announcements when the user packs or unpacks, specify an object list of text objects in item 11 of the package root list. The first text object in the list will be announced when the package is unpacked, and the second object will be announced upon packing.

Every package creates new objects as it is used. In fact, just installing a package causes some new package objects to be created. Packages in RAM and on ROM PC cards store their changes in RAM by default, while packages on RAM PC cards keep their changes on the same card by default. The value given in the package storeroom scene as Size of changes indicates how much memory is occupied by changes to the package persistent cluster.

Magic Cap installs a delete changes button in the Magic Lamp for every package storeroom scene. When the user touches delete changes, Magic Cap throws away any changes to the package by emptying its package changes and package shadow clusters. This button and its function are provided automatically by Magic Cap. You don't have to add anything to your package to support it.

Most of Magic Cap's major built-in features, including the datebook, notebook, name card file, client for AT&T PersonaLink Services, and phone, are called built-in packages because they perform much like packages, providing an organized collection of functions to users. However, these built-in features are not organized as true software packages, but as parts of Magic Cap itself. They are not represented by storage boxes on shelves in the storeroom, and they create objects in system clusters, rather than in package clusters. One exception to this is the calculator, which is a true package and is represented by a storage box in the storeroom. See the Object Runtime chapter of this book for more information on clusters and memory management.

For information on what happens to packages as the user manipulates package storage boxes, see the Package States section of this chapter.

How Packages Install Objects

When the user unpacks a package, some of the objects it contains are placed in particular scenes, windows, and other Magic Cap objects. These are the package's installed objects, and they are placed in receivers. After the objects are installed, they become available to the user, implementing the features of the package. When the package is packed up, the objects it installed are removed from their receivers and are no longer available to the user.

Packages specify each object to be installed and each receiver. The software package object's installList field refers to a the list of objects to be installed, and the receivers field refers to the objects that will get them. Magic Cap recognizes certain types of install-receive pairs and takes appropriate action to install the specified object. For some install-receive pairs, Magic Cap adds the specified object to its receiver. For example, if the receiver is an object list, Magic Cap adds the installed object as a new entry in the object list. If the installed object is a task and the receiver is the datebook, the task is added to the datebook's collection.

For other install-receive pairs, Magic Cap takes special action to install the given object. For example, you can specify a scene and the hallway as an install-receive pair. When your package is unpacked and Magic Cap finds a scene-hallway pair, it installs a door in the hallway that takes the user to the installed scene.

Objects to be installed are objects from your package, while receivers are system objects, generally specified with indexicals. Typical install-receive pairs include scenes or entrances and the hallway (iHallway), scenes or entrances and downtown (iDowntown), icons and the desk accessory drawer (iDeskAccessoryWindow), and name cards and the name card file (iNameCardsStack).

For more information on installing objects, see the Packing and Unpacking section of this chapter.

NOTE: Magic Cap defines a separate mechanism, known as scene additions, for installing items that are only available when a particular scene in your package is current. You can use scene additions to install the following kinds of items that appear only when a particular package storeroom scene is current: commands and rules in the Magic Lamp, tools in the tools holder, and stamps in the stamper. For more information, see the Scenes chapter of this book.

Package States

Magic Cap packages go through various state transitions as users work with them, such as the transition from being packed up to being unpacked, or the drastic transition that occurs when the user throws the package away and empties the trash. Some transitions occur very rarely, such as the one that takes place when the user copies a package from a PC card to main memory. Others, like the transition that happens when the communicator shuts off, can happen many times a day. This section describes what happens to your packages when these transitions occur and how you can react appropriately to each situation.

Loading Packages

Magic Cap users can add new packages and remove existing ones. Packages can be stored in various places in memory, as follows:

A package stored in main memory or on a PC card is said to be present in the communicator. As soon as Magic Cap detects the presence of a new package, it loads the package by creating a context and clusters for it and adding its storage box to a storeroom shelf. Magic Cap can execute code on PC cards directly, so users don't have to copy packages to main RAM in order to use them.

When the user receives a package via electronic mail or beam, the package is packed up. When the user puts a package on a RAM card, ejects the card, then reinserts the card, the package remains in the same state it was in (unpacked or packed up) when the card was ejected.

The package remains unpacked or packed up according to the state is was in when created or the last time it was removed from Magic Cap

When a package is loaded for the first time, it can be unpacked or packed up. You can set your package to unpack automatically upon loading. Otherwise, the package will be packed up or unpacked according to its state before it was loaded.

As soon as a package is loaded, its objects can be used by other packages and by Magic Cap, even if the package is packed up. However, users have no way to directly access the objects in a package until it is unpacked. Packages in the communicator's ROM can be copied to RAM or to RAM cards, but can never be removed.

Packing and Unpacking

Virtually all packages provide a way for users to manipulate their contents and perform actions, whether by installing new stamps in the stamper, adding a set of tools, or providing a door in the hallway that leads to a scene. Every package can specify a set of objects to be installed and a set of receivers that will get the objects. When the package is unpacked, Magic Cap installs the objects in their receivers.

You specify the objects to be installed and their receivers in your package's instance definition file. The installList field of the software package object refers to a list of objects to be installed, and the receivers field refers to a corresponding list of objects to receive the installed objects. These two lists are parallel: the items at the same position in the lists form an install-receive pair. The lists are called the install list and the receiver list.

When the package is unpacked, Magic Cap calls InstallInto for every receiver in the receiver list, passing the corresponding install list item as a parameter. The receiver's class installs the object appropriately. For example, class StackOfCards overrides InstallInto to add the install list object to its stack after first checking to make sure that the object is a card. You can create a class that overrides InstallInto if you want it to act as a receiver of install list objects. See the Specifying a Software Package Object section of this chapter for more information.

For more complex installations, some receivers accept parameters to InstallInto to customize the installation process. You can pass parameters to the receiver by using the installFlags and installParameters fields of the software package object.

As each object is installed, the receiver's InstallInto operation calls InstallingInto for the install list object. You can create a class that overrides InstallingInto if you want your objects to be notified just after they've been installed.

Your package isn't notified when it is being unpacked. You can find out when your package is unpacked by including an object of one of your package's classes in the receiver list. Then, when the package is unpacked, Magic Cap will call the package class's InstallInto operation, notifying it that your package is being unpacked.

When the package is packed up, Magic Cap removes the install list items from their receivers. When a package is packed up, any objects it installed are removed from the user's view, but its objects are still loaded and available to Magic Cap and to other packages. The package isn't notified when the install list items are removed. For more information on accessing package objects from another package, see the Interpackage Operability section of this chapter.

Power Off and On

By far the most common transitions for a package are the ones that occur when the communicator's power turns off or on. When the communicator is off, only persistent RAM is powered, maintaining the user's data. Transient RAM isn't powered and its contents are undefined after the communicator shuts off, so you must use special design considerations if you have transient objects in your packages.

When the user turns the communicator on, Magic Cap signals your package by calling Install for every class. You should override Install if you want your class to perform some initialization every time the communicator turns on. Typically, you'll use Install to recreate any transient buffers and other transient objects that are lost when the communicator turns off.

When the user turns the communicator off, or when it goes off automatically after several minutes idle, transient RAM loses power and its contents are lost. During the power-off process, Magic Cap finds persistent objects with fields that refer to objects in transient RAM and changes the fields to nilObject. The user's data in persistent memory, including system clusters and package clusters, is powered even when main power is off and so isn't affected when the communicator turns off.

Any buffers you created with NewTransientBuffer are lost when the communicator powers off. Because you refer to transient buffers with direct pointers, rather than object IDs, Magic Cap won't change the direct pointers, so these pointers will be invalid when power returns.

During the power-off process, Magic Cap also commits changes before turning off, causing objects to move from the package changes cluster in transient RAM to the package shadow cluster in persistent RAM.

When the communicator is about to shut off, Magic Cap calls the current scene's ShutDownScene operation. If your package's scene isn't current, or if the communicator must perform an emergency shutdown due to a sudden loss of power, or the user pushes the reset button, your package isn't notified, so you should design your package with the assumption that the contents of transient RAM could vanish at any time. In these critical cases, the communicator may lose power before the most recent changes in transient RAM can be committed to persistent RAM, causing the changes to be lost.

The next time the user turns the communicator on after an emergency shutdown, Magic Cap will check object fields that refer to other objects, making sure that the fields refer to valid objects in persistent RAM. If any fields are found to have invalid object IDs, they are set to nilObject.

When the user turns the power on, Magic Cap calls Reset for every object in the package source cluster; that is, every object that was specified in the package's instance definition file. Reset is used to notify servers and other objects that manage hardware that the communicator has just powered up. For example, the object that manages the speaker overrides Reset to make sure that any sound object that was being played at power off is deleted when power returns so that it doesn't continue to take up memory after it has been used.

You should override Reset if your class controls a server or other hardware resource that you want to set up when the communicator turns on. Unless you're creating servers or other hardware-controlling software, you'll rarely override the Reset operation. Reset is called after Install when the communicator turns on. You're much more likely to override Install to perform some action when the communicator turns on.

Removing Packages

The user can remove any package that isn't in the communicator's ROM. If the package is in main RAM or on a RAM PC card, the user can throw the package away and empty the trash, destroying the software package and its changes. If the package is on a RAM or ROM PC card, the user can eject the card, unloading the package and removing the package's install list objects from their receivers.

Packages in main RAM and on ROM PC cards store their changes in RAM by default, while packages on RAM PC cards keep their changes on the same card by default. If a RAM PC card is inserted and the user has checked its new items go here option, changes will go on the designated RAM card if the package calls NewPreferred and CopyPreferred to create new objects. If the packages doesn't use these calls, the new objects will go to the default location indicated above.

If the user ejects a PC card containing the package, the package may still have changes in main RAM. In this case, the changes will remain in main RAM, pining for the lost package to return. If the package is loaded again, Magic Cap will connect it with its changes. The package will be packed up or unpacked according to the state it was in when the card was ejected.

Unfortunately, when the package isn't available, Magic Cap provides no easy way for users to delete the package's changes. The only user interface for deleting changes that belong to a missing package is provided when the communicator's memory is completely full and Magic Cap presents a list of objects that can be deleted to recover memory.

When the user inserts a ROM PC card containing a package, Magic Cap keeps the package's changes in persistent clusters in RAM. When the user ejects the card containing the package, the changes clusters remain. When the package reappears, Magic Cap reconnects the changes clusters to the package, effectively restoring the package and its data to the state they were in when the package's card was ejected.

Interpackage Operability

Magic Cap provides interpackage operability features that allow packages to share information. Packages can use these features to implement several kinds of information sharing techniques, including:

This section provides information about how Magic Cap refers to objects that belong to other packages and discusses each kind of interpackage operability.

WARNING: You should never use classes or objects defined by another package unless the author of the other package has provided appropriate information about the shared objects. Using objects from other packages without thorough information can cause severe software problems, including corruption of user data in persistent RAM.

Indirect References

Magic Cap objects are organized into clusters, and every package has a set of clusters that it can access by using object IDs for the objects in those clusters. These clusters and their objects are said to be directly accessible by the package.

Directly accessible clusters are listed in the package's context. The package's context includes system clusters as well as clusters of package objects that are directly accessible to that package only. Magic Cap includes one context for every loaded package as well as a system context that contains only the system clusters.

Because every context includes the system clusters, system objects are directly accessible to every package. Because package clusters only belong to their own contexts, objects that belong to foreign packages are not directly accessible. Instead, Magic Cap defines indirect references that allow packages to refer to objects from foreign packages.

When your package takes some action that refers to an object from another package, Magic Cap creates a system object of class Reference that contains the context and object ID of the foreign object. The ID of the Reference object is then used as an indirect reference to the foreign object. Magic Cap permits indirect references wherever object IDs are allowed, such as in a field of an object that refers to another object. The following diagram shows an example of an indirect reference:

Indirect reference to foreign object

In this example, a box has two subviews, both of which are package-defined subclasses of Stamp. The first subview is an instance of a class defined by the local package, while the second subview is an instance of a class defined by a foreign package. When the first subview refers to the second in its next field, it uses an indirect reference; that is, it refers to a reference object, which in turn refers to the foreign object in the foreign context. Magic Cap uses the indirect reference to get the foreign object automatically.

Creating Objects of Foreign Classes

Your package can create and use objects of a class defined by another package. In order to create objects of foreign classes, your package must know two facts about the foreign package: its citation, an object that identifies the package, and the class number of the desired class. Typically, packages designed to share their classes will document this information. If you're also the author of the foreign package, you can get its citation and class numbers from its source code.

To create the object, you must first get the foreign package's context. You can call FindActiveSoftwarePackageByCitation with the citation object to get the context. FindActiveSoftwarePackageByCitation will return the package's context if the package is loaded, even if the package is packed up. If the package isn't loaded, FindActiveSoftwarePackageByCitation returns nil.

After getting the package's context, you can get a reference to the desired class by calling Import with the foreign context and the desired class number. Import creates and returns an indirect reference to the foreign class. Once you've created this reference to the foreign class, you can use it just as you would a local class.

To make a new object of the class, call any of the standard object-creation operations, such as NewTransient or NewNear. The new object is created in the specified cluster in your package's context, although its class is in a foreign context. Objects created from classes in foreign contexts can be used just as you use objects of classes defined in the current context.

The following example shows the process of getting the foreign package's context, importing the class, and creating a new object:

// Get foreign package context
foreignContext = FindActiveSoftwarePackageByCitation(foreignCitation, -1);

// Create indirect reference to foreign class by importing
importedClassNumber = Import(foreignContext, ForeignClass_);

// Create object of foreign class using indirect reference
foreignObject = NewTransient(importedClassNumber, nil);

The above example assumes that a copy of the foreign package's citation (foreignCitation) is available and that the desired class's number (ForeignClass_) is known. In practice, only packages created by the same author or by authors working in contact with each other would have this intimate knowledge. You should declare the foreign citation in your instance definition file, referring to it from the package root list. The foreign class number is simply a constant, which you can declare in your C source or header file.

If your package contains objects of foreign classes and the foreign package is packed up or unloaded, Magic Cap also packs up your package. If the foreign package is unpacked and your package is then unpacked, the objects of foreign classes will still be present in your package. If your package is unpacked while the foreign package is packed up, the objects of foreign classes will be destroyed and won't return even if the foreign package is unpacked. Magic Cap presents a warning announcement if the user is about to pack up your package and possibly lose foreign objects, but your package isn't notified. If this happens, references to the missing objects will be replaced with nilObject.

Calling Foreign Package Operations

Your package can call operations of a class defined by another package. To call the foreign operations, you must first get the foreign package's context, then the appropriate foreign class, using the techniques explained in the preceding section. Call FindActiveSoftwarePackageByCitation with the foreign package's citation object to get its context, then call Import with the foreign context and desired class number.

Once you have imported the foreign class number, you can call its operations just as you would with objects of local classes, including its operations that create new instances of the class. When you call an operation of any instance of an imported class, Magic Cap temporarily switches the current context to the foreign context.

The object's ID and the IDs of any parameters that are objects are automatically translated to be appropriate for the operation's context. Magic Cap performs this translation as follows:

Because of this automatic translation, you can use the imported object and any parameters inside an operation without having to import or otherwise translate their object IDs.

NOTE: Magic Cap must switch to the foreign context in order to execute operations of the foreign class, so calling foreign operations is much slower than calling operations of classes in the system or in your own package. You may find that your package's performance degrades if you call foreign operations excessively.

Some operations define a parameter block, a structure of type Parameters. Object IDs in parameter blocks, like standard parameters, are also translated automatically to be appropriate for the foreign context when you call an operation of an imported object. After translating any object IDs to be appropriate for the foreign context, Magic Cap switches to the foreign context, executes the operation, then switches back to the current package's context.

If your package includes any operations that use callback functions or otherwise pass function pointers as parameters, such as Each or RunSoon, you may have to explicitly switch the current context to make sure object IDs are handled correctly. For complete information on this subject, see the Contexts and Callback Functions section of this book's Object Runtime chapter. If your package doesn't have any operations that pass function pointers as parameters, you can safely ignore this subject.

NOTE: You can't call intrinsic operations of foreign package classes. Intrinsic operations can only be called from their native context.

All operation names used by your package must be unique, including the imported ones. When you call an operation defined in a foreign class, your package must not define an operation with the same name as an imported one. If your package defines an operation with the same name as an imported one, you'll get an error when you try to build your package.

In addition to calling operations of foreign classes by importing them, you can also switch explicitly to another package context in order to call operations of foreign classes. For more information on the advanced topic of explicit context switching, see the Explicit Context Switching section in this book's Object Runtime chapter.

Importing Foreign Package Objects

You can use statically defined objects of another package - that is, objects defined by a foreign package in its instance definition file. To use an object of another package, the other package must refer to the desired object in its package root list, making it accessible via indexical. Magic Cap designates several package root list positions for objects that are available to other packages.

You must have a copy of the foreign package's citation in order to import an object defined by an indexical in the foreign package. With your copy of the foreign citation, you can call FindActiveSoftwarePackageByCitation to get the foreign context, then call Import to get the desired object. This process is shown in the following example:

// Get foreign package context
foreignContext = FindActiveSoftwarePackageByCitation(foreignCitation, -1);

// Create indirect reference to foreign object by importing
importedObject = Import(foreignContext,iForeignPackageIndexical);

The above example assumes that a copy of the foreign package's citation (foreignCitation) is available. In practice, only packages created by the same author or by authors working in contact with each other would have this intimate knowledge. You should declare the foreign citation in your instance definition file. Note that the indexical for the foreign object (iForeignPackageIndexical) is simply a standard indexical defined in the same way as other indexicals, by declaring the object in an instance definition file and creating the indexical with the MakePackageFlatIndexical or MakePackageIndexical macro in a C source file.

By convention, software packages reserve item 14 in the package root list for specific objects designed to be made available to other packages. These objects can be instances of any class or classes. Package root list item 14 contains a single object or object list that is published for other packages to use. If you want to use objects provided by a foreign package, you should first obtain details from the author of the package about the specific objects that package provides.

Magic Cap designates several other items in the package root list for objects that can be used by other packages. Each of these items is a single object or an object list containing items of a particular class, as follows:

---------------------------------
root list item  description        
---------------------------------
1               text styles        
3               sounds             
5               prototype objects  
7               fonts              
15              images                                  
---------------------------------

Each root list item can refer to a single object or to an object list that contains objects of the specified type. If you want to use objects of these classes provided by the foreign package, you should first obtain details from the author of the package about the specific objects that package provides.

In addition to the root list items meant for particular kinds of objects, Magic Cap reserves root list items 25 and higher for package objects of any kind. Your package can use these items for two purposes: sharing objects with other packages, and providing your package with global runtime access to its own objects defined at build time.

If you want your package to use objects defined by other packages, you'll usually find them in the other package's root list item 14, but the other package might use items 25 and higher for additional objects. As with other forms of sharing objects, you should obtain details from the author of the other package before using its objects.

To provide your own package with runtime access to an object defined at build time, declare the object in your package's instance definition file as usual, then include a reference to the object in the package root list in item 25 or higher and define an indexical for that item. You can then use the indexical to refer to the object in your C source or elsewhere in your instance definition file.

Exporting Information about Package Objects

This section presents some of the same information as the preceding section, Importing Foreign Package Objects, but from a different point of view. While the previous section described how to import objects from other packages, this section discusses how to export objects that your package creates.

You can allow other packages to use any of your package's objects. To allow another package to use your package's objects, you should refer to the objects in your package root list, making them accessible via indexicals. Magic Cap designates several package root list positions for objects that are available to other packages.

Software packages reserve item 14 in the root list for specific objects designed to be made available to other packages. These objects can be instances of any class or classes. Item 14 contains a single object or object list that is published for other packages to use. If you want to make objects available for use by other packages, you should also provide details in your package's documentation about the specific objects your package provides and how to use them properly.

As described in the preceding section, the package root list designates particular items for text styles, sounds, prototype objects, scenes, fonts, and images. Each of these items can be a single object or an object list. If your package contains objects of these classes and you want those objects to be available to other packages, you should list them in the appropriate package root list items and provide information about them in your package's documentation.

In addition to the root list items meant for particular kinds of objects, Magic Cap reserves package root list items 25 and higher for package objects of any kind. Your package can use these items for two purposes: sharing objects with other packages, and providing your package with global runtime access to its own objects defined at build time.

If your package has objects to share with other packages, you'll usually refer to them in package root list item 14, but you can use items 25 and higher for additional objects. To provide runtime access to an object defined at build time, declare the object in your package's instance definition file as usual, then include a reference to the object in the package root list in item 25 or higher and define an indexical for that item. You can then use the indexical to refer to the object in your C source or elsewhere in your instance definition file.

NOTE: Although most of the package root list items described in this section are intended to make your objects available to other packages, some items are required by Magic Cap for your package to function properly. In particular, the object in item 6 determines what scene will appear when the user unpacks your package, and the object in item 15 is displayed in your package's storeroom scene. See the Package Root List section of this chapter for more information.

Creating a Package

This section describes the objects you must include in your instance definition file when you create a new package. The most important object is the software package itself, but there are various other required objects.

Required Objects

When you create a software package, you must declare exactly one member of class SoftwarePackage in your instance definition file. The software package object refers to many other objects, acting as the root of a tree of objects. Taken together, all the objects you specify in the instance definition file form the package in its initial state when the package is loaded by Magic Cap.

If your package defines its own classes, it should also include the following objects that make the objects of the package classes and the package itself available to other packages:

In addition, most packages will include the following objects, referred to by the software package object:

The smallest typical package would contain a software package object, the install and receiver lists, and the objects to be installed. Magic Cap uses citations to keep track of imported objects, and users expect to be able to move objects freely from scene to scene in Magic Cap, even across packages, so every package should also include a citation and the objects it refers to.

VERSION NOTE: In a future draft, this section will contain information on how to create the citation, octet strings and other objects described above. For now, you can find this information in the Citation chapter of Magic Cap Class and Method Reference.

Specifying a Software Package Object

The software package object contains many fields and includes the package root list. This section describes each field of the software package object and each item of the package root list. When you create a software package, you'll probably clone an existing package, including its software package object. You can use this section as a guide to interpreting or changing the values in the software package object's fields.

The first field, length, is inherited from superclass AbstractList and indicates the length of the package root list, which is implemented as an object list at the end of the software package. The length field should always contain 32 for software package objects.

The next four fields, dateCreated, timeCreated, dateModified, and timeModified, are inherited from superclass HasDate. These fields specify the date and time the package was built and the date and time the package was last changed by the user. You should set these fields to zero. ObjectMaker will fill in the correct date and time for the package's creation, and Magic Cap will maintain the fields that specify the date and time for user changes.

The next seven fields are inherited from superclass PackageRootList and help determine what happens when the package is loaded and unpacked. These fields are author, installList, receivers, installFlags, installParameters, installTargets, and autoActivate.

The author field refers to an address card that specifies the author of the package. You should include in your package an address card that specifies you as the author. Magic Cap uses this address card to display the package author's name in the package storeroom scene.

The installList and receivers fields each specify an object list. Each item in the install list is installed into the corresponding item in the receiver list. When the package is unpacked, Magic Cap calls InstallInto on each receiver to perform the installation. You should list in the install list every object you want to install into Magic Cap when your package is unpacked, coupled with its destination in the receiver list.

When the user packs up your package, Magic Cap updates the install and receiver lists by removing any objects it installed that are no longer in your package. These objects may have been thrown away, moved into main memory, or otherwise detached from the package. In addition to removing missing objects from the install and receiver lists, Magic Cap changes these lists to reflect the current state of your package's cards and stacks. If the user has added cards to or removed cards from your stacks, the install and receiver lists will reflect those changes.

For example, if your package installs a card in the name card file with the install and receiver lists and the user deletes that card, Magic Cap removes the card and name card file from the install and receiver lists. Similarly, if the user adds any cards to stacks defined by your package, Magic Cap changes your package's install and receiver lists to include the new cards and stacks.

When the user unpacks your package again, Magic Cap again installs the install list cards into their stacks. For this reason, you should include your package's cards and stacks in the install and receiver lists. In addition, you should list all your package's stacks in root list item 22 (iPackageStacks) so that Magic Cap can maintain the install and receiver lists. When Magic Cap cleans up following an emergency shutdown or other serious error condition and finds a package card that has somehow become disconnected from its package, it uses the stacks in this list to put the card back in its package.

Some receiver classes override InstallInto to allow you to pass parameters when you install into their objects. Classes that override InstallInto can accept parameters that are objects or simple values. The software package object provides the installFlags and installParameters fields for these object and simple value parameters.

The installFlags field refers to a list of 32-bit values, and the installParameters field refers to a list of object IDs (that is, an object list). When the package is unpacked, Magic Cap calls InstallInto on every receiver list item and passes the corresponding entries from the installFlags and installParameters lists. Very few classes take install parameters. Unless you're installing into one of those rare exceptions, you'll set these fields to nilObject in your instance definition files.

The installTargets field determines whether your package's objects are installed in Magic Cap itself or in other packages. You'll usually set this field to nilObject, indicating that you want to install your objects in Magic Cap's system objects. To install into other packages, you must know their citations. Create an object list of citations of the target packages, then set the installTargets field to refer to the list of citations.

Use the autoActivate field to indicate what will happen when the package is loaded. If autoActivate is true when the package is loaded, Magic Cap will unpack the package and perform the action indicated by the gotoActionSelector field (described below). If autoActivate is false when the package is loaded, the package will be packed up when it is loaded.

The rest of the fields in the software package object are defined by class SoftwarePackage itself and provide miscellaneous details about the package, many of them used internally by Magic Cap.

The citation field, as described earlier in this chapter, provides identity information about the package to other packages. Magic Cap uses this information when the user moves objects from one package to another or sends package objects on telecards. You should always include a citation object (and the identifier, telename, and octet string objects it refers to) in your packages and set this field to refer to it.

You can use the publisher field if your package has separate entities for author and publisher. If you want to specify a publisher, include an address card for the publisher and set this field to refer to it. Magic Cap uses this address card to display the package publisher's name in the package storeroom scene.

If you want the author and publisher's name and address information to appear in the name card file, you can provide name cards that contain the author and publisher address cards and install the name cards in the name card file (iNameCardsStack) by using the install and receiver lists.

The next three fields, persistentShadowSize, persistentChangesSize, and transientSize, are all used internally by Magic Cap. You should set them to zero in your instance definition files.

When the user loads a package that has autoActivate set to true, or when the user touches the go to button in the package's scene in the storeroom, Magic Cap uses the gotoActionSelector field to determine where to go. If gotoActionSelector is 1, Magic Cap goes to the package's startup scene, specified in root list item {6,1} (iPackageStartupScene). If gotoActionSelector is 2, Magic Cap goes to the desk and opens the desk accessory drawer. If gotoActionSelector is 3, Magic Cap goes to a system scene specified by the package in root list item 13 (iPackageStartupSystemScene).

You'll usually set gotoActionSelector to 3, showing the system scene that leads to the package. You might want to use 2 if your package installs an icon in the desk accessories drawer. You should avoid setting gotoActionSelector to 1, as many users are confused by the sudden transition directly to the package's startup scene.

Use the hidden field to indicate whether the package appears on the shelf in the storeroom. If you set hidden to true, your package won't appear on the shelf in the unless the user turns on the Show hidden packages rule in the storeroom. You should set hidden to false, unless your package is an accessory to another package and that main package provides a user interface for removing both packages.

If any class in your package overrides Reset, its needsReset field will be set automatically at build time. You should set needsReset to false in your instance definition file, as the build system will set it true if appropriate.

You should set the copyOnActivate and dontDeactivate fields to false in your instance definition files.

The last fields in the software package object are named systemPackageReserved6 through systemPackageReserved16 and are reserved for use in future versions of Magic Cap. These fields are all defined as boolean values. The first two of these fields are used in Magic Cap 1.0, despite their names.

Magic Cap uses systemPackageReserved6 to indicate whether the package has imported any classes from other packages. You should set this field to false. Magic Cap will maintain it as users add or remove objects from other packages.

Some very specialized packages, such as software enhancements that modify Magic Cap classes, are designed to destroy themselves after being loaded and having their objects installed. The systemPackageReserved7 field is used in Magic Cap to indicate whether the package should destroy itself after being loaded. You should set this field to false for your packages.

You should always set the remaining reserved fields, systemPackageReserved8 through systemPackageReserved16, to false.

Package Root List

The package root list is an object list that follows the last field of the software package object. The first 24 items are used by Magic Cap, and the rest are available for your packages. Typically, the package root list contains 32 elements, 24 for Magic Cap and 8 for your package, although it can contain more. The root list items in this section are described roughly in order of their importance. All mentions of the root list in this section refer to the package root list, not the system root list.

Every item in the package root list refers to another object. In some cases, the object in the root list is itself an object list. For many of the root list entries, you can specify either a single object or an object list and Magic Cap will handle both cases appropriately. The description in this section for each root list item mentions whether it works with a single object, an object list, or either.

You can refer to the software package object itself and the package root list with indexical iSoftwarePackage, defined by Magic Cap as package root list item 0.

If your package has a scene, you should refer to it in root list item 6 (iPackageStandardPlaces). Magic Cap goes to this scene when the user starts using your package. If your package has more than one scene, create an object list that refers to all of them, then refer to that object list in root list item 6. The first item in the list of scenes, iPackageStartupScene, is the one Magic Cap goes to when the user starts using your package. Magic Cap 1.0 doesn't use any entries in iPackageStandardPlaces beyond the first one.

If you set the gotoActionSelector field to 3, Magic Cap will go to a system scene when the user unpacks your package or touches the go to button in the package's storeroom scene. You specify the system scene by referring to it in root list item 13. You should set this item to an object that leaves the user one obvious step away from starting your package. Use iHallway, iDowntown, or iDesk for packages with doors in the hallway, buildings downtown, or viewables on the desk, respectively. If you specify a corridor, such as iHallway or iDowntown, Magic Cap will scroll the corridor to show the package's entrance. Root list item 13 should contain a single object, not an object list.

If your package includes any stacks, you should declare an object list that refers to all the stacks of cards in your package, then refer to that object list in root list item 22, iPackageStacks. If your package's cards somehow become disconnected from their stacks following an error condition, Magic Cap uses this item to try to put the cards back where they belong. This item can contain a single stack or an object list of stacks.

If your package includes any scenes or windows, you should provide contents for their information windows. Root list item 9 is a list of objects to be installed in information windows, and item 10 is the corresponding list of scenes and windows for each information object. Each information object in item 9 must be a text object or a viewable. If it is a viewable, it can be the first item in a view chain. When the user opens an information window, the item in the list is displayed inside the window. These items should always be object lists, not single objects.

When the user packs up or unpacks your package, an announcement appears on the screen, as follows:

You can customize either or both of these announcements by providing text objects in root list item 11. Magic Cap uses the text in item 11,1 (iPackageUnpackMessage) as the announcement when the package is unpacked, and the text in item 11,2 (iPackagePackMessage) as the announcement when the package is packed up. To customize either or both announcements, define the text objects that contain the custom text, then define an object list that refers to the text objects. The object list should have two items. Set either entry to nilObject if you're only customizing one. Then, refer to the object list in package root list item 11.

When the user touches your package's storage box in the storeroom, Magic Cap goes to your package's storeroom scene. You can provide information for this scene by referring to a viewable in root list item 12, iPackageAboutInfo. When the user touches the circled question mark at the left edge of the name bar, an information window appears with this viewable inside. This item should contain a single object, not an object list.

You can provide a book or other viewable that contains instructions for using your package. If your package includes a book or other instructive object, you can refer to it in root list item 17, iPackageGuideBook, which makes a guide button appear in the package's storeroom scene. When the user touches guide, Magic Cap calls GoTo on root list item 17. Although most guides are books, your package's guide can be any viewable that implements the GoTo operation, such as a card or scene. This item should contain a single object, not an object list.

Your package can provide a direct way for users to send you a telecard to register their software, request information, or provide comments. If your package includes an object of class Stationery, you can refer to it in root list item 19, iPackageStationery, which makes a respond button appear in the package's storeroom scene. When the user touches respond, Magic Cap calls CreateResponse on root list item 19. This item should contain a single object, not an object list.

You can provide a scene or other viewable that contains information about the people who made the package. If your package includes a scene with credit information or other similar viewable object, you can refer to it in root list item 18, iPackageCreditsScene, which makes a credits button appear in the package's storeroom scene. When the user touches credits, Magic Cap calls GoTo on root list item 18. Although most credits displays are scenes, your package's credits display can be any viewable that defines the GoTo operation, such as a card or book. This item should contain a single object, not an object list.

Root list item 15 refers to a single image. The image, iPackageLogo, is shown in the package's storeroom scene. If you provide a list of images in this item, Magic Cap ignores all but the first item.

You can use root list item 14 (iPackagePublicObjects) for general objects that you want to share with other packages. Magic Cap doesn't use this item or treat it specially in any way. It's simply designated by convention for general objects to be shared. If your package defines any objects that you want to share with other packages, you can refer to them in this item. This root list item can contain a single object or an list of objects. If you don't want your package to share objects, set this root list item to nilObject.

Magic Cap defines several root list items for specific types of objects: items 1 (iPackageTextStyles), 3 (iPackageSounds), 5 (iPackagePrototypes), 7 (iPackageFonts), and 15 (iPackageImages). Magic Cap itself never uses these items, and they aren't treated specially in any way. They are simply designated by convention for particular kinds of objects to be shared. If your package defines any objects of these classes and you want to share them with other packages, you can refer to them in these items. Each item can contain a single object or a list of objects of the specified class. If you don't want your package to share these kinds of objects, set these root list items to nilObject.

Root list items 25 through 32 are reserved for use by packages. You can use these items for objects defined at build time that your package must refer to at runtime, additional objects to be made available to other packages, or any other use.

The following figure shows the package's storeroom scene and indicates the source for each item in the scene.

Storeroom scene with sources of information

The remaining root list items are used internally by Magic Cap or rarely.

Root list item 8 is iPackageNumbers, miscellaneous values used by Magic Cap. You should set this field to nilObject in your instance definition file.

Root list item 2, iPackageColors, is used for the package's color objects. Most Magic Cap objects that use color, such as viewables, use simple values rather than objects to specify their colors. The classes that use color objects are shadows, text styles, line styles, and color coupons. You'll probably set this item to nilObject.

Root list item 4, iPackageBackupMemoryStream, is reserved for use by backup packages created by Magic Cap. You should set this field to nilObject.

Two root list items are reserved for future use by Magic Cap. These are items 16 (iPackageAboutWindow) and 20 (iPackageInterchangeList). You should set these items to nilObject.

Indexicals

In addition to all the package indexicals defined for items in the package root list, as described in the preceding section Package Root List, Magic Cap provides several indexicals that contain useful objects related to packages. You can use iNameBarPackage to get the tiny image of a storage box that is placed in the name bar to show that a card or other object belongs to a package is. You can read iPackageScene to get the scene used by Magic Cap for a package's storeroom scene.

You can get or change iResetPackagePrompt, which contains the text that appears in an announcement when the user touches the delete changes button in the Magic Lamp.

When the user mails a package by touching the mail button in the Magic Lamp in the package's storeroom scene, Magic Cap creates a new telecard from iSendPackageStationery to enclose the package. When the user beams the package, Magic Cap uses iBeamPackageStationery to create the telecard. You can read or change these objects by using the indexicals.

Reference

For more information, see these topics in Magic Cap Class and Method Reference:

class SoftwarePackage

fields:

author
autoActivate
citation
copyOnActivate
dateCreated
dateModified
dontDeactivate
dontSaveData
gotoActionSelector
hidden
installFlags
installList
installParameters
installTargets
length
needsReset
persistentChangesSize
persistentShadowSize
publisher
receivers
systemPackageReserved6
systemPackageReserved7
timeCreated
timeModified
transientSize

class PackageContext

operations and attributes:

FindActiveSoftwarePackageByCitation
Import

class Object

operations and attributes:

CopyPreferred
Each
EachElem
Install
InstallingInto
InstallInto
NewPreferred
Reset

class Citation

class Identifier

class Telename

class OctetString

class Reference

class Stationery

operations and attributes:

CreateResponse

class AddressCard

system indexicals:

iBeamPackageStationery
iDesk
iDeskAccessoryWindow
iDowntown
iHallway
iNameBarPackage
iNameCardsStack
iPackageScene
iResetPackagePrompt
iSendPackageStationery
iSystemPackageScene

package indexicals:

iPackageAboutInfo
iPackageAboutWindow
iPackageBackupMemoryStream
iPackageChangesName
iPackageColors
iPackageCreditsScene
iPackageFonts
iPackageGuideBook
iPackageHelpOnObjects
iPackageImages
iPackageImportCitations
iPackageImportObjects
iPackageImports
iPackageInterchangeList
iPackageLogo
iPackageNumbers
iPackageObjectReferenceNumbers
iPackageObjectsWithHelp
iPackagePackMessage
iPackagePatchNumber
iPackagePrototypes
iPackagePublicObjects
iPackageSounds
iPackageStacks
iPackageStandardPlaces
iPackageStartupScene
iPackageStartupSystemScene
iPackageStationery
iPackageText
iPackageTextStyles
iPackageUnpackMessage
iSoftwarePackage

Book Contents          Previous Chapter          Next Chapter