For the OM_SET message, the rkmmodelclass dispatcher steps through the attribute/value pairs passed to it in the OM_SET message looking for the local attributes (see OM_NEW for the OM_SET message structure). The RKMMOD_Limit attribute is easy to process. Just find it and record the value in the local RKMModData.vallimit field. Because the function of the rkmmodelclass's OM_SET and OM_UPDATE methods are almost identical, the rkmmodelclass dispatcher handles them as the same case. The only difference is that, because the OM_UPDATE message comes from another Boopsi object, the OM_UPDATE method can report on transitory state changes of an attribute. For example, when the user slides a Boopsi prop gadget, that prop gadget sends out an interim OM_UPDATE message for every interim value of PGA_Top. When the user lets go of the prop gadget, the gadget sends out a final OM_UPDATE message. The OM_UPDATE message is almost identical to the OM_SET message: #define OPUF_INTERIM (1<<0) /* the OM_NOTIFY method uses the same structure */ struct opUpdate { ULONG MethodID; struct TagItem *opu_AttrList; struct GadgetInfo *opu_GInfo; ULONG opu_Flags; /* The extra field */ }; A dispatcher can tell the difference between an interim and final OM_UPDATE message because the OM_UPDATE message has an extra field on it for flags. If the low order bit (the OPUF_INTERIM bit) is set, this is an interim OM_UPDATE message. The interim flag is useful to a class that wants to ignore any transitory messages, processing only final attribute values. Because rkmmodelclass wants to process all changes to its attributes, it processes all OM_UPDATE messages. The RKMMOD_CurrVal attribute is a little more complicated to process. The dispatcher has to make sure the new current value is within the limits set by RKMMOD_Limit, then record that new value in the local RKMModData.currval field. Because other objects need to hear about changes to RKMMOD_CurrVal, the dispatcher has to send a notification request. It does this by sending itself an OM_NOTIFY message. The OM_NOTIFY message tells an object to notify its targets (its ICA_TARGET and the objects in its broadcast list) about an attribute change. The OM_NOTIFY method does this by sending OM_UPDATE messages to all of an object's targets. The rkmmodelclass dispatcher does not handle the OM_NOTIFY message itself. It inherits this method from modelclass, so the rkmmodelclass dispatcher passes OM_NOTIFY messages on to its superclass. To notify its targets, the rkmmodelclass dispatcher has to construct an OM_NOTIFY message. The OM_NOTIFY method uses the same message structure as OM_UPDATE. Using the stack-based version of DoSuperMethodA(), DoSuperMethod(), the dispatcher can build an OM_NOTIFY message on the stack: . . . struct TagItem tt[2]; struct opUpdate *msg; . . . tt[0].ti_Tag = RKMMOD_CurrVal; /* make a tag list. */ tt[0].ti_Data = mmd->currval; tt[1].ti_Tag = TAG_END; DoSuperMethod(cl, o, OM_NOTIFY, tt, msg->opu__GInfo, ((msg->MethodID == OM_UPDATE) ? (msg->opu_Flags) : 0L)); . . . Because the OM_NOTIFY needs a tag list of attributes about which to issue updates, the dispatcher builds a tag list containing just the RKMMOD_CurrVal tag and its new value. The dispatcher doesn't use the tag list passed to it in the OM_UPDATE/OM_NOTIFY message because that list can contain many other attributes besides RKMMOD_CurrVal. The msg variable in the DoSuperMethod() call above is the OM_SET or OM_UPDATE message that was passed to the dispatcher. The dispatcher uses that structure to find a pointer to the GadgetInfo structure that the OM_NOTIFY message requires. The GadgetInfo structure comes from Intuition and contains information that Boopsi gadgets need to render themselves. For the moment, don't worry about what the GadgetInfo structure actually does, just pass it on. The targets of an rkmmodel will probably need it. Notice that the dispatcher has to test to see if the message is an OM_SET or OM_UPDATE so it can account for the opu_Flags field at the end of the OM_UPDATE message. Processing the RKMMOD_Up and RKMMOD_Down attributes is similar to the RKMMOD_CurrVal attribute. When the dispatcher sees one of these, it has to increment or decrement the local RKMModData.currval, making sure RKMModData.currval is within limits. The dispatcher then sends an OM_NOTIFY message to the superclass about the change to RKMModData.currval. The return value from the dispatcher's OM_SET method depends on the what effect the attribute change has to the visual state of the objects in the rkmmodel's broadcast list. If an attribute change will not affect the visual state of the rkmmodel's objects, the OM_SET method returns zero. If the attribute change could trigger a change to the rkmmodel's objects, it returns something besides zero. For example, the rkmmodelclass OM_SET method returns 1L if an rkmmodel's RKMMOD_CurrVal, RKMMOD_Up, or RKMMOD_Down attribute is changed. At some point the rkmmodelclass dispatcher has to allow its superclasses to process these attributes it inherits. Normally a dispatcher lets the superclass process its attributes before attempting to process any local attributes. The rkmmodelclass dispatcher does this by passing on the OM_SET or OM_UPDATE message using DoSuperMethodA() (inheritance at work!). As an alternative, the dispatcher can use the amiga.lib function SetSuperAttrs(). See the amiga.lib Autodocs for more details on this function.