The om_new method returns a pointer to a newly created boopsi object, or NULL if it failed to create the object. This method receives the following message structure (defined in <intuition/classusr.h>): /* The OM_NEW method uses the same structure as OM_SET */ struct opSet { ULONG MethodID; struct TagItem *ops_AttrList; struct GadgetInfo *ops_GInfo; }; The ops_AttrList field contains a pointer to a tagitem array of attribute/value pairs. These contain the initial values of the new object's attributes. The ops_GInfo field is always NULL for the om_new method. Unlike other methods, when a dispatcher gets an om_new message, the object pointer (recvobject from the dispatchrkmmodel() prototype above) does not point to an object. It doesn't make sense for recvobject to point to an object because the idea is to create a new object, not act on an existing one. The pointer normally used to pass a Boopsi object is instead used to pass the address of the object's "true class". An object's true class is the class of which the object is an instance. The first thing the dispatcher does when it processes an om_new message is pass the OM_NEW message on to its superclass's dispatcher. It does this using the amiga.lib function dosupermethoda(): ULONG DoSuperMethodA(Class *cl, Object *trueclass, Msg msg); Each dispatcher passes control to its superclass. Eventually the message will arrive at the rootclass dispatcher. the om_new method in the rootclass dispatcher looks at the object's true class (trueclass from the prototype) to find out which class dispatcher is trying to create a new object. Note that trueclass is not necessarily the same as the current dispatcher's class (cl from the dispatchrkmmodel() prototype above), although this would be the case if the object's true class is a subclass of the current dispatcher's class. The rootclass dispatcher uses the true class to find out how much memory to allocate for the object's instance data. Each class keeps a record of how much memory its local instance data requires. The rootclass dispatcher also looks at each class between the true class and rootclass to find out much memory the local instance data for those classes require. The rootclass dispatcher totals the amount of local instance data memory needed by the true class and each of its superclasses and allocates that much memory. If all goes well, the rootclass dispatcher increments a private field in the true class that keeps track of how many instances of the true class there currently are. It then returns a pointer to the newly created object and passes control back to the subclass dispatcher that called it, which is icclass in the case of rkmmodelclass. if there was a problem, the rootclass dispatcher does not increment the object count and passes back a NULL. When the rootclass dispatcher returns, the icclass dispatcher regains control from dosupermethoda(). dosupermethoda() will return either a pointer to the new object or else it returns NULL if there was an error. Although the rootclass dispatcher allocated all the memory the object needs, it only initialized the instance data local to rootclass. Now it's the icclass dispatcher's turn to do some work. It has to initialize the instance data that is local to icclass. A dispatcher finds its local instance data by using the INST_DATA() macro (defined in <intuition/classes.h>): void *INST_DATA(Class *localclass, Object *object); INST_DATA() takes two arguments, a pointer to a class and a pointer to the object. The INST_DATA() macro returns a pointer to the instance data local to localclass. When the icclass dispatcher was called, it received three arguments, one of which was a pointer to the local class (icclass). The icclass dispatcher passes this pointer and the new object pointer it got from dosupermethoda() to inst_data() to get a pointer to the instance data local to icclass. After initializing its local instance data, the icclass dispatcher passes control back to the modelclass dispatcher, which in turn, initializes the instance data local to modelclass. Finally, the rkmmodelclass dispatcher regains control and now has to take care of its local instance data. To find its local instance data, the rkmmodelclass dispatcher needs a pointer to its Class and a pointer to the new object. The dispatcher function gets its Class pointer as its first argument (cl from the dispatchrkmmodel() prototype above). it gets the new object pointer as the return value from dosupermethoda(). in this case, inst_data() returns a pointer to an rkmmoddata structure. Now the dispatcher has to initialize its local instance data. It has to scan through the tag list passed in the om_new message looking for initial values for the rkmmod_currval and rkmmod_limit attributes. as an alternative, the dispatcher's OM_NEW method can use its om_set method to handle initializing these "settable" attributes. Finally, the dispatcher can return. When the dispatcher returns from an om_new method, it returns a pointer to the new object. If the om_new method fails, it should tell the partially initialized object it got from its superclass's dispatcher to dispose of itself (using om_dispose) and return null.