In Magic Cap 1.x, positive integers were used as identifiers for lightweight exceptions. Because References cab use the same values, this will no longer be true in Rosemary. Instead, indexicals will be used as exception values. Since exceptions are often handled by displaying a particular announcement, using the announcement indexical as the exception value is a nice simplification.The exception constants defined in the Exceptions.h file are now indexicals. The indexical names simply prepend an "i" to the existing exception name.
Current versions of Magic Cap restrict how objects' extra data can be used: only one class in a class hierarchy can use the extra data portion of object instances. The Rosemary release of Magic Cap relieves this restriction with the concept of shared extra data.A class that uses the extra data portion of instances, but also wants to allow subclasses to store their own extra data declares the fact in the class definition with the shares extra keyword. The class should also override ExtraUsedBySuperclasses() so that subclasses can find out how much of the extra data space this class is using. Subclasses can than use the result from this method as an offset to get to their portion of the extra data space.
A subclass of this class that also wishes to use the extra data portion of instances declares this fact with the uses shared extra keyword in its class definition. The subclass can call ExtraUsedBySuperclass() to deterime how much of the extra data is owned by a superclass. If this subclass also overrides ExtraUsedBySuperclass() so that subclasses of it can use space in the extra data portion, InheritedExtraUsedBySuperclass() should be used to find the how much of the extra data belongs to superclasses.
The Rosemary version of Magic Cap uses this feature to implement the new viewable format. The list of subviews are maintained in a viewable's extra data portion. However, certain subclasses of class Viewable also use the extra data portion of object instances for their own purposes. A prime example of this is class Card, which stores form item data in the extra data portion of card instances. Class Viewable declares shares extra and class Card declares uses shared extra so that both classes have access to the extra data.
The shared extra data model gives you greater flexibility in how your package classes can use the extra data portion of object instances. Because certain system classes now use extra data that didn't before -- like Viewable -- you might need to re-declare how some of your package classes use extra data. If your package implements a Viewable subclass that uses extra data, you'll need to change the class definition and possibly some methods to account for the fact that not all the extra data in an instance belongs to your subclass.
In Magic Cap 1.x, code iterates through the extra data portion of objects with the EachExtraField() operation. A class that uses extra data for anything other than raw bytes needs to override this operation to define the structure within the extra data. Because Magic Cap runs on both big endian and little endian chip architectures, classes that use extra data must also implement byte swapping functionality in EachExtraField(). This means that the code for that class has to be present in order to read the extra data in instances. If a package class defines a custom extra data format, instances of that class are rendered unusable when that package goes away. (Considering that packages usually live on removable PC cards, this is a serious problem.) Furthermore, if the package is not present, Magic Cap itself would be unable to perform garbage collection on these objects.
Rosemary defines a standard format for extra data, so it will no longer be necessary to implement custom operations in order to iterate over extra data. Structured data is stored in extra data as lists. This extra list can contain only one data type; it is illegal to mix bytes, shorts, longs, strong object references, weak object references, class numbers, operation numbers, etc. in the extra data of a single object. Structured data is automatically byte swapped to compensate for the endian-ness of the underlying chip architecture. Use the uses extra list keyword in class definitions to specify that a class has structured extra data. Unstructured data represents a stream of byte-length data. Unstructured data is not automatically byte swapped. It is illegal to store object or class references in unstructured extra data. Use the uses extra or shares extra keywords in a class definition to specify that a class has unstructured extra data.
If an object's extra data is structured, the first word of extra data contains the count of list entries, with the word format in the high byte. Any additional extra data is unstructured. If extra data space is shared between classes, subclasses are restricted in how they can use their portion of extra data. If a base class that declares it can share the extra data space has unstructured extra data, subclasses are only allowed to have unstructured extra data. If the base class has both structured and unstructured extra data, subclasses are still restricted to only unstructured data unless the base class makes special provisions to share the extra list area as well. Class Viewable does this so that cards can store text styles in the extra list and form data as unstructured data.
If a base class that shares the extra data space has structured extra data, subclasses can only store the same type of data in the extra list as the base class. This restriction might mean that some classes that used to use extra data can no longer use extra data. GridView is an example of a Magic Cap class that had to change because of this restriction. In Magic Cap 1.x, GridView stores column information entries in extra data:
typedef struct { Micron offset; UnsignedShort type; UnsignedShort flags; } ColumnInfo;In Rosemary, the class definition for GridView would declare uses extra list to store these structures as extra data. However, class Viewable already declares that it uses the extra list to store strong object references to subviews. Since the extra list of an object can contain only one data type, GridView cannot use extra data to store the column information. GridView now defines fixed fields that have lists for each field of the column information struct.Because the extra list an contain only one type of data, different list classes are needed to contain different types of data. Magic Cap provides several of these classes: ByteList, ShortIntegerList, IntegerList, ObjectList, OperationNumberList, ClassOperationNumberList and IntrinsicNumberList. These are all subclasses of FixedList, which is an abstract class in Rosemary. Each class stores the format it works with in the high byte of the first word of extra data word. The data in these extra lists are automatically byte swapped as needed. You will most likely subclass or instantiate from one of these classes instead of subclassing FixedList directly. If your data size is different than that provided by one of these classes, you can subclass FixedList and override Stride() to specify the size of a list entry.
It is illegal to mix object references with non references in an extra list. For example, you cannot define a FixedList subclass that stores a struct like this:
typedef struct { ObjectID reference; Unsigned nonReference; } IllegalExtraData;The syntax for declaring extra lists in class definitions is discussed in the ObjectMaker section of this document.You can use the Object_ExtraFormat operation to determine whether or not the extra data of an object contains Magic Cap references, such as class numbers, operation numbers, etc. There are many routines that allow you to find out information about the format of data in structured lists. These are discussed in the Lists section of this document.
Card extra data is used to hold the data that will be displayed by objects on the form associated with a card. In Magic Cap 1.x, the object source for card extra data is formatted as raw hex data. Unless you can convert hex to ASCII in your head, this meant that you had to run Magic Cap to view the form data associated with a card. In this release of Magic Cap, the object compiler and simulator have been changed to use a more human readable format when compiling and dumping card extra data.
Form data is described in fields whose sequence and naming conventions are defined by the object compiler. There are two kinds of fields: object references made from form items, and other form item data. Object references are listed in separate fields, one per reference, other data in a single field per form item. Field names start with "formItem", followed by the item number, followed by either "Object" and the object reference number or "Data". Examples are formItem1Data, formItem2Object1.
Fields are grouped by form item, references first, other data last. If there is no data for a form item, the data field is omitted.
If the data for a form item is text, it can be written as a string. Other data is written in hexadecimal format.
Form data header information is no longer provided in the source code, but calculated by the object compiler.
This example shows how the standard text format can be used for form data, and the form data header no longer needs to be provided. There are two form items in this example, both TextFields, but data is provided for only the first one. The last one doesn't even receive a length byte.
Form item list:
instance ObjectList unnamed5831; entry1: (TextField unnamed5819); entry2: (TextField unnamed5821); end instance;
instance definition in old syntax:
instance LessonCard aboutTheseLessons 'About these lessons'; <regular fields and subviews omitted> header1: $ 14; data1: $ 486F 7720 746F 2075 7365 2074 6869 7320 626F 6F6B; end instance;
instance definition in new syntax:
instance LessonCard aboutTheseLessons 'About these lessons'; <regular fields and subviews omitted> formItem1Data: 'How to use this book'; end instance;
In the old syntax, data for several form items could be lumped together into one block of extra data. The new syntax requires breaking them into separate fields.
Form item list:
isnstance ObjectList unnamed5831; entry1: (TextField unnamed5819); entry2: (TextField unnamed5821); end instance;
instance definition in old syntax:
instance Card unnamed5811 AboutToShow: (script lessonsLastPageScript); <regular fields and subviews omitted> data: $ 0F43 6F6E 6772 6174 756C 6174 696F 6E73 6C59 6F75 2068 6176 6520 6669 6E69 7368 $ 6564 2073 6574 7469 6E67 2075 7020 796F 7572 2063 6F6D 6D75 6E69 6361 746F 722E $ 2049 7481 2019 7320 7265 6164 7920 746F 2068 656C 7020 796F 7520 636F 6D6D 756E $ 6963 6174 6520 616E 6420 6761 7468 6572 2069 6E66 6F72 6D61 7469 6F6E $ 2E; end instance;
instance definition in new syntax:
instance Card unnamed5811 AboutToShow: (script lessonsLastPageScript); <regular fields and subviews omitted> formItem1Data: 'Congratulations'; formItem2Data: 'You have finished setting up your communicator. ' 'It\x2019s ready to help you communicate and gather information.'; end instance;
In this example, source text in the old syntax needs a more complicated format 2 header because the text of item 2 is larger then 127 bytes. In the new syntax, source text is not affected by this implementation detail.
Form item list:
instance ObjectList unnamed5831; entry1: (TextField unnamed5819); entry2: (TextField unnamed5821); end instance;
instance definition in old syntax:
isntance Card unnamed5787 AboutToShow: (script lessonsFirstPageScript); <regular fields and subviews omitted> header1: $ 22; data1: $ 4765 7474 696E 6720 5374 6172 7465 640A 616E 6420 5065 7273 6F6E 616C 697A 696E $ 6720; header2: $ 8000 0000 D5; data2: $ 5468 6573 6520 696E 7374 7275 6374 696F 6E73 2065 7870 6C61 696E 2073 6F6D 6520 $ 6261 7369 6320 6665 6174 7572 6573 2061 6E64 206C 6574 2079 6F75 2070 6572 736F $ 6E61 6C69 7A65 2079 6F75 7220 636F 6D6D 756E 6963 6174 6F72 2E20 5468 6520 7365 $ 7475 7020 696E 666F 726D 6174 696F 6E20 796F 7520 656E 7465 7220 6865 7265 2077 $ 696C 6C20 6265 2073 6176 6564 2073 6F20 796F 7520 6361 6E20 7573 6520 6974 206C $ 6174 6572 2E20 0A0A 546F 7563 6820 7468 6520 7061 6765 2063 6F72 6E65 7220 6162 $ 6F76 6520 746F 2074 7572 6E20 7468 6520 7061 6765 2E; end instance;
instance definition in new syntax:
instance Card unnamed5787 AboutToShow: (script lessonsFirstPageScript); // 'Welcome To Magic' <regular fields and subviews omitted> formItem1Data: 'Getting Started\nand Personalizing'; formItem2Data: 'These instructions explain some basic features and let you ' 'personalize your communicator. The setup information you enter ' 'here will be saved so you can use it later.\n\n' 'Touch the page corner above to turn the page.'; end instance;
In the old syntax, form items that don't receive data (skipped items) are indicated by a modified header for the following item. With the new syntax, the object compiler recognizes skipped items by interpreting the field names, and creates the modified header automatically.
Form item list:
instance ObjectList unnamed861; entry: nilObject; entry: (BodyField unnamed1245); end instance;
instance definition in old syntax:
instance Telecard unnamed769; <regular fields and subviews omitted> header2: $ 93; data2: $ 4465 6172 202F 6669 7273 7420 6E61 6D65 2F2C $ 0A; end instance;
instance definition in new syntax:
instance Telecard unnamed769; <regular fields and subviews omitted> formItem2Data: 'Dear /first name/,\n'; end instance;
The simulator and object compiler use the new formatting for the extra data in Text objects as well, allowing styled text to be dumped in a human readable format. The string format has been extended by new escape codes to denote style references in text: "\1" through "\9" are used to reference styles one through nine in the style table of the Text object.
This example shows how styled text is represented in the new syntax. It also shows how hex data encourages errors--of the five text styles listed as object references, only one is actually used in the text.
Form item list:
instance ObjectList unnamed8087; entry: nilObject; entry: (BodyField unnamed8082); end instance;
instance definition in old syntax:
instance SignupCard unnamed1169; <regular fields and subviews omitted> object1: (TextStyle unnamed1170); object2: (TextStyle unnamed1171); object3: (TextStyle unnamed1172); object4: (TextStyle unnamed1173); object5: (TextStyle unnamed1174); objectCount: 5; header2: $ 8005 0100 A2; data2: $ C145 6E68 616E 6365 6D65 6E74 2053 6572 7669 6365 C00A 0A53 656E 6420 7468 6973 $ 2063 6172 6420 746F 2073 6967 6E20 7570 2066 6F72 2073 6F66 7477 6172 6520 7570 $ 6772 6164 6573 2E20 4F6E 6365 2079 6F75 2073 6967 6E20 7570 2C20 796F 7581 2019 $ 6C6C 2067 6574 2073 6F66 7477 6172 6520 656E 6861 6E63 656D 656E 7473 2074 6872 $ 6F75 6768 2074 6865 2041 5426 5420 5065 7273 6F6E 614C 696E 6B20 7365 7276 6963 $ 652E; end instance;
instance definition in new syntax:
instance SignupCard unnamed1169; <regular fields and subviews omitted> formItem2Object1: (TextStyle unnamed1170); formItem2Data: '\1Enhancement Service\0\nSend this card to sign up for ' 'software upgrades. Once you sign up, you\x2019ll get software ' 'enhancements through the AT&T PersonaLink service.'; end instance;