ObjectMaker

In Magic Cap 1.x, ObjectMaker was the tool that compiled class definitions into C header files, and compiled object definitions into a partial source cluster image. The Rosemary development environment splits the functionality of ObjectMaker into two distinct tools, the class compiler and the object compiler. The current naming convention uses the .Def extension to identify both class definition and object definition files. Rosemary uses a new convention. Class definition files are denoted by the .cdef extension while object definition files are denoted by the .odef extension.

The class and object compilers now require class header information to be included to be able to compile class definitions, and to create class instances. For any class you inherit from, instantiate, or use as a type, you must include a corresponding read statement for that class definition in your class and object definition files.

        read "<class definition file>";
Typically, you would include "MagicCap.cdef", which contains information about system classes, followed by any class definition files you've created for your package.

Additionally, all code files must include the header files generated by the class compiler for all the classes mentioned in the code file. These new headers come in two flavors: public headers (of the form ClassFileName.xh) and private headers (of the form ClassFileName.xph). If your code calls the method of a class, it needs to include the public header. If it accesses the fields of a class directly, it needs to include the private header. Code files that contain the implentation of a class also needs its private header. If you use an indexical in a code file, you need to include the public header for the class definition file where the indexical is declared. These header files replace the Package.h include file from Magic Cap 1.x.

Indexicals are now declared in class definition files and defined in object definition files. Object fields that refer to an indexical must use the symbolic name to specify that indexical. The object compiler will flag indexicals specified in the {x,y} format as errors. The Magic Cap simulator has been modified to dump the symbolic name for indexicals. Refer to the section on indexicals for information about the new syntax.

The Rosemary object compiler tool uses a new instance definition syntax. The optional name now follows the identifier tag instead of preceeding it:

        instance <class> <identifier> [name]

Instead of a meaningless instance definition number, you must now identify object instances with arbitrary (albeit meaningful) symbolic names:

old style:

        instance NotebookScene 516 'Notebook';
new style:
        instance NotebookScene scene 'Notebook';
With the old numerical style of identifying object instances, the simulator might sometimes renumber instances during dumping. The new identification scheme avoids this problem. When an object that was created at runtime is dumped, it will be dumped with a generated "unnamedn" tag. Numeric tags are no longer supported.

When referencing an instance that was defined with a symbolic tag, the object name is no longer specified:

        superview: (Scene deskScene);           // preferred
        superview: (Scene 'Desk' 123);          // obsolete
        superview: (Scene 123);                 // illegal
        superview: (Scene 'Desk' deskScene);    // not allowed
Symbolic tags are separated into namespaces, so that different sets of objects can use the same tag but still be able to refer to objects in other sets without conflicts. Namespaces are declared with the namespace keyword in your object definition files. The namespace keyword can be used multiple times in a single file to switch between namespaces.

The tag for the SoftwarePackageContents object must be "contents" for the linker to be able build your package. Additionally, the SoftwarePackageContents object must live in the Main namespace. You can do this by either not declaring a namespace with the namespace keyword, or using the namespace keyword to switch back to the Main namespace, declare the SoftwarePackageContents object, then use the namespace keyword again to switch back to a different namespace.

The class compiler provides the syntax to declare that classes have structured extra data. Structured data is stored as a list in extra data. This is called the extra list. To declare that a class keeps structured extra data, use the uses extra list keyword:

define class Viewable;
    abstract;
	uses extra list: Object;
	...
end class;
This specifies that extra list entries will be strong object references. You can specify any class name or any data type that is defined in Types.Def. You can declare that the class stores weak object references by adding , weak at the end of the uses extra list declaration. Specifying a class or data type is optional, but doing so lets the class compiler enforce type checking on instances of this class in your object definition file.

The class compiler defines new keywords to declare public interfaces, and to import interfaces published by another package. This syntax is required to support the dynamic linking feature in the new runtime. The define interface keyword is used to define a package's public interface. It is similar to the existing define class keyword, but is used to list all classes, operations, intrinsics and indexicals that are available for use by other packages.

The import keyword is used to import an interface published by another package. There are two methods to use the import keyword. The first method defines a strong dependency between two packages; if the interface to be imported does not exist in the system, the importing package will not be activated, and a package-defined message is displayed:

