Currently, because package objects share the same object ID space, a Reference object is created whenever one package object refers to an object in another package context, or when an object in the system context refers to a package object. Since all object references will share the same namespace in the new runtime model, the current Reference object machinery is obsolete and will be removed from Rosemary. For the most part, packages should not be making explicit use of the Reference classes or methods; Reference objects are normally created automatically by the system. This means that this aspect of the new object runtime should have little impact on application packages.
Cleaned up LocalRuleAction so that the action data wasn't sometimes an operation number and sometimes a value. Removed the actionData field and replaced it with two fields, operationToExecute and valueData.The design of LocalRuleAction has been simplified as well. Some of the action types have been removed, along with IntrinsicRuleAction. The seven action types that remain are as follows:
- actionCallOperationPassTrigger (7)
- Call an operation
- operationToExecute is called on actionObject. The object that triggered the rule is passed as the single parameter. If you specify an operation without a parameter, that works fine; the trigger object is ignored.
- actionCallOperationPassInteger (8)
- Call an operation
- operationToExecute is called on actionObject. valueData is passed as the single parameter. If you specify an operation without a parameter, that works fine; the valueData parameter is ignored.
- actionCallOperationOnTrigger (6)
- Call an operation
- operationToExecute is called on the object that triggered the rule. valueData is passed as the single parameter. If you specify an operation without a parameter, that works fine; the valueData parameter is ignored.
- actionPostAnnouncement (4)
- Put up an announcement
- actionObject is the text.
- actionPlaySound (1)
- Play a sound
- actionObject is the sound.
- actionPlaySoundFor (11)
- Play a sound for a fixed duration using the PlaySoundFor() call
- actionObject is the sound and valueData is the duration.
- actionPutInContainer (2)
- File a card that just arrived
- This is mainly useful for the in box rules that file cards into folders, into the file cabinet, or into the trash. The object that triggered the rule must be a card. The actionObject is something that can swallow a minicard.
Here's how you should convert the obsolete action types:
- actionSetAttribute (3)
- Convert all local rule actions that were using this action type to use actionCallOperationPassTrigger instead. This requires changing the operation to the setter instead of the getter. For example, if the old operation number was operation_AutoLogging, the new action should use the operation number operation_SetAutoLogging. Also, the scene attribute feature that was triggered by the rule flag sceneAttributeMask is no longer supported.
- actionPostTaskAnnouncement (6)
- Convert all local rule actions that were using this action type to use actionCallOperationOnTrigger instead. This requires putting the operation number operation_PostTaskAnnouncement into the operationToExecute field. Note that this new action type is re-using the number 6.
- actionDeleteOld (8)
- Convert all local rule actions that were using this action type to use actionCallOperationPassTrigger instead. This requires putting the operation number operation_DeleteOldItems into the operationToExecute field. The number of old items in the valueData field will still be passed through as before, so you should leave the old value in there. Note that this new action type is re-using the number 8.
- actionDoIntrinsicOperation (9)
- Convert all local rule actions that were using this action type to use non-intrinsic operations. The cases of this that showed up in the system were: 1) an intrinsic that just played a sound -- converted to actionPlaySound -- and 2) an intrinsic that was only used from the rule action -- converted to a non-intrinsic operation and used actionOperationPassTrigger.
- actionSetMax (10)
- Convert all local rule actions that were using this action type to use actionCallOperationPassInteger instead. This requires putting the operation number operation_SetMax into the operationToExecute field. The maximum value in the valueData field will still be passed through as before, so you should leave the old value there.
Rule editing did not work if the qualifier and action were setting up the same text mapping slots. Because the action modified the text last, you would never see the qualifier's text. To fix this, changed the use of the field numberOfControls in class RuleTemplate. This field is now called textMapFlags. The last four bits still specify the number of controls in the rule edit view, but the rest of the flags specify whether the action or the qualifier owns the mapping slot.
In the rule editing interface, editing a rule will cause it to be automatically checked in the rules list.
Renamed CollectAddressCardsRuleAction to CollectContactsAction
In Magic Cap 1.x, LocalRuleActions that represent boolean attribute rules stored the operation number for the getter. In Rosemary, the operation number of the setter is stored instead.
Added a field ownsActionObject field to class LocalRuleAction. This field is set to true when a temporary object list is used to set the action object. This is necessary because the LocalRuleAction_actionObject field is weak.
Added a new rule action type, actionCallOperationPassNewEnabled which is used to update the enabled setting of check boxes. This new action type should be used by rules that executed operations that set a value and whose action type was actionCallOperationPassTrigger.
Added back the TimedEvent_Data attribute.
Removed traces of Telescript support:
Removed RuleView_NotifyCloudOfChanges. It was only used by its historical subclass, CloudRuleView.
Removed the nameField and ruleView fields of class BookOfRulesPage. These fields were referring directly to objects on the prototype form when they really wanted to manipulate objects in the installed form.
The word "hilite" is a leftover of days when compilers would only recognize idenitifiers of a certain length. Those days are long gone. All occurences of "hilite" in Magic Cap have been changed to the more proper "highlight". The hiliteIndex field of class RuleView has been renamed highlightIndex.
The Rosemary Magic Cap API tries to avoid having multiple operations have the same name but different interfaces. Since Magic Cap doesn't do polymorphism, this is just plain confusing. Many operations have been removed or renamed to avoid this problem. All occurences of Entity() in Magic Cap are now attributes. Some classes had defined two operations, Entity() and SetEntity().
The ruleFlags field of class Rule has been split into individual Boolean attributes.
Rosemary will include a new object runtime that will make the system faster. Current versions of Magic Cap incur a performance penalty when dealing with inter-package object references. In Rosemary, all object references share the same namespace, so there is no performance penalty for inter-package operations. For example, accessing objects stored in a separate data package will not be any slower than accessing an object stored in your own package. The speed gains are realized by a new memory manager that can quickly get to the data for any object instance. This new access method is called fast-dispatched data. The operations available on fast-dispatched data objects are similar to those currently available for objects, although the internal object and cluster representations will be very different. Metaclusters do not exist in the new runtime. The concept of a storage volume now represents a physical container that holds data.Package operation numbers and package class numbers will be dynamically assigned at runtime in Rosemary. References to these numbers in package objects and code will be represented as operation selectors and class selectors in the package image. These references will be fixed up when the package is installed. You should no longer manually assign class or operation numbers in your class definition files.
One of the major complaints about Magic Cap is how slow it is. Through timing tests, it turns out that the majority of the time is spent in the operation dispatcher and the object runtime. Only a minor portion of time is spent drawing graphics or manipulating data. Improving the performance of the object runtime will significantly increase the overall responsiveness of Magic Cap. To speed up operation dispatching, operation numbers, class numbers, intrinsic numbers and unsigned integers have been made distinct data types. Refer to the type safety section for specifics related to this topic.
Since all object references will be in the same namespace, the current Reference object machinery is obsolete and will be removed from Rosemary. For the most part, packages should not be making explicit use of the Reference classes or methods; Reference objects are normally created automatically by the system. This means that this aspect of the new object runtime should have little impact on application packages.
One call that is likely to be used often by packages, SetUpParameters(), is obsolete in the new runtime because References are no longer needed. You can still define parameter blocks that will be passed to Each callbacks and the main routine of actors, but you no longer need the Parameters header at the beginning of parameter block and you no longer need to call SetUpParameters(). Because of the stronger type checking rules enforced by the compiler for Rosemary packages, the pointer type for the parameter block in your callback should be void *. You would cast the pointer to the proper parameter block type inside your routine.
The dynamic assignment of package operation and class numbers means that representation of these values in instance definitions and in C code is likely to change. It's possible that the syntax will remain unchanged, and the compiler will be responsible for generating the correct code or object format. The mechanism for importing classes from another package will most likely change.
The new runtime means that a lot of the things you learned about objects and clusters will be obsolete. Don't rely on internal structures of clusters, object ID slots, or the shadowing mechanism. Don't assume that you can distinguish an object ID from an integer or a pointer. Currently, the high bits of a 32 bit value have special meanings in an ObjectID. This will no longer be true in Rosemary.
The new runtime introduces the concept of an abbreviated class. Abbreviated classes allow objets to be put on a PC card and then take that PC card to a different device and still have an idea as to what the object is; i.e., its human-readable name a a way to garbage collect without trashing the things that the object refers to, even when the package that owns the object is not around.
The new runtime will not support class globals. However, the new runtime will support standard C globals, so many class globals can be made into traditional global variables.
The new runtime does not support lightweight objects.
The new runtime has a new set of calls for dealing with object formats. These calls replaces the EachField() calls. The following operations and types are obsolete: EachExtraField(), BeginModifyFieldsByClassNumber(), ObjectFieldByOffset(), SetObjectFieldByOffset(), EachInspectorFieldFunction, EachObjectFieldFunction, ReadFieldByClassNumber(), WriteFieldsByClassNumber(), BeginReadFieldsByClassNumber(), EachField(), EachFixedField(), EachFieldOfClass(), EachObjectField(), and EachExtraInspectorField().
Added the operation ExtraSizeActuallyUsed() attribute so that objects with slop can tell ComputeCRC() and MatchesInstance() not to checksum or compare bytes in the slop area.
The new operation Object_CopyDeletableNear makes the result of a copy operation deletable in one pass. This is quite a bit faster than calling CopyNear() followed by SetCanDeleteDeep(). CopyDeletableNear() uses the new CopyNearWithFunction() bottleneck operation. This operation takes a function pointer of type CopyingFunction. Each copying function must call Copying(). Folded the functionality of Moved() and Copied() into Copying(). Overriders of Moved() and Copied() should override Copying() instead. Eliminated Move() and Copy(). Former overriders of Copy() should override CopyNearWithFunction() instead.
In Rosemary, the Preferred memory calls no longer exist. Instead, you call one of the Near calls, passing the iNewItemsGoHere indexical as the <nearThis> parameter. In previous versions of Rosemary, new objects would be created in the system persistent cluster if the new items package did not exist. This is not always desirable. This release of Rosemary adds a new intrinsic method, Object_NewItemNear, that when passed an object, will return the new items package if it's active, or the cluster that the object is located in. Now, instead of specifying iNewItemsGoHere, you can use this result of a call to NewItemNear() to create objects in your package cluster if the new items package is not active. To avoid confusion possible confusion with the 1.x method of creating near items, the iPreferredContainer indexical has been removed.
The CanDelete() operation in Magic Cap specifies whether or not an object is deletable. Rosemary adds another level of deletability that specifies that an object should only be deleted with the user's knowledge. This is implemented by the new attribute Object_CanDeleteAtWill. By default, CanDeleteAtWill() returns CanDelete(). If CanDelete() returns true, but CanDeleteAtWill() returns false, that means that the user should be told that the object is being deleted. The case of returning false for CanDelete() but true for CanDeleteAtWill() never arises. Cards and tasks return false for CanDeleteAtWill() so that user data will not be lost.
Class Class has been renamed ClassWithInstances. Class AbstractClass has been renamed ClassWithMethods.
Since the runtime no longer uses Reference objects, class Context is no longer required. Also removed the Parameters structure, SetUpPameters(), Push-, Pop-, BeginImport- and EndImportParameters() calls.
Removed ClusterAt() and EachContext().
Removed the Object_Protected and Object_Marked attribute, which are obsolete.
Removed Cluster_FindByName. This will not be supported in the new runtime and wasn't such a hot idea in the old one anyway.
The SoftwarePackage class has been modified greatly in the new runtime. Indexicals are no longer entries in the software package root list. Additionally, system-defined package indexicals are now attributes in fields in the software package object. The class itself has been renamed SoftwarePackageContents. To maintain parallelism, DataPackage has been renamed DataPackageContents. Many fields have been removed from the software package object: citation, persistentShadowSize, persistentChangesSize, transientSize, dontSaveData, copyOnActivate, hasClassImports, and suicidal.
The linker requires that the tag of the package contents object be "Main.contents".
In the new runtime, symbolic debugging information is kept in a DebugPackage, which is generated by the linker. This information is used for such tasks as inspecting, script editing, dumping and readable info for asserts and complaints.
Added the operation Object_CurrentUserChanged. This method does nothing, but you can override it if you want to be notified when the current user of the device has changed. Objects that appear in the indexical iNotifyCurrentUserChangedList will have this method called on them.
The new mixin class CanAccessWhileMoving allows Magic Cap objects to be accessed at interrupt time without needing to be locked. Because Magic Cap objects are relocatable, interrupt routines could not access an object because the memory manager might be in the middle of moving this object in the heap. The new mixin class TracksMemoryManagerMoves defines the notification interface that the memory manager uses to move blocks in heaps. The memory manager calls the operation MoveMemoryBlock() during compaction to move a block in a heap. Override this routine to get notified when a block needs to be moved. You can update any dereferenced pointers to this object at this point. Call InheritedMoveMemoryBlock() to actually move the block.
Since there is only a logical difference between persistent and transient memory, some occurances of "transient memory" have been removed from the software. The method System_PersistentPercentUsed has been renamed PercentMainRAMUsed(), and System_TransientPercentUsed has been removed entirely. In the storeroom, the memory sign no longer displays a bar for transient memory.
Do not store another package's references, classes, operation numbers, intrinsic numbers, or indexicals inside your package if that component was not exported from the other package. These "under-the-table" references cannot survive rebooting. You can store these components in transient objects because transient objects go away during rebooting.
Image chains were not being copied properly. This was caused by the fact that Image still inherited from Linkable and SingleLinkable. While fixing this problem, these two classes have been eliminated; all the functionality that Image required is implemented in Image. All image chains that are linked with indexicals are not shared, since they must always be referred to via indexical. All images except the first image in a chain that is linked directly are no shared. The first image in the chain is shared and the others are owned-by-shared.
Added the operation Object_SharedSetOwner. This is used in cases where a set of objects have mutual strong ownership; it should return the same object no matter which of the interlinked objects it's called on. The default implementation returns nilObject. Added the operation Object_CorrespondingOwnedObject, which takes an object that's a shared set owner and another object that's an owned object in an equivalent set, and returns the object in this set that corresponds to the object in the equivalent set. The default implementation returns nilObject.
Implemented a mechanism that allows all objects entering Magic Cap from the outside to acclimatize themselves to their new environment. One application of this is to let alphabetical lists resort themselves for the current localized sort order. The Object class defines the operation Acclimatize() which is called when objects enter Magic Cap. The default implementation does nothing. The AlphabeticalList class overrides this operation to let lists resort themselves.
Added the intrinsics BeginModifyMemoryMappedHardware() and EndModifyMemoryMappedHardware() to the Exception server class. These should be used in code that would require using supervisor mode. These methods should be used instead of the old SET_SUPERVISOR_MODE and RESTORE_MODE macros.
BeginReadFieldsOf() is obsolete. Use BeginReadBytes() instead.
Added support for persistent objects without generations (i.e., persistent objects that don't get shadowed.) The system will not automatically generate shadows for objects of classes that inherit from the new mixin class HandlesGenerationsItself. The classes can manage their own shadowing by overriding CommitChangesToObject() and DeleteChangesToObject().
The Cache class has been reimplemented. The new version is optimized for adding, retreiving, flushing and purging entries. The cache now has an upper bound for the number of elements it contains; once the cache grows to a full size, the oldest elements are automatically recycled. Refer to the class definition for this class for details about the API changes.
Added call Object_DestroyWillFreeMemory that lets you know if calling Destroy() on an object will get you more memory. This returns false for pristine objects.
A class can now specify whether an object should have a structured extra list, the format of the list, and whether the data should be cleared. This simplifies object allocation, allowing you to create an object with structured extra data in one shot instead of first creating a fixed size object, then calling SetExtraIsList(), then setting the size of the extra list.
Removed the restriction that prevented you from reading past the end of a tracked object. This is now allowed for efficiency reasons.
Fixed a bug where calling DirectID() on a destroyed reference returns nilObject. It now just returns the original reference.
Fixed a bug where the copy engine can leave objects with the wrong shared state. This happens when the copy engine is being used to make a non-shared copy of a shared original. It needed to determine which objects need to be marked "owned by shared" and which "modifiable." The key was the distinguish between two sets of sub-objects of the top-level object being copied. The first set are objects that are owned by a sub-object that is shared. The second set are objects that are marked owned-by-shared only because the top-level object was shared.
Fixed a bug where the copy engine can create two identical shared objects in the same cluster.
Fixed a bug where ResetClass() for packages was being called from supervisor mode. ResetClass() is now always called in user mode.
In Magic Cap 1.x, you would use a call from the preferred family to respect New Items Go Here. In Rosemary, the preferred calls have been removed. Instead, pass the indexical value iNewItemsGoHere as the nearThis parameter of one of the near calls. An alternate form is to use the result of NewItemsNear as the nearThis parameter. This routine returns either iNewItemsGoHere or cluster containing the exampled object passed to this routine. The difference in behavior in the near calls is that by passing iNewItemsGoHere directly, the new object will be created in the system persistent cluster if the new items package is not activated. NewItemsNear checks for this case, and returns the package persistent cluster if the new items package is not active.
Removed the revert feature from the magic lamp. Reverting only threw away the uncommitted changes clusters. Since cluster updates happen every few minutes, revert only takes you back in time by that much anyway, which isn't very useful. Removed the underlying API as well: System_RevertSystem, System_RevertWithConfirmation, and the indexicals iRevertChoices, iRevertPrompt, and iSystemDateRecord.
Renamed EachPotentialObject() to EachPotentialObjectInStack().
EachReference() has been renamed EachStrongReference(). This intrinsic is used to iterate through an object's non-weak object reference fields.
MakeReferenceList() has been split into three new intrinsics. The old operation used to build a list of objects that are referenced from a specified object. The three new methods allow callers to build more refined lists of referenced objects. The three new intrinsic methods are OwnedObjects(), OwnedNonSharedObjects() and OwnedObjectsWIthFilter().
Removed some fields of the Actor class which were necessary for the old runtime. The fields Actor_contextStack, Actor_contextStackPointer, Actor_process, and Actor_context no longer exist.
Removed the Citation class. Citation objects were used for two purposes: specifying the version of a package, and providing a standard object that other packages can look for to find your package with FindSoftwarePackageByCitation(). The new dynamic linking framework now manages both of these concepts. A textual representation of a package's version is referenced from the SoftwarePackageContents_versionText field.
Removed the operation Object_Destroyed. This call is no longer necessary in the new runtime. (You should have been overriding Finalize() to deal with deallocation cleanup anyway!)
Removed the vestiges of pre-emptive multitasking support. Since the pre-emptive multitasking code was never activated in Magic Cap, this should have no effect in your packages.
Removed vestiges of the old runtime:
Replaced MakeUsable() with MakeUsableReference(). Replaced MakeStorable with MakeStorableReference(). Replaced InSystemTransient() and InPackagePersistent() with SystemTransientCluster(). Replaced InSystemPersistent() with SystemPersistentCluster(). Replaced IsDirectIndexical() and IsSystemIndexical() with IsIndexical(). Replaced NewTransientNear() with NewTransient(). Replace IsNotObjectID(object) with object == nilObject. Replace IsObjectID(object) with object != nilObject. Replaced class PackageContext with PackageCluster. Callers of Context() should use Cluster(). Replaced UpdateAll(SystemContext_) with CommitAllChanges(System_). Replaced SetShouldUpdateSoon(SystemContext(), true) with SetShouldCommitSoon(iSystem, true). Removed InPackagePersistent(). You should just specify what used to be the parameter for InPackagePersistent() instead. Removed IsIndirect(), IsIndirectReference() and IsNotIndirectReference(). Removed ForceUsable() and ForceToggleUsable(). Removed InMetaCluster(). Removed OperationNumberAsInteger(). Removed Object_Reclaim. Destroy() should be used instead. Removed NearMetaCluster(). Removed PushContext(), PopContext(), CurrentContext(), RequestContext() and SystemContext(). Removed Import(). Simply use the desired object directly. Removed MakeClassNumberStorable(). Simply use the desired class number. Removed ImportClassNumber(). Removed OperationIndex(), SystemOperationIndex(), PackageOperationIndex(), IntrinsicIndex(), SystemIntrinsicIndex() and PackageIntrinsicIndex().
Removed traces of Telescript knowledge:
Renamed System_cloudVersion to _reserved2 and deleted to corresponding attribute.