Defined in Object.Def
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.
You'll never create any objects of class Object, and this class doesn't define any fields.
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.
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:
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.
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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) |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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) |
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 |
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 |
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) |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
The Object class doesn't define any fields.
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
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).
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.
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.
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.
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.
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
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)
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.
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.
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.
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
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.
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.
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.
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))
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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);
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.
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.
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.
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.
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.
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?}
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.
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(¶ms.header, 1); /* set up params */ Each(iterateOnMe, (EachFunction)MyOwnEachFunction, ¶ms.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.
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.
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.
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.
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.
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.
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>
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>