import ArrangerInterface or say iCantFindArrangerInterface;
The second method defines a weak dependency between two packages. If the interface to be imported does not exist in the system, the importing package is still activated, but now it is responsible for making sure that the imported interface is present before it is used:
weakly import ArrangerInterface;
Added the sharedSetter keyword. This is an auto-setter variant that stores a shared copy of the object that's passed.

The "Telescript predefined" keyword is no longer supported by the class compiler.

The class compiler has been made case sensitive. All keywords must be lowercase only.

The class compiler no longer supports the inherits implementation from syntax. This syntax was used to allow classes to "privately" inherit the implementation of another class without making the interface to the implementation available to subclasses.

The noCopy keyword has been replaced with weak. The class compiler no longer supports the telescript safe statement. The safe keyword is obsolete and its use results in an error. The common, sealed and scriptable keywords are also ignored.

Because the new runtime does not support class globals, it is a compile time error to declare a global in class definition files.

The class compiler used to have a problem where it was possible to inherit from the same mixin twice. This is no longer possible. The single case where this occured in the system was class Linkable, which inherited from HasIterator twice. This was resolved by getting rid of HasIterator as a superclass of SingleLinkable.

The implementation/interface relationship between fields and attributes is now more strictly encforced. If you specify getter and setter features on a field, you must supply an attribute interface for that field.

The object compiler now computes the length field of instances of various list classes. The length field should not be specified for instances of subclasses of ObjectList, FixedList, ClassNumberList or OperationNumberList. The list length for subclasses of FixedList is actually stored in a special word between the fixed and extra data portions of the object now instead of in a length field. The section on lists discusses this change in more detail. As part of this change, the keyword uses extra list has been added to the class compiler. Right now, this keyword does nothing. In later versions, this keyword will be used to control the type of data in lists.

The object compiler no longer supports Pascal style strings, or the \p syntax. Extra data cannot be expressed as characters except in instances of Text, StringList and OctetString. The object compiler no longer supports the ".w" field extension extension. Use .s instead. The line continuation character "\" has always been vestigial; you never actually needed to specify it, but the simulator included it in object dumps. The object compiler no longer requires or recognizes a line continuation character. The use of micron coordinates between "<>" is obsolete; pixel coordinates should be used instead. (Micron coordinates were the <0,0> variety; pixel coordinates are specified as <0.0,0.0>.)

The object compiler now allows inline declarations of text objects. If a field refers to object of class Text, HasText or Object, you can specify the text directly on that field instead of referring to a specific Text object. The object compiler does the work of creating the text object for you. The new text object will have a tag that is based on the name of the object field if you put a single-quoted string in for the value of the field.

instance Rule trashEnabledRule;
      ruleFlags: 0x40C00000;
   ruleTemplate: (RuleTemplate unnamed8268);
    ruleTrigger: nilObject;
    description: 'Only keep the last 6 items put in the trash.';
     ruleAction: (LocalRuleAction unnamed8273);
  ruleQualifier: nilObject;
end instance;
Scripts are attached to objects with a new syntax:

    instance <class> <tag> [<name>] <triggerOperation>: (script <scriptTag>);
The <triggerOperation> is the operation that the script overrides, that used to be specified in the initial on statement in 1.x MagicScripts. This will usually be Action.

The escape code used to specify a Unicode character in a text run has been changed. Use "\u" instead of "\x", which is no longer supported.

Card and Text extra data is now dumped in a human readable format by the simulator. The object compiler only recognizes the new syntax for extra data for these objects. Existing object sources that use raw hex representations of extra data for cards and text objects must be redumped with the simulator to convert the extra data into the new syntax.

Instances of classes that are normally shared can be specified as being a non-shared version in object definition files. Similarly, instances of classes that are normally non-shared can be specified as being a shared version. This is done with new attribute specifiers at the end of an object definition. The syntax for an object definition now looks like this:


instance <classname> <tag> ['<objectName>'] [<scriptTag>] [, shared|nonShared];

Out of memory window

Rosemary improves the interface for the "Suggestions for discarding" scene and the "Completely out of memory" window. Suggestions for discarding are added to the lists as they are found, so users no longer need to wait for the entire scavenging operation to complete before they can manipulate discardable items. The underlying framework for finding and displaying discardable items has been consolidated from various places in the system.

