previous chapter chapter"> contents
page top
page next chapter chapter">

Object

April 5, 1992last updated February 14, 1995

Defined in Object.Def 

Class Description

Class Object provides the fundamental behavior that all objects share. You never create or use any objects of this class. Instead, you use objects that are instances of subclasses of Object. Most other classes in Magic Cap are subclasses of Object.

Many methods of class Object are empty; they're placeholders for features that are implemented when subclasses override these methods.

Remember that if the documentation and the software (especially the definition files) disagree, always trust the software.


Version note: This chapter is in mid-revision. Some of the method descriptions are shiny, new, and truthful. Others are old and moldy.


Using an Object

You'll never create any objects of class Object, and this class doesn't define any fields.

Programming Information

Instantiate: never
Subclass: rarely
Call its methods: often

The Object class provides the fundamental behavior for most objects in the system. Most other classes are subclasses of Object. Although class Object is an abstract class, so you'll never create or encounter any instances of this class, you will often use its methods while interacting with instances of other classes.

When you want to create a new class, you'll probably create a subclass of one of the many built-in subclasses of Object, rather than creating a subclass of Object directly.

Methods you might call

Class Object defines many methods. This section lists all of the methods of class Object together with brief descriptions of what the methods do. The methods are grouped by their general function. The groupings are:

  • Identity and locationpage 360
  • Interface to classes, attributes, and methodspage 361
  • Fields, sizes, and memory usepage 361
  • Manipulating extra datapage 362
  • Creating and destroying objectspage 362
  • Manipulating object namespage 363
  • Comparing objectspage 364
  • Getting text attributespage 364
  • Initializing classes and their globalspage 364
  • Packingpage 365
  • Observing and notifyingpage 364
  • Manipulating locked bufferspage 364
  • Iterating through field and object referencespage 365
  • Filingpage 365
  • Cleaningpage 365
  • Filingpage 365
  • Scriptingpage 366
  • Sending and arrivingpage 366
  • Debugging and testingpage 366
  • Telescript supportpage 367
  • Managing low memorypage 368
  • Icons and other kinds of content informationpage 368
  • Mailing an objectpage 368
  • Digestpage 368
  • System cachespage 368
  • System internal usepage 369

    Methods that you are likely to call or override are described in detail in the Method Descriptions section of this chapter. Methods appear in alphabetical order in that section.

    Identity and location

    The following methods give information about an object's identity and location:

    Method Description
    HasObject Find out if an object ID has an object behind it
    Import Translate an object ID from one context to another after switching contexts
    MakeUsable Change a storable object ID (from an object or buffer) into a usable ID (for dispatching and accessing)
    MakeStorable Change a usable ID (in local variables for example) into a storable object ID (to be stored in an object or buffer)
    DirectID Translate an indexical into the object it points to
    ShallowDirectID Get the value of an indexical
    IsIndexical Find out if an object ID is an indexical (including references to package indexicals)
    SetIndexical Change the value of an indexical
    Near Find out if one object is near another (in the same cluster)
    NearSystem Find out if an object is in the system
    NearPackage Find out if an object is in any package
    NearPersistent Find out if an object is in persistent storage
    NearTransient Find out if an object is in transient storage
    Context Get the context of an object
    FindReference Get the reference, given an object
    ReferenceClassNumber Called by the system to decide what kind of reference to make for an object
    SetUpParameters Prepare a Parameters structure (must call before passing to any routine that takes Parameters)
    PushImportParameters Import parameters after switching contexts (context is switched automatically by dispatching to a package object)
    PopImportParameters Return parameters to their previous state after PushImportParameters

    Interface to classes, attributes, and methods

    The following methods provide an interface to an object's class, its attributes, and its methods:

    Method Description
    ClassNumber Get the class number of an object's class
    Class Get an object's class
    UnscriptedClass Get an object's class, skipping the class made to hold a script for scripted objects
    Implements Check if an object is a member of a class (its class is an interface subclass)
    HasAttribute Find out if this object has a particular attribute
    Attribute Get the value of an attribute if you have an attribute number
    SetAttribute Set the value of an attribute if you have an attribute number
    AttributeType Find the type of an attribute; returns one of the typeIDXXX constants
    InvertAttribute Convenience routine to toggle the value of an attribute; toggles 0 to 1 and any non-0 to 0
    OperationByNumber Use to call any operation by its operation number
    IntrinsicByNumber Use to call any simple intrinsic or intrinsic operation by its intrinsic number
    DispatchLookup Internal dispatch hook

    Fields, sizes, and memory use

    The following methods allow you to manipulate an object's fields directly and to get information about an object's memory use:

    Method Description
    FieldOf get the value of a field given its field number
    SetFieldOf Set the value of a field given its field number
    ReadFieldsOf read the fields of one class from an object into a buffer
    WriteFieldsOf write the fields of one class from a buffer into an object
    BeginReadFieldsOf lock down an object and return a pointer to the fields of one class for reading
    EndRead release an object that was locked by a BeginReadFieldsOf call
    BeginModifyFieldsOf lock down an object and return a pointer to the fields of one class for modification
    EndModify release an object that was locked by a BeginModifyFieldsOf call
    ObjectFieldByOffset Get the value of a field that contains an object, given a class number and offset within the fields of that class
    SetObjectFieldByOffset Set the value of a field that contains an object, given a class number and offset within the fields of that class
    FixedSize Get the size of the fixed part of an object
    Resize resize an object by delta; returns the total size of the object before resizing
    GetSize Get the total size of the fixed and extra parts of an object
    SetSize Set the total size of the fixed and extra parts of an object; returns the total size of the object before resizing
    DeepSize Get the total size of an object
    FlatSize Get the size of an object, including the fixed size, extra size, and overhead
    Moving Never call this; it is called automatically by the system
    Stabilize Tell an object that it is no longer being modified and can shrink to a smaller stable form
    Compact Called by the system when squeezing memory to do allocation
    Cluster Find what cluster an object is in
    InMetaCluster Find out if an object is in a particular meta-cluster
    InROM Find out if an object comes from any locked cluster (not necessarily ROM)
    InDeviceROM Find out if an object comes from the device ROM, which includes the system ROM and vendor ROM
    InSystemROM Find out if an object comes from the system ROM
    DestroyWillFreeMemory Find out if destroying an object will free any memory in a particular meta-cluster
    IsShadowed Find if an object is in any shadow (either the committed or uncommitted shadow)
    ContainerNear Get the container device which holds this object (calls ObjectContainer)
    ObjectContainer Get the container device which holds this object

    Manipulating extra data

    The following methods change an object's extra data

    Method Description
    ZeroExtra Zero all of the extra data
    AppendExtra Append data from the extra data area of a source object to the end of this object's extra data
    AppendByte Append one byte to the end of this object's extra data
    AppendWord Append two bytes to the end of this object's extra data
    AppendLong Append four bytes to the end of this object's extra data
    AppendBytes Append bytes from a buffer to the end of this object's extra data

    Creating and destroying objects

    The following methods create, copy, move, and destroy objects:

    Method Description
    New Called by the system to create a new object; parameters are passed through to Init
    NewNear Create an object in the same cluster as the nearThis parameter
    NewPreferred Create an object in the preferred container ("new items go here")
    NewTransient Create a transient object
    NewTransientNear Create a transient object in a specific transient cluster
    NewSystemPersistent Called by the system to create a persistent object
    InitialExtraSize Called by the system before creating an object to determine how large to make it
    Init Called by the system after creating a new object so the object can be initialized
    Copy Called by the system to copy an object, including all objects it owns
    CopyNear Copy an object, including all objects it owns, into the same cluster as the nearThis parameter
    CopyPreferred Copy an object into the preferred container ("new items go here")
    CopyTransient Copy an object into transient storage
    CopySystemPersistent Called by the system to copy into system persistent storage
    Move Called by the system to move an object, including objects it owns
    MoveNear Move an object, including all objects it owns, into the same cluster as the nearThis parameter
    MovePreferred Move an object, including all objects it owns
    PreferredContext Get system context or the package where new items would go (created by New/Copy/MovePreferred)
    Copied Called by the system on each object that is copied by any copy or move call
    Moved Called by the system on each object that is moved by any move call, before the original is destroyed
    Copying Called by the system on each new object created by moving or copying from any copy or move call
    FlatCopy Call rarely to make a bit-for-bit low-level copy (do NOT use on any object containing object IDs)
    Destroy Destroy object and all objects it owns
    ShallowDestroy Destroy object and all objects it owns except members of the collection, if the object is a collection
    FlatDestroy Destroy a single object, leaving objects it owns intact
    GarbageDestroy Destroy a single object for garbage collection
    OutOfMemoryDestroy Destroy a single object from the low-memory window
    ShrinkToStub Called by the system to turn an object into a stub
    Finalize Called by the system for each object to be destroyed by Destroy or ShallowDestroy
    Destroyed Called by the system for each object just as it is about to be destroyed (after it is already a zombie)
    MarkUsedRecently Indicate that an object was just used and should be purged later than it would be otherwise
    Purge Called by the system to get rid of a purgeable object when low on memory
    IsShared Find out if an object is shared
    FindMatch Called by the system to find a match for an object in the current cluster
    DeleteDuplicate Call this to find a match and delete the object passed if it is found
    Reclaim Call this to reclaim the memory used by an object
    EqualsShadow See if a shadowed object is equal to the source object in the source cluster just above it
    Unshadow Discard an object from the shadow, possibly revealing an original source object behind it

    Manipulating object names

    The following methods get and set the various names associated with an object:

    Method Description
    GetName Get the name of an object
    SetName Set the name of an object
    CopyName Copy the name from one object to another
    CopyNameToText Put the object's name into an existing text object
    NamesMatch Compare the names of two object
    SearchName Get the name of an object for higher-level purposes like searching
    DisplayName Get the name of an object for higher-level purposes like displaying to the user
    IdentificationString Get a name that is useful for authoring (similar to the way ObjectMaker names objects)
    ScriptName Get a name that summarizes the script on an object

    Getting text attributes

    An object has two kinds of text information associated with it, in addition to its name: text data and text info. The following methods get and set an object's text information:

    Method Description
    TextData Get the value of a text-data attribute given its index
    StringData Get the result of TextData in a string
    SetTextData Get the value of a text-data attribute given its index
    TextInfo Get the value of a text-info attribute given its index

    Comparing objects

    The following methods allow you to compare two objects:

    Method Description
    IsEqualOrNil Compare two object IDs for equality
    IsEqual Compare two objects for equality
    MatchesInstance Compare two objects that both have the same class
    IsSameChoice Make a higher-level check of equality than IsEqual (used by choice boxes)
    ComputeCRC Compute a combined CRC for this object and all objects it owns
    ComputeNameCRC Compute a CRC for the name of this object (calls GetName to get the name)

    Initializing classes and their globals

    The following methods are called by the system to initialize classes:

    Method Description
    Install Called by the system on each class when transient memory is reinitialized
    Reset Called by the system when the device hardware is reset
    ClassGlobalsOf Get the globals object for a class

    Manipulating locked buffers

    The following methods create and and destroy locked buffers:

    Method Description
    NewLockedBuffer Create a locked buffer
    DestroyLockedBuffer Destroy a locked buffer
    NewTransientBuffer Create a transient locked buffer
    TransientBufferSize Get the size of a transient buffer
    DestroyTransientBuffer Destroy a locked buffer

    Observing and notifying

    The following methods implement Magic Cap's observe/notify mechanism:

    Method Description
    Observe Start or stop observing another object
    Notice Called by the system when an observed object has been changed
    NoticeChange Trigger the notify mechanism when an object is changed
    SendAllNotices Called by the system to send queued notices

    Packing

    The following methods pack and unpack objects:

    Method Description
    CanPack Find out if an object can be packed
    PackPeek Get the value of the peek, a 16-bit value for cached information to be visible while an object is packed
    PackingBufferSize Called by the system before packing to figure out how big the maximum size the packed object could be
    PackIntoBuffer Called by the system to do the actual packing after calling PackingBufferSize and allocating the buffer
    UnpackFromBuffer Called by the system to do the actual unpacking

    Iterating through field and object references

    The following methods allow you to iterate through each of the fields of an object:

    Method Description
    EachField Iterate through all fields in an object (calls EachFixedField, then EachExtraField)
    EachFixedField Iterate through all fixed fields of an object (calls EachFieldOfClass for all superclasses)
    EachFieldOfClass Iterate through all fields of one class
    EachExtraField Iterate through all extra fields of an object
    EachInspectorField Iterate through all fields in an object from the inspector's point of view (calls EachFixedField and EachExtraInspectorField)
    EachExtraInspectorField Iterate through extra fields in an object from the inspector's point of view (calls EachExtraField)
    EachReference Find out about objects referenced from this object (calls EachField)
    GarbageCollectSize Called by the system to determine how much of an object it needs to look at for fast garbage collection
    MakeReferenceList Make a list of all objects referenced by a given object (calls EachReference)
    MapReferences Map a set of references between copied objects
    SwapBigEndian Swap a single field's byte sex

    Cleaning

    The system uses the following methods to clean references after objects vanish from memory:

    Method Description
    MakeValid() Called by the system to clean up after some objects disappear (like when a PC card is removed)
    MakeActive Called by the system on each object in iMakeActiveList after all objects have had MakeValid called
    CleanReferences Called by the system to clean references from this object that are no longer valid
    CleanStubReferences Called by the system to clean references to stubs after running out of memory
    HealSystem Called by the system to heal the system after an uncaught exception

    Filing

    The following methods file objects into packages and maintain lists of package objects:

    Method Description
    CopyIntoNewPackage Copy an object into a new package or to create a new empty package (if a class number is passed)
    InstallInto Called by the system for each object in the install list of a package when it is activated
    InstallingInto Notify the object being installed that it has been, so it can do its initialization
    SetUpReinstallEntries Recreate install list entries for all package objects in a container
    ReinstallFlagsFor Called by the system to compute the flags when creating a reinstall entry for an object
    InstalledReceiver Called by the system on a filingContainer to compute the receiver indexical for the install list
    InstalledFlags Called by the system on a filingContainer to compute the default flags for the install list
    CopyDefaultDataPackageName Called by the system on a filingContainer to compute the name of the package to put a new item in

    Scripting

    These methods control how scripts affect an object:

    Method Description
    ScriptTarget Find the object that should be scripted instead of this object
    DefaultOperation Get the operation number of the operation a typical script on this object would override
    OperationIsScriptable Find out if an operation should show up as scriptable for this object
    OperationAccessibility Find out if an operation should show up as callable for this object
    OperationAccessibleName Find out the accessible name for an operation on this object (new transient copy)

    Sending and arriving

    The following methods are called when an object has been sent:

    Method Description
    Arrived Tell object that it has arrived after being sent
    SendArrivedToEachReference Tell all objects owned about arrival

    Debugging and testing

    The following methods allow you to save object information to a log file or to examine an object's fields with the Inspector. Most of these methods are only useful in development versions of Magic Cap.

    Method Description
    Dump Dump an object to the log
    DeepDump Dump an object and all those owned by it
    DumpWithScript Dump an object with a script attached
    ShouldDumpExtra Called by the system to determine whether to skip the extra data when dumping; returns true by default
    ReferenceNumber Get number from ObjectMaker source code
    DumpName Get name used when dumping this object
    Inspect Point the inspector at this object
    DebugName Get a C string containing the name of an object suitable for logging
    Validate Validate this object

    The following methods are available only in the validation version of Magic Cap. That is, they're in the version you'll use while you're writing and debugging your package. They aren't available in the versions of Magic Cap your users will have, though. These methods often report information to Magic Cap's log file and to the message window.

    Method Description
    ValidateBad Report that a field is bad
    ValidateBadObject Report that a field is bad because it contains a bad object
    ValidateImplements Check the class of a field (reports bad class or bad object)
    ValidateReservedFlags Check that unused flags are not set in an object while validating

    The following methods are available only in the debug version of Magic Cap. That is, they're in the version you'll use while you're writing and debugging your package. They aren't available in the versions of Magic Cap your users will have, though. These methods often report information to Magic Cap's log file and to the message window.

    Method Description
    DebugMicron Get a C string containing a display of a coordinate suitable for logging
    DebugDot Get a C string containing a display of a both coordinates of a dot suitable for logging
    DebugBox Get a C string containing a display of all four coordinates of a box suitable for logging
    DebugFixed Get a C string containing a formatted fixed-point integer suitable for logging
    DebugDate Get a C string containing a formatted date suitable for logging
    DebugTime Get a C string containing a formatted time suitable for logging

    Telescript support

    The following methods implement some features of Telescript:

    Method Description
    Protect Call with an object ID to return a protected reference to that object (not yet implemented)
    Discard Ignore the parameter; useful in Telescript code to discard item on the top of the stack
    Ref Get another reference to the same object; useful in Telescript code to put another copy on top of the stack
    IsSame Check if both objects are the same; identical to DirectID(self) == DirectID(other)
    IsAfter Check if an object sorts after the other object; only defined for objects that mix in the class Ordered
    IsBefore Check if an object sorts before the other object; only defined for objects that mix in the class Ordered
    TelescriptAttribute Get the value of an attribute by name; used internally by the Telescript engine
    TelescriptClass Get a class by name; used internally by the Telescript engine
    TelescriptNew The Telescript engine calls this to create a new object
    MagicscriptNew The script interpreter calls this to create a new object
    Initialize The Telescript engine calls this to initialize a new object

    The following attributes are Telescript attributes:

    Attribute Type Description
    IsProtected Boolean true if an object ID is a protected reference to that object (not yetimplemented)
    Owner Process findwhich Telescript process owns an object (not implemented: always returns nil)

    Managing low memory

    When the system runs low on available memory, it encourages the user to delete unwanted items. To do so, it lists objects in a low-memory window. The user can touch objects to add them to a purge list, then tap accept to remove the objects from memory. Class Object defines one method to assist this process:

    Method Description
    AddToUserPurgeList Called by the system to add objects to the objects to destroy list displayed in the low-memory window

    Icons and other kinds of content information

    The following methods manipulate an object's contents:

    Method Description
    ContentIcon Get an icon that represents the object in a context where any object might appear
    DestroyContents Destroy the contents of an object
    DestroyContentsInSystem Destroy the contents of an object, but only in the system
    Info Get help text for this object in the system or package list of objects with help
    ShouldAddToNameCardLog Called by the system to find out if this object should be included in the per-person log in the name cards

    Mailing an object

    Class Object defines one method that you can use to mail an object:

    Method Description
    MailOnTelecard Create and return a Telecard to mail this object

    Digest

    The following two methods make and return an object's digest:

    Method Description
    Digest Get the digest of an object
    MakeDigest Compute, store, and return the digest of an object

    System caches

    The following methods are used by the system to manipulate various caches. You will probably never call them.

    Method Description
    CodeMoving Called by the system when code is moving to flush processor instruction cache if any
    InvalidateClusterObjects Called by the system to flush all caches of objects from some clusters
    InvalidateIndexicalCacheOnly Called by the system to flush the indexical cache (subset of InvalidateClusterObjects)
    InvalidateReference Called by the system to flush a reference from the reference cache
    InvalidateReferences Called by the system to flush all references in a context from the reference cache
    InvalidatePackageClasses Called by the system to flush all information about package classes from system caches
    InvalidatePackageIndexicals Called by the system to flush all information about package indexicals from system caches
    FlushDispatchCaches Called by the system to flush all dispatch caches
    UpdateCacheEntries Called by the system when moving an object to update the access cache
    InvalidateAccessCacheEntry Called by the system to flush any entries for this object from the access cache
    InvalidateObjectCacheEntry Called by the system to entries for this object from the object dispatch cache

    System internal use

    These methods should be called only by the system. You should never use them.

    Method Description
    InstallVectors Called by the system once at each boot to set up patches
    NotifyCleaning Called by the system to clean out the notice lists when cleaning the system
    CallTestMachine A hook for the test machine
    ReuseReference Called by the system on a reference that might already exist to set up the reference for use with a new object

    Definition of Attributes

    Class Object defines the following attributes:

    Attribute Type Definition
    ExtraSize Unsigned The size of the extra part of an object; set to change the size of an object (0 means no extra data)
    DisplaySize Unsigned The size of the object to display to the user
    DestroySize Unsigned The amount of memory that would be reclaimed by destroying this object
    SendSize Unsigned An estimate of the object's size for purposes of sending
    Protected Boolean True if an object has memory protection turned on (usually used only by the system)
    IsZombie Boolean True if an object is a zombie
    Marked Boolean True if an object is marked; set to change the state of the marked bit; used by garbage collection
    Purgeable Boolean True if an object is purgeable
    IsValid Boolean True if an object is in a valid state
    NameAsText Text The name of an object returned in a text object; call the setter to set the name of the object from a text object
    Named Boolean True if an object has its named bit set
    SearchInitial UnsignedByte The first letter of the last name, or 0; use to speed searching
    Packed Boolean True if an object is in packed form (compressed into one tightly encoded object); set to pack or unpack an object
    HasReferences Boolean True if there are any real object references in an object; set to tell an object that you have stored object references in an object
    BigEndian Boolean True if an object is in big-endian format; set to change an objects byte sex back and forth, swapping all fields if necessary
    Target Object The target of an object
    Script Object A translation of a scripted object's script in a standalone form (returns nil if object is not scripted); set to apply a CompiledScript or UncompiledScript onto an object (giving it script class)
    CanDelete Boolean True if an object can be deleted; set to mark the object as deletable or not deletable
    CanDeleteDeep Boolean True if this object and anything else it owns can be deleted; set to mark this object and all objects it owns as deletable or not deletable

    Obsolete methods

    You shouldn't use the following obsolete methods:

    Method Description
    BeginImportParameters replaced by PushImportParameters
    EndImportParameters replaced by PopImportParameters
    CanUpdate never called, always returns true
    NeedsArchiving for future use

    Methods you might override

    When you create a subclass of the Object class, you might override these methods under the following circumstances:

    Method When to override
    Arrived To do an action when object arrives on telecard
    Compact To free memory by removing data from object
    EachReference If objects have references in variable data area
    GetTextData If object's text data is not its name
    Init If your class defines fields that should be set up
    Install To initialize class variables when system starts
    IsShared To indicate whether objects are sharable
    MatchesInstance To change the test for instance equality
    Notice To do an action when observed objects change
    SetTextData If object's text data is not its name
    Stabilize To convert objects to more stable form
    Validate To perform additional validify checking

    Description of fields

    The Object class doesn't define any fields.

    Method Descriptions

    AppendByte

    operation AppendByte(source: UnsignedByte): Unsigned
    
    Call: sometimes
    Override: rarely
    

    Call AppendByte to add the given byte onto the end of the object's extra data. The object's old size is returned as the function result. AppendByte should only be called by the class that owns the extra data, or on a buffer object by its owner.

    AppendBytes

    operation AppendBytes(sourcePointer: Pointer; length: Unsigned): Unsigned;
    
    Call: sometimes
    Override: rarely
    

    Call AppendBytes to add a run of bytes of any length onto the end of the object's extra data. The sourcePointer parameter points to the start of the bytes to be added, and the length parameter indicates how many bytes to add. The object's old size is returned as the function result. AppendBytes should only be called by the class that owns the extra data, or on a buffer object by its owner.

    AppendExtra

    operation AppendExtra(source: Object; startOffset: Unsigned; length: Unsigned):
    Unsigned;
    
    Call: sometimes
    Override: rarely
    

    Call AppendExtra to append data from the extra data area of a source object to the end of this object's extra data. AppendExtra returns the object's old size. AppendExtra should only be called by the class that owns the extra data, or on a buffer object by its owner.

    AppendLong

    operation AppendLong(theLong: Unsigned): Unsigned
    
    Call: sometimes
    Override: rarely
    

    Call AppendLong to add the given four-byte value onto the end of the object's extra data. The object's old size is returned as the function result. AppendLong should only be called by the class that owns the extra data, or on a buffer object by its owner.

    AppendWord

    operation AppendWord(theWord: UnsignedShort): Unsigned
    
    Call: sometimes
    Override: rarely
    
    

    Call AppendWord to add the given two-byte value onto the end of the object's extra data. The object's old size is returned as the function result. AppendWord should only be called by the class that owns the extra data, or on a buffer object by its owner.

    Arrived

    operation Arrived(sender: Object); scriptable
    
    Call: rarely
    Override: sometimes
    

    The system calls Arrived for each new object that arrives from another device. The sender parameter indicates the object that did the sending. You can use this mechanism to have objects of your class perform some action when they arrive.

    Object_Arrived does nothing. You should override Arrived if you want objects of your class to do something on arrival. For example, sound stamp objects override Arrived to play their sounds on arrival. You should call the inherited Arrived from your overriding method to be sure that all arrival actions defined by superclasses are performed.

    Attribute

    operation Attribute(attributeNumber: Unsigned): Unsigned, intrinsic
    
    Call: sometimes
    Override: never
    

    Call Attribute to get the value of the given attribute of the object. The number of the desired attribute is specified in attributeNumber. The attribute's value is returned as the function result.

    Attribute numbers are assigned in a class's definition file.

    Here's an example of a small class, class Frobnanger, which defines only one operation and one attribute:

    Define Class Frobnanger;
      inherits from Object;
      field widgetToFrob: Widget, getter, setter;
      operation FrobWidget(): Boolean; //returns true if succeeds
      attribute WidgetToFrob: Widget;
    End Class;
    

    This class would define its attribute and object numbers this way:

    Class       Frobnanger      1;
    operation   FrobWidget      2;
    attribute   WidgetToFrob    3;
    

    You can refer to the WidgetToFrob attribute using either its number, 3, or its symbolic representation, attribute_WidgetToFrob.

    Attributes have getter and setter methods, which also have operation numbers associated with them. The operation number for an attribute's getter is the same as the attribute number, and the number for its setter is one higher. So in our example, the operation number for SetWidgetToFrob would be 4.

    Here's where you learn how this rather long-winded example is actually relevant to a discussion of the Attribute method: the Attribute method takes these attribute numbers in its attributeNumber parameter. You can use either the number or the symbolic representation of the number. The symbolic representation of the number is better, though: it's more readable and it can't change out from under you the way the number can.

    For more information on attributes, see Magic Cap Concepts.

    ClassGlobalsOf

    
    operation ClassGlobalsOf(): Object, intrinsic
    
    Call: sometimes
    Override: rarely
    

    Call ClassGlobalsOf to get the object that contains the global data for a class. Despite the fact that ClassGlobalsOf is a method of class Object, the parameter is usually a class number. You will often call this method with the ClassGlobals cover macro, instead of directly.

    Compact

    operation Compact(severityMask: Unsigned; bytesNeeded: Unsigned);
    
    Call: rarely
    Override: sometimes
    

    Warning! This description is incomplete.

    The system calls Compact when there's a critical shortage of memory. Compact asks the object to try to free up memory by removing data that can be recreated, such as caches or indices.

    Object_Compact does nothing. You should override Compact if you want to provide a way for objects of your class to free up memory when requested, as by removing information that can be recreated.

    The bytesNeeded parameter indicates how much memory the system is trying to make free.

    The severityMask parameter is mysterious right now. Look for more information in the next edition of this chapter.

    #define kMaxSeverity               0x00FFFFFF
    #define kMetaSeverityMask          (~kMaxSeverity)
    #define kDeepCompactSeverityFlag   0x80000000
    #define kCompactUnlockFlag         0x40000000
    

    Context

    operation Context(): Context, intrinsic;
    
    Call: sometimes
    Override: never
    

    Call Context to find out which context an object is in. You can call Context on class numbers as well as on objects.

    For system objects and class numbers, Context returns the system context. For package objects and class numbers, Context returns the package context for that package. For indexicals, Context returns the context of the indexical's DirectID.

    For an overview of contexts, please see the section on Clusters and Contexts in the chapter "Object Runtime" in Magic Cap Concepts.

    Copy

    operation Copy: Object; noFail, safe
    
    Call: sometimes
    Override: rarely
    

    Call Copy to make a copy of the object. Copy also makes copies of all objects referenced by the object's fields (except objects defined as noClone in the class's definition), then sets the copy's fields to refer to the new objects. Referenced objects defined as noClone are not copied, and the new object keeps the same references as the original object. The new object is returned as the function result.

    The new object is created in the current cluster. To create a copy in a different cluster, use one of the variants of Copy, such as CopyNear or CopyPreferred.

    The system calls Copy to create a copy of an object. You should override Copy if you want objects of your subclass to perform some additional action when a new copy is created with Copy. Usually, this additional processing involves setting up fields of the newly-created object. For example, class Viewable overrides Copy to set the newly-created object's superview field to nil.

    Object_Copy automatically copies all objects referenced by fields in the object, so you don't have to override Copy just to ensure that referenced objects are copied. You should call the inherited Copy in your overriding method, usually at the beginning, to ensure that your object and the objects it references are copied.

    Copying

    operation Copying(), safe;
    
    Call: rarely
    Override: sometimes
    

    The system calls Copying on each new object created by any call to a copy or move method. Override Copying for your subclasses if you want to do some additional work to set up new objects of your classes.

    For example, class Linkable overrides Copying to make sure that the new copy's Next and Previous attributes point to objects that point back to the copy. Class Card overrides Copying to make sure the new copy doesn't point to the same stack as its original, if the new copy isn't in the old stack.

    CopyNear

    operation CopyNear(nearThis: Object): Object, intrinsic, safe;
    
    Call: sometimes
    Override: rarely
    

    Call CopyNear to copy an object into the specified cluster. Like Copy, CopyNear also copies all objects owned by the target object.

    The nearThis parameter specifies where the copy should be created. This parameter can be another object or a cluster number.

    Handy names for cluster numbers are defined in the file FrameworkDefines.asm.h. They are listed here for your convenience:

    Name Number Description
    kAnyIndex (-1)
    kSystemPersistent 0 8 uncommitted changes to ROM metacluster
    kLockedPersistent 1 88 specially locked persistent blocks
    kCard2 2 9 card 2 metacluster
    kPackageReserved98 3 98 reserved by the current package
    kPersistentRAM 4 A persistent RAM metacluster
    kTransientRAM 5 A8 transient RAM metacluster
    kPackagePersistent 6 B uncommitted changes to package persistent cluster
    kPackageReservedB8 7 B8 reserved by the current package
    kPackageTransient 8 C transient package objects
    kVendorROM 9 C8 vendor ROM metacluster
    kSystemTransient 10 D transient system objects
    kCardAdditional 11 D8 addition cluster for cards with more than one device
    kCard1 12 E card 1 metacluster
    kLockedTransient 13 E8 locked blocks
    kScripting 14 F cluster for objects owned by current Telescript process
    kTemporary 15 F8 reserved for temporary copying
    kSystemSource 16 ROM metacluster
    kSystemShadow 17 committed changes to ROM metacluster

    For descriptions of these clusters and what they contain, see the chapter "Object Runtime" in Magic Cap Concepts.

    Class Object provides you with a convenience routine, CopyTransient, which you can call instead of CopyNear when you want to copy an object into the transient cluster. Calling CopyTransient is equivalent to calling CopyNear(object, kSystemTransient).

    CopyPreferred

    operation CopyPreferred(filingContainer: Object): Object, safe;
    
    Call: sometimes
    Override: rarely
    

    Call CopyPreferred to copy an object into the preferred container. The preferred container is the place the user has specified for storing new objects. For example, the user might choose to create new items on a particular RAM card instead of in main memory. In that case, the copies created by CopyPreferred would go into the new items package on the card.

    The filingContainer parameter specifies where the copy should reinstall when the new items package is unpacked. This parameter must be an indexical. For example, if the item is a name card, the filingContainer parameter should be iNameCardsStack.

    CopyPreferred works on class numbers as well as on objects.

    DeleteDuplicate

    operation DeleteDuplicate(): Object
    
    Call: sometimes
    Override: rarely
    

    Call DeleteDuplicate if you suspect that there's more than one copy of the object. DeleteDuplicate checks to see if there's an exact copy of this object in the system. If so, it deletes the object passed as self and returns the duplicate as the function result. If there is no duplicate, it simply returns this object; nothing is deleted and the object is not changed. DeleteDuplicate checks for a copy by calling Object_FindMatch.

    You must call DeleteDuplicate after you copy and modify a shared object. For example, Class Control calls DeleteDuplicate after copying and updating a control target that's shared.

    Destroy

    operation Destroy(), noFail
    
    Call: sometimes
    Override: rarely
    

    Call Destroy to delete the object and all objects referenced by its fields. Shared objects and global objects (indexicals) won't be deleted. The system calls Destroy to delete an object and all the objects it refers to.

    Object_Destroy automatically deletes all objects referenced by fields in the object, so you don't have to override Destroy just to ensure that referenced objects are deleted. If the object has any observers, Object_Destroy notifies the observers that the object is being deleted and removes the object from their observation lists.

    If you want objects of your subclass to perform some additional action when they're destroyed, you should almost always override Finalize instead of Destroy. Finalize is called on the object that's being destroyed and on all objects owned by it. Destroy is called only on the object iself.

    If you do override Destroy, call the inherited Destroy in your overriding method to ensure that your object and the objects it references are deleted.

    Digest

    operation Digest(): Unsigned
    
    Call: rarely
    Override: rarely
    

    When the system is about to send an object to another place, and there already seems to be a copy of the object at the destination, the system calls Digest to get summaries of the two objects' contents. These summaries are usually checksums of the objects' contents.

    The system compares the digests to determine if two objects are the same. The digest is a 32-bit value returned as the function result. Object_Digest simply returns zero and prints this debugging message: "<Object> was asked for a digest; it doesn't have one".

    You should override Digest if you want objects of your class to implement a mechanism for computing and returning a digest of their contents. See the description of MakeDigest for additional information on digests.

    DirectID

    operation DirectID(): Object, intrinsic, safe;
    
    Call: often
    Override: never
    

    Call DirectID to translate an indexical into the object it points to. DirectID has no effect on object IDs other than indexicals.

    Most of the time you won't need to translate an indexical to its object. Sometimes you'll want to

    EachReference

    operation EachReference(mask: Unsigned; function: EachFunction; VAR 
    parameters: Parameters): Object;
    
    Call: sometimes
    Override: sometimes
    

    Call EachReference when you want to invoke a function repeatedly for every object that's referenced by the object. If you call EachReference, you must also define the iterative function to be called for each reference, then pass a pointer to this function in the proc parameter. If you want to send any parameters to your iterative routine, pass a pointer to the parameters in params when you call EachReference.

    EachReference keeps calling the iterative function as long as the iterative function returns nilObject and there are still referenced objects that haven't been processed. When the iterative function returns an object ID instead of nilObject, EachReference stops calling the iterative function and exits. This is useful if you want to stop iterating when your iterative function fulfills some condition, such as successfully completing a search.

    EachReference uses EachField to do its work. It differs from EachField because you only need to pass the objects referenced. If you were using EachField instead, you would need to pass the byte offsets of the fields that reference the objects.

    The mask parameter allows you to specify that certain references be skipped. The system defines these symbols that you can use to help specify the mask:

    #define kNoMapFlag     0x80000000
    
    #define kVarFlag       0x00004000
    #define kNoCloneFlag   0x00002000
    #define kNoSendFlag    0x00001000
    

    Use kNoCloneFlag if you want to skip objects that aren't automatically cloned when the object is copied with Copy. Use kNoSendFlag to skip objects that aren't automatically sent when the object is sent. You can add the flags together to skip both kinds of references.

    The routine that's called for each referenced object should be declared like this:

    Private ObjectID IterativeProc (ObjectID theObject, void *params)
    
    


    WARNING! You must use the Private specifier when you declare your iterative function. If you fail to do so, you'll get no warning from any tools during the build process, but your software will fail in an unpredictable way.

    The theObject parameter contains the object that's currently being processed. EachReference passes the params parameter unchanged each time IterativeProc is called.

    You should override EachReference if your class's objects refer to objects in other ways, such as in their extra data area or in lists. You should call the inherited EachReference from your overridden method, then call the iterative routine for the other referenced objects. You might also override EachReference to dynamically change non-owning references (such as noCopy references) to owning references.

    FindMatch

    operation FindMatch(): Object
    
    Call: rarely
    Override: rarely
    

    The system calls FindMatch to try to find a duplicate of the object, usually while it's moving or copying shared objects. If FindMatch finds a duplicate, it returns the duplicate as the function result. Otherwise, it returns nilObject.

    FindReference

    operation FindReference(): Reference, intrinsic;
    
    Call: sometimes
    Override: never
    

    Call FindReference to get a reference to an object, given the object. FindReference returns nil for objects that don't have a reference. FindReference does not create a reference if one doesn't already exist.

    GetIDStr

    operation GetIDStr(VAR name: String)
    
    Call: sometimes
    Override: rarely
    

    Call GetIDStr to get the object's ID string, which identifies an object as seen in the Inspector. This format consists of the class name followed by the object name, if it has one, enclosed in single quote marks, followed by the low bytes of the object ID. Here are some example ID strings for various objects:

    Screen 51     Form 'Home' 241     Shape 344
    Icon 'Stocks' 1599     Button 'Push' 242     Shelf 242
    

    GetName

    operation GetName(VAR name: String), noIndirection
    
    Call: sometimes
    Override: rarely
    

    Call GetName to get the name of the object returned in the theName parameter. Object_GetName calls Cluster_GetObjectName to perform its action.

    GetSize

    operation GetSize(): Unsigned
    
    Call: rarely
    Override: rarely
    

    Call GetSize to find out the size of the object in bytes. The size is returned as the function result. GetSize reads the object's size from the header in the object's data structure. In general, you should call Bytes instead of GetSize to find out the object's size.

    See the description of Bytes for more information.

    GetStringData

    operation GetStringData(index: UnsignedShort; VAR strData: String)
    
    Call: sometimes
    Override: rarely
    

    Call GetStringData to get the object's text data returned as a Pascal-style string in the strData parameter. GetStringData performs its action by calling GetTextData, then putting the text into strData. GetStringData truncates the text to 255 characters if necessary.

    HasObject

    operation HasObject(): Boolean, intrinsic;
    
    Call: often
    Override: never
    

    Call HasObject to find out if an object ID has an object behind it. HasObject returns false for any type of object ID that does not have an object, including indexicals with non-object values.

    In many cases, you'll need to test an object you've been passed is a good object before you try to use it. Test using HasObject with code that looks like this:

    if (HasObject(checkThisID)) 
       {
       /* do some work with the widget object /*
       }
    

    Since HasObject returns false for non-object indexicals, you'll need to modify this check slightly for cases where you might be checking an indexical. In those cases, your check might look like this:

    if (IsIndexical(checkThisID) || HasObject(checkThisID))
    

    Implements

    operation Implements(classNumber: Unsigned): Boolean; noFail
    
    Call: rarely
    Override: rarely
    

    Call Implements to determine if the class that the object belongs to implements the operations defined by the given class.

    Import

    intrinsic Import(fromContext: Context; whatToImport: Object): Object;
    
    Call: sometimes
    Override: never
    

    Call Import to translate an object ID or class number from one context to another. You'll call Import if you've switched contexts or if you want to borrow an object from a different package.

    The fromContext parameter is the context the object ID was in. If you're switching contexts yourself, you can get this context from the return value from PushContext or PopContext. If you aren't switching contexts but are importing from outside your context, you can identify the foreign context using a call like FindSoftwarePackageByCitation.

    You must use Import to make objects and classes from other packages usable in your package. Here's a code snippet that shows how you might import a class from another package:

    /* first get the context for the other package */
    otherPackageContext =   
    FindSoftwarePackageByCitation(ipOtherPackageCitation, -1);
    /* import a class number from the other package */
    importedClassNumber = Import(otherPackageContext, 
                          OtherPackageClass_);
    /* now you can use the class to make new objects */
    newForeignObject = NewTransient(importedClassNumber, nil);
    

    For a detailed example of using Import to use a class defined by another package, see the ClientPackage sample in Magic Developer.

    Init

    operation Init(params: Pointer)
    
    Call: rarely
    Override: often
    

    When a new object is created, the system calls Init to allow the new object to set up its fields. The params parameter points to a structure that contains initial values for the object's fields.

    You should override Init if your class defines any fields that should be set up to initial values when a new object is created.

    For more information, see any class that overrides Init, such as class Class or class FixedList.

    Install

    operation Install()
    
    Call: rarely
    Override: sometimes
    

    When the system starts up, it calls the Install method for every class. This gives each class a chance to initialize any globals, private variables, or other state information.

    You should override Install if you want your class to initialize any global variables when the system starts up. You should not call the inherited Install, because the system calls every class's Install method directly.

    IsIndexical

    operation IsIndexical(): Boolean, intrinsic;
    
    Call: sometimes
    Override: rarely
    

    Call IsIndexical to find out if an object ID is an indexical. This also works for references to package indexicals.

    IsReference

    operation IsReference: Boolean; noFail; noIndirection
    
    Call: rarely
    Override: rarely
    

    Call IsReference to determine whether the object is a reference, rather than a direct object ID (a reference provides access to an object from any context). Object_IsReference always returns false. See the description of the NewReference method for more information.

    IsShared

    operation IsShared(): Boolean; noFail
    
    Call: rarely
    Override: sometimes
    

    In order to reduce the number of objects that must be kept in memory or sent to another device, the system defines a sharable object as one that can be substituted for another that appears to be the same. For example, this allows the system to keep only one object of type Color that defines, say, red, and all objects that refer to the red color can refer to that shared object.

    The system calls IsShared to determine if the object is sharable. If so, the object is shared, and IsShared returns true; otherwise, it returns false. If an object is shared, the system won't clone it or delete it automatically when an object that references it has its Copy or Destroy method called.

    Object_IsShared always returns false. You should override IsShared to indicate whether objects of your class are sharable. Some classes, such as Color and TextStyle override IsShared to always return true, indicating that their objects are sharable.

    IsSystemObject

    operation IsSystemObject(): Boolean; intrinsic
    
    Call: rarely
    Override: never
    

    Call IsSystemObject to determine whether the object is in the system cluster. IsSystemObject works by checking the high bits of the object ID.

    MakeDigest

    operation MakeDigest(): Unsigned
    
    Call: rarely
    Override: rarely
    

    The system calls MakeDigest to ask the object to recalculate its digest. The newly-calculated digest is returned as the function result. Object_MakeDigest simply returns zero.

    You should override MakeDigest if you want objects of your class to implement a mechanism for computing and returning a digest of their contents.

    MakeStorable

    operation MakeStorable(whatToStore: Object): Object, intrinsic;
    
    Call: often
    Override: never
    

    Call MakeStorable to change a usable object ID into a storable object ID to be stored in an object or buffer.

    The first, or self, parameter is the object that the ID will be stored in. The self parameter should be nil if you'll be storing the ID in a buffer. The whatToStore parameter is the object ID that you want to make storable.

    Most of the time MakeStorable will be called for you by the system. You'll need to call it yourself only if you don't use the usual methods for getting objects and are treating object IDs like data. For instance, MakeStorable is called for you if you use SetFieldOf to read an object from another object's field. But if you call WriteFields or WriteFieldsOf instead, you need to call MakeStorable yourself.

    This code snippet shows you how you might use MakeStorable with WriteFields:

    Calculator          calculator;
    Calculator_Fields   fields;
    ObjectID            displayText;
    /* displayText is a local variable that contains a usable
       objectID.  We have to call MakeStorable to make our
       our displayText object into a storable object. */
    fields.displayText = MakeStorable(calculator, displayText);
    /* now we can write the fields into the calculator object */
    WriteFields(calculator, &fields);
    

    This is the most common use you'll have for MakeStorable.

    MakeUsable

    operation MakeUsable(whatToRetrieve: Object): Object, intrinsic;
    
    Call: sometimes
    Override: never ?
    

    Call MakeUsable to change a storable object ID from an object or buffer into an object ID you can use for dispatching and accessing.

    The self parameter is the object that the object ID was stored in or nil for a buffer. The whatToRetrieve parameter is the object ID you need to convert into a usable form.

    Most of the time MakeUsable will be called for you by the system. You'll need to call it yourself only if you don't use the usual methods for getting objects. For instance, MakeUsable is called for you if you use FieldOf to read an object from another object's field. But if you call ReadFields or ReadFieldsOf instead, you need to call MakeUsable yourself.

    Here's an example of a code snippet from class Calculator that shows how to use MakeUsable with ReadFields:

    Calculator          calculator;
    Calculator_Fields   fields;
    ObjectID            displayText, display;
    /* read all the fields */
    ReadFields(calculator, &fields); 
    /* then call MakeUsable on the ones we need to use */
    displayText = MakeUsable(calculator, fields.displayText);
    display = MakeUsable(calculator, fields.display);
    

    This is the most common use of MakeUsable. You might also use it if you're using BeginReadExtra to read an object's extra data.

    MarkSetMark

    attribute Mark: Boolean
    // operation Mark: Boolean
    // operation SetMark(newValue: Boolean)
    
    Call: rarely
    Override: rarely
    

    The system includes a garbage collection mechanism that searches for objects that aren't referenced by any other objects. Each object can be marked or unmarked during the garbage collection process. The mark is maintained as part of the object's header. At the end of the garbage collection process, marked objects are deleted. The system calls Mark to test whether the object is marked. If Mark returns true, the object is marked; false means it's not marked.

    The system calls SetMark to mark or unmark the object as part of the garbage collection process. If newValue is true, the object is marked; if newValue is false, the object is unmarked.

    MatchesInstance

    operation MatchesInstance(other: Object): Boolean
    
    Call: rarely
    Override: sometimes
    

    The system calls MatchesInstance to see whether the objects have equal data.

    Object_MatchesInstance returns true if the objects are the same size and contain identical bytes. You should override MatchesInstance if you want your class to change this test for instance equality. For example, Shadow overrides MatchesInstance to return true if the objects' shadow offsets are the same.

    Moving

    operation Moving(deltaPtr: Signed); noFail
    
    Call: rarely
    Override: rarely
    

    Objects in clusters always occupy contiguous bytes in memory. In order to make the best use of memory space, the system relocates objects to produce larger blocks of contiguous free space. When an object is about to be relocated, the system calls the object's Moving method. The deltaPtr parameter is a signed value giving the offset of the object's new address from its old location. Object_Moving updates the object's entry in the system's object cache when the object is about to move.

    You should override Moving if you want objects of your class to perform some additional action when they're about to be relocated. You should call the inherited Moving from your overriding method.

    NamedSetNamed

    attribute Named: Boolean
    // operation Named(): Boolean
    // operation SetNamed(newValue: Boolean)
    
    Call: rarely
    Override: rarely
    

    The system calls Named to determine if the object has a name. If so, Named returns true. Object_Named performs its action by examining a flag in the object's header.

    The system calls SetNamed to set the flag in the object's header that indicates that the object is named. Calling SetNamed doesn't give you a chance to actually name the object; it's mainly called as a side effect when you set the object's name with SetName, so you'll rarely call it directly.

    Near

    operation Near(nearThis: Object): Boolean, intrinsic;
    
    Call: often
    Override: never
    

    Call Near to find out if one object is in the same cluster as another. Near returns true if the self parameter is in the same cluster as the nearThis parameter.

    Either parameter can be a cluster number or an object ID. Either parameter can also be an indexical. However, if an indexical parameter is not an object ID, Near will treat its value as a cluster number.

    NearPackage

    operation NearPackage(): Boolean, intrinsic;
    
    Call: often
    Override: never
    

    Call NearPackage to find out if an object is in any package. NearPackage works with cluster numbers as well as object IDs.

    NearPersistent

    operation NearPersistent(): Boolean, intrinsic;
    
    Call: often
    Override: never
    

    Call NearPersistent to find out if an object is in persistent storage. NearPersistent works with cluster numbers as well as object IDs.

    NearSystem

    operation NearSystem(): Boolean, intrinsic;
    
    Call: often
    Override: never
    

    Call NearSystem to find out if an object is in the system. NearSystem works with cluster numbers as well as object IDs.

    NearTransient

    operation NearTransient(): Boolean, intrinsic;
    
    Call: often
    Override: never
    

    Call NearTransient to find out if an object is in transient storage. NearTransient works on cluster numbers as well as object IDs.

    NewReference

    intrinsic NewReference(inThis: ClusterContext; toThis: Object; nearThis:
    Object): Object
    
    Call: rarely
    Override: rarely
    

    Standard object IDs are context-sensitive: they can only be used to refer to objects in the same cluster as the code that's accessing the object. The system defines a special way of referring to an object, called a reference, that can be used from any context. Call NewReference to create a reference to the object that can be used from any cluster.

    Notice

    operation Notice(observed: Object; deleted: Boolean); noFail
    
    Call: rarely
    Override: sometimes
    

    The system periodically calls Notice for every observed object that has changed or been deleted. If the observed object has been deleted, the deleted parameter is true. Otherwise, the object has changed but hasn't been deleted.

    Object_Notice does nothing. You should override Notice if you want objects of your class to perform some action when they're notified of changes in objects they're observing. For example, the Inspector overrides Notice to update its display when observed objects change.

    Observe

    operation Observe(observerClass: Unsigned; observed: Object; observeFlag:
    Boolean)
    
    Call: sometimes
    Override: rarely
    

    Call Observe to register or remove the registration of the object as an observer of another object. This causes the system to call the object's Notice method whenever the observed object changes. To register the observer-observed pair, pass true for observeFlag. To remove registration for the observing pair, pass false for observeFlag.

    PopImportParameters

    intrinsic PopImportParameters(VAR parameters: Parameters; savedContext:
    Context);
    
    Call: often
    Override: never
    

    Call PopImportParameters to return parameters to their previous state after a call to PushImportParameters.

    The savedContext parameter is the result from the PushImportParameters call.

    PushImportParameters

    intrinsic PushImportParameters(VAR parameters: Parameters): Context;
    
    Call: rarely
    Override: never
    

    Call PushImportParameters to import parameters after switching contexts. For example, the system switches context when it dispatches to a package object.

    PushImportParameters is called by routines that take parameters, not by functions passed in. (Functions passed to iterators like Each can rely on the iterator to import paramters properly.)

    PushImportParameters returns the context that the parameters used to be set up for. You should save this context to pass to PopImportParameters to export the parameters back to their original context.

    You'll use PushImportParameters and PopImportParameters in pairs in code that will look something like this:

    objectID    originalContext;
    /* we've been passed paramsPtr and we're not sure if it's
       from the same context as us. So we import: */
    originalContext = PushImportParameters(paramsPtr);
       /* do work with the parameters here */
    /* pop the parameters back to their original context so their
       owner can use them */
    PopImportParameters(paramsPtr, originalContext);
    

    Resize

    operation Resize(deltaSize: Signed): Unsigned
    
    Call: rarelyO
    verride: rarely
    

    Call Resize to change the size of the object by adding the value in deltaSize to the object's current size. You can use Resize to make the object larger or smaller by passing a positive or negative value for deltaSize. The object's old size is returned as the function result.

    Resize performs its action by calling GetSize to learn the object's current size, then calling SetSize to set the new size.

    SearchName

    operation SearchName(VAR name: String; userEntryOrder: Boolean)
    
    Call: rarely
    Override: rarely
    

    When the user searches for an object using the search tool, the system calls SearchName to determine the name that the object presents to the search tool.

    Object_SearchName calls GetName and places the result in the theName parameter. You should override SearchName if you want objects of your class to return something else for their search names. For example, class ImageCard overrides SearchName to return the name of the card's image as the search name.

    SetAttribute

    operation SetAttribute(attributeNumber: Unsigned; newValue: Unsigned)
    
    Call: sometimes
    Override: never
    

    Call SetAttribute to set the value of an object's attribute. The desired attribute is specified in attributeNumber. The new value that the attribute takes on is passed in the newValue object.

    SetIndexical

    operation SetIndexical(replacement: Object), intrinsic;
    
    Call: often
    Override: never
    

    Call SexIndexical to change the value of an indexical. The self parameter is the indexical to set, and the second parameter is the new value.

    SetName

    operation SetName(name: String); noFail
    
    Call: sometimes
    Override: rarely
    

    Call SetName to set the object's name to the given string. The new name is passed as a Pascal-style string. Object_SetName calls Cluster_SetObjectName to perform its action.

    SetSize

    operation SetSize(newSize: Unsigned): Unsigned
    
    Call: rarely
    Override: rarely
    

    Call SetSize to change the size of the object to the value in newSize. You can use SetSize to make the object either larger or smaller. The old size of the object, before the SetSize takes effect, is returned as the function result.

    SetSize performs its action by calling Cluster_SetObjectSize on the object's cluster. {When or how would you really use this, and what are the hazards?}

    SetTextData

    operation SetTextData(text: TextBehavior; index: Unsigned; where: Dot)
    
    Call: rarely
    Override: sometimes
    

    The system calls SetTextData to set the object's text when the user drops text onto an object. The text parameter contains the text to be dropped in. The index parameter indicates which of the object's text values to change if it has more than one. The where parameter gives the location where the user dropped the text. SetTextData can use this location to determine which text value to change in the object instead of index.

    Object_SetTextData does nothing. You should override SetTextData if your class defines objects that include text data other than their names. You should redraw the object if drawFlag is true.

    SetUpParameters

    intrinsic SetUpParameters(VAR parameters: Parameters; objectCount: Unsigned);
    
    Call: often
    Override: never
    

    Call SetUpParameters to prepare a Parameters structure before passing it to any routine that takes Parameters. You must call SetUpParameters on a Parameters structure before using it. ObjectIDs are only valid in the context where they are created, so to use them in other contexts, you have to create references to them. SetUpParameters creates those references for parameters.

    The parameters parameter should be a pointer to the header of your Parameters structure. Any objects in the structure must come right after the Parameters header.

    The objectCount parameter tells how many ObjectID fields there are in the parameters structure you're setting up. This tells the system how many of the fields must be made usable in another context.

    You'll need to call SetUpParameters any time you pass a parameters structure to the system. You'll do so any time you call an iterator like Each, methods that create new objects like New and NewTransient, or methods like RunSoonIn.

    For example, suppose you've defined a parameters structure to use with an Each function, the private function MyOwnEachFunction. The parameters structure will look something like this:

    typedef struct {
       Parameters   header; // standard parameters header
       ObjectID     iterateWithThis; // objectIDs after the header
    } MyOwnParams;
    

    Here's a code fragment that sets up a MyOwnParams structure and uses it in an Each Call:

    MyOwnParams   params;
    ObjectID      iterateOnMe;
    /* … */
    SetUpParameters(&params.header, 1); /* set up params */
    Each(iterateOnMe, (EachFunction)MyOwnEachFunction,
         &params.header); /* now call Each */
    

    The MyOwnParams structure includes one object following the header, so the example passes 1 as the objectCount parameter to SetUpParameters .

    For more examples of using parameters, see the discussion in the chapter on class HasIterator, particularly the descriptions of HasIterator_Each and HasIterator_UniqueName.

    Stabilize

    operation Stabilize(); noFail
    
    Call: rarely
    Override: sometimes
    

    When a new object is created and initialized, the object might go through a period of instability while its initial values are set up. This happens, for example, when a list object is created and filled with values. When this unstable period is over, the system calls Stabilize to notify the object that the system probably won't be making frequent changes to the object. When this happens, the object should convert to a form that occupies less memory but isn't as easy to modify. This is especially useful for list objects, which tend to have a "loose" form that takes more memory but it easier to modify, and a "tight" form that's more useful when the object is stable.

    Object_Stabilize does nothing. You should override Stabilize if you want to provide a way for objects of your class to convert to a tighter form, as by removing unused or obsolete data. For example, StringList overrides Stabilize to remove invalid entries.

    TextData

    operation TextData(index: UnsignedShort): Object, noFail, safe;
    
    Call: sometimes
    Override: sometimes
    

    Every object in the system can define one or more text values that reflect some text in the object. Call TextData to get the object's text. The exact meaning of the object's text data is determined by its class. The index parameter determines which text value is returned.

    Object_TextData simply returns the object's name if index is not zero, and a new, empty text object if index is zero. You should override TextData if you want objects of your class to define text data that consists of more than just the object's name. If your objects can return more than one text value, you can use the index parameter to determine which text value to return.

    The Definitely Moldy Section

    GetFieldCount

    operation GetFieldCount(): Unsigned
    
    Call: rarely
    Override: rarely
    

    Call GetFieldCount to find out how many fields are defined by the object's class. The Inspector calls GetFieldCount to determine how many fields an object has.

    GetEachField

    operation GetEachField(proc: GetEachFieldProcPtr; params: Pointer): Unsigned
    
    Call: rarely
    Override: rarely
    

    The system calls GetEachField to invoke a routine repeatedly for every field that's defined by the object's class. The proc parameter is a pointer to the routine that's called for every field. A pointer to the iterative routine's parameters is supplied in params.

    The iterative routine that's called for each field should be declared like this:

    void proc (ObjectID object, ulong fieldNum, StringPtr fieldName, StringPtr 
    commentStr, TypeValue *typePtr, void *dataPtr, void *paramsPtr);
    

    The fieldNum, fieldName, and typePtr parameters contain the number, name, and type of the field that's currently being processed. The dataPtr parameter points to the field's data.

    Debugging and Testing

    Validate

    operation Validate()
    
    Call: rarely
    Override: sometimes
    

    The system calls Validate to try to determine if an object is valid. If Validate detects any problem or inconsistency, it causes an exception or posts an appropriate error message.

    Object_Validate checks the following conditions and performs the following actions if the conditions are true:

    condition action if true
    the object's ID is not valid Prints debug message: (id) is not an object id; calls fail(cannotfindobject)
    the object's ID doesn't refer to any existing object Prints debug message: (id) is either a bad id or something that has been destroyed; calls fail(cannotfindobject)
    the object's class number is the ID for free blocks Prints debug message: (id) is a free block, not a valid object; calls fail(cannotfindobject)
    the object is too small for instances of its class Prints debug message: (id) is too small ([size] bytes; instances of (class) are supposed to be (correct size) bytes
    the object is too large for instances of its class Prints debug message: (id) is too large ([size] bytes; instances of (class) are supposed to be (correct size) bytes

    You should override Validate if you want objects of your class to perform any additional validity checking.

    ValidateBad

    operation ValidateBad(fieldName: String)
    
    Call: sometimes
    Override: rarely
    

    Call ValidateBad from the object's Validate routine when you want to indicate that a field is invalid. ValidateBad displays the following message:

    <self> has a bad <fieldName>
    

    ValidateBadObject

    operation ValidateBadObject(fieldName: String; badValue: Object)
    
    Call: sometimes
    Override: rarely
    

    Call ValidateBadObject from the object's Validate routine when you want to indicate that an object is invalid. ValidateBadObject displays the following message:

    <self> has a bad <fieldName>: <badValue>