The "Suggestions for discarding" scene features two new buttons. The "list" button is used to initiate a fast search for recommended discardable items. Tapping the "more" button starts a slower, more thorough search for discardable items. The "file" button can now file multiple checked items.

The mixin class CanOfferPurgingSuggestions defines the API that should be implemented by classes that can add items to the "suggestions for discarding" list. The 1.x method Object_AddToUserPurgeList has been moved to this class and renamed SearchForSuggestions(). System classes that used to override AddToUserPurgeList() now mix in with CanOfferPurgingSuggestions and override SearchForSuggestions().

Made MakeSuggestionsForDiscarding(), SearchForSuggestions(), FindOldTasks(), SearchForSuggestionsByDate(), ConsiderPurgingEnclosures(), AddLargeCards(), AddSuggestionsFromPurger(), DestroyWillFreeMemory() and ConsiderPurging() pass a ContainerDevice instead of an obsolete metacluster number.

The mixin class CanShowPurgingSuggestions defines the interface for classes that can display the user interface for a suggestions for discarding list. Rosemary has two such interfaces: the "Suggestions for discarding" scene and the "Completely out of memory" window. The existing mixin PurgesDaily now inherits from CanOfferPurgingSuggestions.

Created a new mixin class, PurgeableItemsProxy, to represent items that can go into the suggestions for discarding list. PurgeableContents now inherits from this mixin. PurgeableItemsProxy defines two methods. DestroyKeepContents(), which used to be defined by PurgeableContents, is used to specify that the proxy should be destroyed, but the contents of the container should not be. PurgeableItemsProxy defines this as noMethod, so subclasses must implement it. The second method, RepresentsSameContents(), is called by the purging suggestion framework to determine if an item already exists in the suggestions list. The default implementation calls IsEqual(). Override this method to implement a different matching algorithm.

Changed the name of the field PurgeableContents_containerObject to purgeableContainer, and made a read only auto-getter attribute to access it with.

The class PurgingWindow offers up a list of discardable items. The out of memory window inherits from this class.

Moved DestroyContents() from Object to ObjectList, since it was never called in anything other than object lists.

Moved DestroyContentsInSystem() from Object to StorageContainer, and renamed it DestroySystemStorageContents() for clarity. It is only used when dragging a SystemStorageBox to the trash. Eliminated overrides that don't inherit from StorageContainer.

Renamed PurgesDaily_FillPurgeList to SearchForSuggestionsByDate().

Renamed class UserPurgeListScene to PurgingScene.

Renamed the operation DestroyOrForget() to Eliminate.

Cleaned up the way that the phrases describing where viewables are in the suggestions for discarding list and the search results list are constructed. Some of these cleanups were inspired by localization concerns, others by the lack of class names at runtime in the new world, and still others by bugs.

Removed the obsolete indexicals iSinglePurgeableTemplate and iPluralPurgeableTemplate. Added new indexicals, iClassesWithDescriptions, iSingularClassDescriptions and iPluralClassDescriptions. Added the operations Object_ClassDescription and Object_PluralClassDescription. By default, these operations return "items". Subclasses can override these methods and return a more appropriate string.

Viewable_LocationDescription now implements these operations instead of using the now defunct EnglishPluralNounHack().

Removed field PurgeableContents_containerContext and changed unsigned field PurgeableContents_containerObjectNumber into object field PurgeableContents_containerObject.

Classes affected by these changes

BrowsingListViewScene new
CanOffserPurgingSuggestions
CanShowCompletePurgingList new
CanShowPurgingSuggestions new
Datebook
FilteredListView obsolete
FolderTray
LowMemoryWindow obsolete
MailStack
NotebookScene
OutOfMemoryWindow new
PhoneScene
PurgeableContents
PurgeableItemsProxy new
PurgeableSubviews new
PurgeableTaskViewEnclosures new
PurgesDaily new
PurgingScene new
PurgingWindow new
Screen
StorageContainer
StoreroomShelf
SuggestionFilingList new
SuggestionsTextMapping new
System
SystemStorageBox
TaskView